Platform Architecture
A technical overview of how Celiq's layers โ Physical, Semantic, and Runtime โ work together to serve analytics queries.
This page is for platform builders and administrators who need to understand Celiq's internals. End users building analytics should start with Quick Start instead.
Celiq is a self-hosted semantic analytics platform. It has three layers: the Physical Layer connects to your warehouse, the Semantic Layer defines what data means, and the Runtime Layer executes queries. This page describes each layer and how they interact.
Three-layer architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ RUNTIME LAYER โ
โ Discover ยท Orion AI ยท Mosaics ยท Scheduling โ
โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ resolves
โโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SEMANTIC LAYER โ
โ Nodes ยท Domains ยท Reveals ยท Metrics ยท CML โ
โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ maps to
โโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PHYSICAL LAYER โ
โ Datasets ยท Deployments ยท Mappings โ
โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ queries
โโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WAREHOUSE โ
โ Snowflake ยท BigQuery ยท Postgres ยท Redshift โ
โ DuckDB ยท MySQL ยท SQL Server ยท Databricks โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโPhysical Layer
The Physical Layer resolves abstract dataset names to physical tables at query time. It has three concepts:
Datasets โ Logical table definitions. A dataset is a schema: a name plus a list of column definitions (name, type, nullable). It doesn't live in any one warehouse. Deployments โ Target environments (Production, Development, Staging). Each workspace has one default deployment; all end-user queries run through it. Dataset Mappings โ Bindings that say "in deployment X, dataset Y maps to connection Z, table W." Celiq validates mappings by comparing dataset column definitions against the physical table schema and computes a compatibility score. What it resolves:dataset name + active deployment โ (connection, physical table)
Storage: PostgreSQL tables datasets, dataset_columns, deployments, dataset_mappings
Semantic Layer
The Semantic Layer defines what data means: metric calculations, dimension taxonomies, join logic, and security rules. It is authored in CML files inside Forge.
Nodes โ Map to datasets. Each node defines dimensions (group-by columns) and measures (aggregations). Written in CML. Domains โ Join multiple nodes together. A domain defines which nodes can be combined in a query, and with what join logic. Reveals โ Named, certified query configurations exposed to end users. A Reveal defines which node/domain to start from, which metrics and dimensions are surfaced, and AI context for Orion. Metrics โ Named measures promoted to first-class status. A metric has a canonical definition, a business owner, and usage tracking. Storage: PostgreSQL; CML source files in Forge (Git-backed). A compiled model cache is maintained per workspace. Compile/validate flow: Forge runs a validation pass (Check & Save) before any semantic change goes live. Validation checks SQL parse, fanout risk, join integrity, and field reference correctness.
Runtime Layer
The Runtime Layer is everything that actually runs queries and serves results.
Query execution
- Field resolution โ Discover sends a query spec (dimensions, measures, filters, grain). The backend resolves field names against the compiled semantic model.
- SQL generation โ
buildSQL()generates warehouse-specific SQL viaapplyDialect(). It handles type casting, date truncation, CASE expressions, and window functions per warehouse dialect. - Deployment resolution โ The active deployment is determined (workspace default, or Mosaic-pinned deployment). The
datasetโ(connection, physical_table)mapping is looked up. - Execution โ SQL is sent to the warehouse via the appropriate driver (pg, @google-cloud/bigquery, snowflake-sdk, duckdb).
- Post-processing โ Table calculations (window functions, running totals, rank) that can't be expressed as SQL are applied client-side after results arrive.
Security enforcement
Every query passes through two security guards before results are returned:
dataSecurityEnforceโ Applies row-level security (Data Keys) and column-level security (Data Gates) based on the requesting user's role and attributes. This guard is fail-closed: any error blocks the query rather than returning unredacted data.- Tenant isolation โ All database queries include
workspace_idin WHERE clauses, enforced bytenantRls.js. A user in workspace A cannot access workspace B's data regardless of the query.
Orion AI
Orion is the AI layer that translates natural language into Reveal configurations. It uses Claude (Anthropic) via the workspace's configured API key. The key is stored encrypted per workspace in the database โ never as environment variables.
Orion resolves node/domain/metric references using the semantic model via resolveReveal (DISTINCT ON with domain priority โ the node that most closely matches the intent is selected, preferring nodes within the active domain).
Scheduling and delivery
Scheduled reports and Mosaic snapshots run via a background job queue. Each scheduled item runs a query through the normal runtime path and delivers results via configured channels (email, Slack).
Stack
| Component | Technology |
|---|---|
| Backend | Node.js / Express |
| Database | PostgreSQL (Railway managed) |
| Frontend | React 18 + Vite (dist committed to git) |
| AI | Anthropic Claude โ model configurable per workspace |
| Warehouse drivers | pg (Postgres/Redshift), @google-cloud/bigquery, snowflake-sdk, better-sqlite3 (DuckDB) |
| Deployment | Railway (auto-deploy on push to main) |
Authentication
- Session tokens โ JWT-based, issued on login. No session storage in the database.
- API keys โ Workspace-scoped keys for programmatic access to
/api/*endpoints. - Workspace AI key โ Anthropic API key stored encrypted per workspace, accessed via
getWorkspaceApiKey(workspaceId). Never queried fromworkspace_ai_configdirectly.
Multi-tenancy
Celiq is a single-instance, multi-tenant deployment. Tenant isolation is enforced at:
- Auth middleware โ
req.workspaceIdis set from the authenticated session. All route handlers usereq.workspaceId, neverreq.user.workspace_id. - Database queries โ All queries include
workspace_id = $1filters. ThetenantRls.jsmodule enforces this pattern. - Credential encryption โ Warehouse credentials are encrypted with AES-256-GCM using a per-deployment encryption key (
ENCRYPTION_KEYenv var). Decryption happens inbackend/lib/crypto.js.
Related pages
- Physical Layer โ dataset, deployment, and mapping details
- Semantic Layer โ nodes, domains, metrics, and CML
- CML Reference โ complete field reference
- Connections โ warehouse types and credentials
- Security โ row-level and column-level security