Semantic DomainsTemplate Authoring
Validation & Examples
Complete domain example and validation error reference
Complete Example: E-Commerce Domain
Here's a complete domain template combining all concepts -- 3 datasets, 3 relationships, nested calculated metrics, calculated dimensions, and a grain mapping:
schemaVersion: "2.0"
datasets:
- name: orders
label: "Orders"
type: physical
connectionId: "conn_1"
connectionType: PostgreSQL
schema: public
table: orders
primaryKey: [order_id]
fields:
identifiers:
- name: order_id
dataType: number
type: primary
- name: customer_id
dataType: number
type: foreign
dimensions:
- name: order_date
label: "Order Date"
dataType: date
granularity: day
- name: status
label: "Status"
dataType: string
metrics:
- name: amount
label: "Revenue"
dataType: number
sourceField: amount
- name: cost
label: "Cost"
dataType: number
sourceField: cost
- name: customers
label: "Customers"
type: physical
connectionId: "conn_1"
connectionType: PostgreSQL
schema: public
table: customers
primaryKey: [id]
fields:
identifiers:
- name: id
dataType: number
type: primary
dimensions:
- name: segment
label: "Customer Segment"
dataType: string
- name: region
label: "Region"
dataType: string
- name: returns
label: "Returns"
type: physical
connectionId: "conn_1"
connectionType: PostgreSQL
schema: public
table: returns
fields:
identifiers: []
dimensions:
- name: return_date
label: "Return Date"
dataType: date
metrics:
- name: amount
label: "Return Amount"
dataType: number
sourceField: amount
relationships:
- name: orders_to_customers
sourceDataset: orders
sourceFields: [customer_id]
targetDataset: customers
targetFields: [id]
cardinality: many_to_one
defaultJoinType: LEFT
isAutoJoin: true
discoveredBy: user
isActive: true
calculatedMetrics:
revenue:
label: "Total Revenue"
expression: "SUM({amount})"
inputs:
amount: { dataset: orders, field: amount }
cost:
label: "Total Cost"
expression: "SUM({cost_amount})"
inputs:
cost_amount: { dataset: orders, field: cost }
profit:
label: "Profit"
expression: "{revenue} - {cost}"
inputs:
revenue: { metric: revenue }
cost: { metric: cost }
profit_margin:
label: "Profit Margin %"
expression: "{profit} / NULLIF({revenue}, 0) * 100"
inputs:
profit: { metric: profit }
revenue: { metric: revenue }
format:
type: percentage
decimals: 1
net_revenue:
label: "Net Revenue"
description: "Revenue minus returns"
expression: "{total_sales} - COALESCE({total_returns}, 0)"
inputs:
total_sales: { dataset: orders, field: amount, aggregate: SUM }
total_returns: { dataset: returns, field: amount, aggregate: SUM }
calculatedDimensions:
order_month:
label: "Order Month"
expression: "DATE_TRUNC('month', {order_date})"
inputs:
order_date: { dataset: orders, field: order_date }
dataType: date
order_size:
label: "Order Size"
expression: |
CASE
WHEN {amount} > 1000 THEN 'Large'
WHEN {amount} > 100 THEN 'Medium'
ELSE 'Small'
END
inputs:
amount: { dataset: orders, field: amount }
dataType: string
grainMappings:
- sourceDimension: order_month
targetDataset: returns
targetColumn: return_dateValidation Errors
When you save a domain template, Semaphor validates it and reports errors. Here are the validation codes you may encounter:
Errors
| Code | Meaning | Fix |
|---|---|---|
| E001 | Circular dependency detected (e.g., metric A references B which references A) | Break the cycle by removing one of the references |
| E002 | Input references an unknown metric name | Check that the referenced metric exists in calculatedMetrics |
| E003 | Input references an unknown field in a dataset | Verify the dataset has that field in its field lists |
| E004 | Input references an unknown dataset name | Ensure the dataset is defined in the datasets array |
| E005 | Token {name} in expression not found in inputs | Add the missing token name to the inputs map |
| E007 | Calculated dimension references a metric | Dimensions can only reference columns or other dimensions |
| E008 | Invalid filter on a metric | Check filter syntax (field + operator + value) |
| E009 | Invalid expression syntax | Remove braces inside string literals |
| E010 | Input requires an aggregate but none specified | Add aggregate to the input or wrap token in aggregate function |
| E011 | Input references an unknown calculated dimension | Check that the dimension exists in calculatedDimensions |
| E012 | Unknown field reference in metric expression | Check spelling of field names in the expression; ensure the referenced field is defined in the dataset |
| E013 | Invalid metric expression | Review expression for circular dependencies, remove AS aliases, and check SQL syntax |
Warnings
| Code | Meaning | Action |
|---|---|---|
| E006 | Input is defined but not used in expression | Remove the unused input or add it to the expression |
| W001 | Dataset has no primary key signal | Add primaryKey or mark identifier as type: primary |
| W002 | Relationship may cause metric inflation | Consider using aggregate_then_join strategy or review cardinality |
Next Steps
- Agent Guide -- Build templates programmatically with validation rules
- User Guide -- How end users interact with your domain in dashboards