Analytics
Analytics protocol schemas
Analytics/Semantic Layer Protocol
Defines the "Business Logic" for data analysis.
Inspired by Cube.dev, LookML, and dbt MetricFlow.
This layer decouples the "Physical Data" (Tables/Columns) from the
"Business Data" (Metrics/Dimensions).
Source: packages/spec/src/data/analytics.zod.ts
import { AggregationMetricType, AnalyticsQuerySchema, CubeSchema, CubeJoinSchema, DimensionSchema, DimensionType, MetricSchema, TimeUpdateInterval } from '@objectstack/spec/data';
import type { AggregationMetricType, AnalyticsQuery, Cube, CubeJoin, Dimension, DimensionType, Metric, TimeUpdateInterval } from '@objectstack/spec/data';
// Validate data
const result = AggregationMetricType.parse(data);
count
sum
avg
min
max
count_distinct
number
string
boolean
| Property | Type | Required | Description |
|---|
| cube | string | optional | Target cube name (optional when provided externally, e.g. in API request wrapper) |
| measures | string[] | ✅ | List of metrics to calculate |
| dimensions | string[] | optional | List of dimensions to group by |
| where | any | optional | Filtering criteria (canonical Query DSL FilterCondition) |
| timeDimensions | { dimension: string; granularity?: Enum<'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'>; dateRange?: string | string[] }[] | optional | |
| order | Record<string, Enum<'asc' | 'desc'>> | optional | |
| limit | number | optional | |
| offset | number | optional | |
| timezone | string | optional | |
| Property | Type | Required | Description |
|---|
| name | string | ✅ | Cube name (snake_case) |
| title | string | optional | |
| description | string | optional | |
| sql | string | ✅ | Base SQL statement or Table Name |
| measures | Record<string, { name: string; label: string; description?: string; type: Enum<'count' | 'sum' | 'avg' | 'min' | 'max' | 'count_distinct' | 'number' | 'string' | 'boolean'>; … }> | ✅ | Quantitative metrics |
| dimensions | Record<string, { name: string; label: string; description?: string; type: Enum<'string' | 'number' | 'boolean' | 'time' | 'geo'>; … }> | ✅ | Qualitative attributes |
| joins | Record<string, { name: string; relationship: Enum<'one_to_one' | 'one_to_many' | 'many_to_one'>; sql: string }> | optional | |
| refreshKey | { every?: string; sql?: string } | optional | |
| public | boolean | optional (default: false) | |
| _lock | Enum<'none' | 'no-overlay' | 'no-delete' | 'full'> | optional | Item-level lock — controls overlay & delete (ADR-0010). |
| _lockReason | string | optional | Human-readable reason shown when a write is refused by _lock. |
| _lockSource | Enum<'artifact' | 'package' | 'env-forced'> | optional | Layer that set _lock (artifact | package | env-forced). |
| _provenance | Enum<'package' | 'org' | 'env-forced'> | optional | Origin of the item (package | org | env-forced). |
| _packageId | string | optional | Owning package machine id. |
| _packageVersion | string | optional | Owning package version. |
| _lockDocsUrl | string | optional | Optional documentation link surfaced next to _lockReason. |
| Property | Type | Required | Description |
|---|
| name | string | ✅ | Unique metric ID |
| label | string | ✅ | Human readable label |
| description | string | optional | |
| type | Enum<'count' | 'sum' | 'avg' | 'min' | 'max' | 'count_distinct' | 'number' | 'string' | 'boolean'> | ✅ | |
| sql | string | ✅ | SQL expression or field reference |
| format | string | optional | |
| Property | Type | Required | Description |
|---|
| name | string | ✅ | Unique dimension ID |
| label | string | ✅ | Human readable label |
| description | string | optional | |
| type | Enum<'string' | 'number' | 'boolean' | 'time' | 'geo'> | ✅ | |
| sql | string | ✅ | SQL expression or column reference |
| granularities | Enum<'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'>[] | optional | |
| Property | Type | Required | Description |
|---|
| name | string | ✅ | Target cube name |
| relationship | Enum<'one_to_one' | 'one_to_many' | 'many_to_one'> | optional (default: "many_to_one") | |
| sql | string | ✅ | Join condition (ON clause) |
| Property | Type | Required | Description |
|---|
| every | string | optional | Refresh interval (e.g. "1 hour") |
| sql | string | optional | SQL to check for data changes |
| Property | Type | Required | Description |
|---|
| name | string | ✅ | Target cube name |
| relationship | Enum<'one_to_one' | 'one_to_many' | 'many_to_one'> | optional (default: "many_to_one") | |
| sql | string | ✅ | Join condition (ON clause) |
| Property | Type | Required | Description |
|---|
| name | string | ✅ | Unique dimension ID |
| label | string | ✅ | Human readable label |
| description | string | optional | |
| type | Enum<'string' | 'number' | 'boolean' | 'time' | 'geo'> | ✅ | |
| sql | string | ✅ | SQL expression or column reference |
| granularities | Enum<'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'>[] | optional | |
string
number
boolean
time
geo
| Property | Type | Required | Description |
|---|
| name | string | ✅ | Unique metric ID |
| label | string | ✅ | Human readable label |
| description | string | optional | |
| type | Enum<'count' | 'sum' | 'avg' | 'min' | 'max' | 'count_distinct' | 'number' | 'string' | 'boolean'> | ✅ | |
| sql | string | ✅ | SQL expression or field reference |
| format | string | optional | |
second
minute
hour
day
week
month
quarter
year