Skip to main content

AI Modeling & Build

After BRD completion, ekai generates production-ready artifacts. The AI MODELING & BUILD tab contains six sub-tabs for each artifact type.

Prerequisites

Complete the Capture Requirements step to generate your Business Requirements Document.


Artifact Sub-tabs​

TabContent
DATA LINEAGEVisual diagram of data flow
DATA CATALOGTable and column documentation
BUSINESS GLOSSARYTerm definitions
METRICS/KPISCalculated measures with SQL
DATA VALIDATIONdbt tests and quality rules
DBT PROJECTComplete dbt project code

Data Lineage​

Visual representation of how data flows from source to output:

Slide 1
Slide 2

Lineage Diagram Elements​

1st layer — Source

Leftmost — raw warehouse tables

2nd layer — Staging

Next — cleaned / renamed models

3rd layer — Intermediate

Middle — business logic transforms

4th layer — Final models

Rightmost — marts and facts

Controls​

  • Zoom — + / - buttons
  • Pan — Click and drag
  • Fullscreen — Expand view
  • Download — Export as image

Data Product — Sample Interaction​

Explore the product UI, then try the interactive sample:

Data product in the product UI
Datasets
Planned

Order line revenue fact

fct_line_items

One row per order line. The primary analytical grain and the serving surface for Net Revenue, Gross Revenue, Discount Amount, Effective Discount Rate and Units Sold, with order date, customer, part, priority and status carried down from the header so revenue can be cut by time and segment without a second join.

Grain: one row per order_key + line_number

One row per order line: 59,986,052 rows, one per (order_key, line_number). Revenue measures are additive across every dimension here. The order header total is deliberately absent - query fct_orders for it, and never join lines to orders to sum it. Counting orders from this mart requires COUNT(DISTINCT order_key); COUNT(*) returns lines and is about 4x too high. discount_rate and tax_rate are rates: never sum them, weight by gross_amount when averaging. net_revenue and discount_amount are stored unrounded - round only at presentation.

SourceANALYTICS.MARTS.FCT_LINE_ITEMS
order_key
NUMBER(38,0)
Identifier of the parent order. Part of the grain and the FK to fct_orders.order_key. Values are sparse - TPC-H allocates non-contiguously, reaching ~26.5M across 15,000,000 orders - so never treat it as a dense sequence.
line_number
NUMBER(38,0)
Sequence of the line within its order, 1 to 7. Not unique on its own - only the pair with order_key identifies a line.
order_date
DATE
Date the parent order was placed, carried down from the header. The business date for revenue: revenue is recognised here, not at ship or receipt. Day grain, no time component, no nulls.
order_year
NUMBER(4,0)
Calendar year of order_date, January to December, no fiscal offset. The reporting year for every revenue measure.
customer_key
NUMBER(38,0)
Identifier of the customer who placed the parent order, carried down from the header. FK to dim_customers.customer_key - the path to market segment and nation.
part_key
NUMBER(38,0)
Identifier of the part sold on this line. FK to dim_parts.part_key.
supplier_key
NUMBER(38,0)
Supplier identifier on the line, ~99,265 distinct. Unresolvable - the SUPPLIER table is not in this connection. Carried as a plain attribute: do not join it and do not treat it as a dimension.
order_status
TEXT
Status code of the parent order: O, F or P, read as Open, Fulfilled and Partial. The labels are inferred - no code table exists and the business did not confirm them. A reporting dimension only; it filters no revenue measure.
order_priority
TEXT
Handling urgency of the parent order, one of 1-URGENT, 2-HIGH, 3-MEDIUM, 4-NOT SPECIFIED, 5-LOW. The rank is the leading character, so a lexical sort of the raw value orders it correctly.
quantity
NUMBER(38,0)
Whole units of the part on this line, 1 to 50. Additive across every dimension - the source of Units Sold.
gross_amount
NUMBER(12,2)
Value of the line before discount and before tax - unit price multiplied by quantity, as stored in the source. Observed 906.93 to 104,496.00. Additive; this is the baseline Net Revenue is measured against, not revenue itself.
discount_rate
NUMBER(4,2)
Proportional reduction applied to the line, 0.00 to 0.10 in 0.01 steps - eleven values, complete and confirmed. A rate, not money: never sum it, and weight by gross_amount when averaging.
tax_rate
NUMBER(4,2)
Proportional tax on the line, 0.00 to 0.08 in 0.01 steps - nine values, complete and confirmed. A rate, not money, with the same summing and averaging hazards as discount_rate. Sits outside the agreed revenue definition and is used by no measure in this model.
discount_amount
NUMBER(14,4)
Money given away on this line: gross_amount x discount_rate. Derived once in staging so no consumer rebuilds it. Additive across every dimension. Stored unrounded - round only at presentation.
net_revenue
NUMBER(14,4)
The agreed revenue figure for this line: gross_amount x (1 - discount_rate), tax excluded. Derived once in staging - this column is the single definition of revenue in the model. Additive across every dimension. Stored unrounded - round only at presentation.
return_flag
TEXT
Return status code of the line, 3 distinct values. Both the value list (A, N, R) and the readings come from the TPC-H specification, not from this data - the profiler never captured them. Returns do not affect revenue: every line counts regardless. Descriptive only; do not filter on it.
line_status
TEXT
Line-level code, O or F, distinct from order_status. Meaning unconfirmed and believed to be derived from whether ship_date falls before the dataset cutoff, so it is correlated with ship_date rather than an independent fact. Not an analysis dimension.
ship_date
DATE
Date the line shipped. Carried for completeness; delivery performance is out of scope and no measure is specified on it. Never the basis for revenue timing.
commit_date
DATE
Date the supplier committed to ship the line. Carried for completeness; no measure is specified on it.
receipt_date
DATE
Date the customer received the line. Carried for completeness; no measure is specified on it.
ship_mode
TEXT
Transport mode for the line: AIR, REG AIR, MAIL, RAIL, SHIP, TRUCK, FOB. Carried as an attribute; no delivery measure is specified.
ship_instruction
TEXT
Handling instruction for the line: DELIVER IN PERSON, COLLECT COD, NONE, TAKE BACK RETURN. Carried as an attribute; TAKE BACK RETURN is a shipping instruction and is not a returns indicator.

Data Catalog​

Auto-generated documentation for all tables and columns.

Catalog Entry Example​

fct_line_items · ANALYTICS.MARTS.FCT_LINE_ITEMS

One row per order line (~60M). Primary grain for Net Revenue. PK: order_key, line_number.

ColumnTypeDescription
order_keyNUMBER(38,0)Parent order; FK → fct_orders
line_numberNUMBER(38,0)1–7 within order (composite PK)
order_dateDATERevenue recognition date (from header)
order_yearNUMBER(4,0)Calendar year of order_date
customer_keyNUMBER(38,0)FK → dim_customers
part_keyNUMBER(38,0)FK → dim_parts
quantityNUMBER(38,0)Units sold (1–50)
gross_amountNUMBER(12,2)Pre-discount line value
discount_rateNUMBER(4,2)Rate 0–0.10 — never sum
discount_amountNUMBER(14,4)gross_amount × discount_rate
net_revenueNUMBER(14,4)gross × (1 − discount) — tax excluded

Business Glossary​

Standardized term definitions for the model:

Glossary Format​

TermDefinition & Logic
OrderA purchase commitment by one customer on one date. Groups 1–7 order lines; carries its own date and status. Order-level amounts are valid only on fct_orders.
Order LineOne part, in one quantity, within one order — primary grain of the model and of Net Revenue.
CustomerAn account that places orders. Belongs to exactly one nation and one market segment.
Market SegmentIndustry classification of a customer — primary way revenue is cut in this model (five confirmed values).
PartA catalogue item sold on an order line (manufacturer, brand, type, size, retail price).
NationCountry a customer is based in — geographic dimension of revenue (25 nations).

Metrics/KPIs​

Calculated measures with SQL formulas:

Metrics Format​

NameDescriptionCalculation
Net RevenueValue realised after discount, excluding taxSUM(net_revenue)
Gross RevenueList value of goods sold before discountSUM(gross_amount)
Discount AmountGap between gross and net revenueSUM(discount_amount)
Effective Discount RateDiscount as a share of gross value100.0 * SUM(discount_amount) / NULLIF(SUM(gross_amount), 0)
Units SoldTotal quantity across order linesSUM(quantity)
Order CountDistinct orders in the periodCOUNT(DISTINCT order_key)
Active Customer CountDistinct customers with ≥1 orderCOUNT(DISTINCT customer_key)

Data Validation​

Quality rules implemented as dbt tests:

Validation Rule Example​

Referential integrity — every order line resolves to an order

AttributeValue
RuleEvery order line resolves to an order
CategoryReferential
ClassBuild-time gate
Expected Result0 violations
Failure ActionBlock deployment

Implementation:

SELECT COUNT(*) AS violation_count
FROM LINEITEM l
LEFT JOIN ORDERS o ON l.L_ORDERKEY = o.O_ORDERKEY
WHERE o.O_ORDERKEY IS NULL

DBT Project​

Complete dbt project with all models:

DBT project view

Project Structure​

├── README.md
├── dbt_project.yml
├── logs/
├── macros/
├── mart_relations.json
├── models/
│ ├── intermediate/
│ ├── marts/
│ │ └── analytics/
│ │ ├── fct_line_items.sql
│ │ ├── fct_orders.sql
│ │ ├── dim_customers.sql
│ │ └── dim_parts.sql
│ └── staging/
│ └── tpch/
├── models_targets.json
├── package-lock.yml
└── packages.yml

Code View​

Generated model YAML with contracts, column tests, and unit tests:

models.yml
version: 2

models:
- name: fct_line_items
description: One row per order line; the serving mart for line-level revenue and volume measures.
config: {contract: {enforced: true}}
columns:
- {name: order_key, data_type: 'NUMBER(38,0)', data_tests: [not_null]}
- {name: line_number, data_type: 'NUMBER(38,0)', data_tests: [not_null]}
- {name: order_date, data_type: DATE, data_tests: [not_null]}
- {name: order_year, data_type: 'NUMBER(4,0)', data_tests: [not_null]}
- {name: customer_key, data_type: 'NUMBER(38,0)', data_tests: [not_null]}
- {name: part_key, data_type: 'NUMBER(38,0)', data_tests: [not_null]}
- {name: supplier_key, data_type: 'NUMBER(38,0)', data_tests: [not_null]}
- {name: order_status, data_type: TEXT, data_tests: [not_null]}
- {name: order_priority, data_type: TEXT, data_tests: [not_null]}
- {name: quantity, data_type: 'NUMBER(38,0)', data_tests: [not_null]}
- {name: gross_amount, data_type: 'NUMBER(12,2)', data_tests: [not_null]}
- {name: discount_rate, data_type: 'NUMBER(4,2)', data_tests: [not_null]}
- {name: tax_rate, data_type: 'NUMBER(4,2)', data_tests: [not_null]}
- {name: discount_amount, data_type: 'NUMBER(14,4)', data_tests: [not_null]}
- {name: net_revenue, data_type: 'NUMBER(14,4)', data_tests: [not_null]}
- {name: return_flag, data_type: TEXT, data_tests: [not_null]}
- {name: line_status, data_type: TEXT, data_tests: [not_null]}
- {name: ship_date, data_type: DATE, data_tests: [not_null]}
- {name: commit_date, data_type: DATE, data_tests: [not_null]}
- {name: receipt_date, data_type: DATE, data_tests: [not_null]}
- {name: ship_mode, data_type: TEXT, data_tests: [not_null]}
- {name: ship_instruction, data_type: TEXT, data_tests: [not_null]}
data_tests:
- dbt_utils.unique_combination_of_columns:
arguments: {combination_of_columns: [order_key, line_number]}
- relationships:
arguments: {to: "{{ ref('fct_orders') }}", field: order_key}
- relationships:
arguments: {to: "{{ ref('dim_parts') }}", field: part_key}
- name: fct_orders
description: One row per order header; the only mart that carries order_total_price.
config: {contract: {enforced: true}}
columns:
- {name: order_key, data_type: 'NUMBER(38,0)', data_tests: [not_null, unique]}
- {name: customer_key, data_type: 'NUMBER(38,0)', data_tests: [not_null]}
- {name: order_date, data_type: DATE, data_tests: [not_null]}
- {name: order_year, data_type: 'NUMBER(4,0)', data_tests: [not_null]}
- {name: order_status, data_type: TEXT, data_tests: [not_null]}
- {name: order_priority, data_type: TEXT, data_tests: [not_null]}
- {name: clerk, data_type: TEXT, data_tests: [not_null]}
- {name: order_total_price, data_type: 'NUMBER(12,2)', data_tests: [not_null]}
data_tests:
- relationships:
arguments: {to: "{{ ref('dim_customers') }}", field: customer_key}
- name: dim_customers
description: One row per customer, with flattened nation attributes.
config: {contract: {enforced: true}}
columns:
- {name: customer_key, data_type: 'NUMBER(38,0)', data_tests: [not_null, unique]}
- {name: customer_name, data_type: TEXT, data_tests: [not_null]}
- name: market_segment
data_type: TEXT
data_tests:
- not_null
- accepted_values:
arguments: {values: ['BUILDING', 'MACHINERY', 'HOUSEHOLD', 'AUTOMOBILE', 'FURNITURE']}
- {name: nation_key, data_type: 'NUMBER(38,0)', data_tests: [not_null]}
- {name: nation_name, data_type: TEXT, data_tests: [not_null]}
- {name: nation_region_key, data_type: 'NUMBER(38,0)', data_tests: [not_null]}
- {name: account_balance, data_type: 'NUMBER(12,2)', data_tests: [not_null]}
- name: dim_parts
description: One row per part catalogue item.
config: {contract: {enforced: true}}
columns:
- {name: part_key, data_type: 'NUMBER(38,0)', data_tests: [not_null, unique]}
- {name: part_name, data_type: TEXT, data_tests: [not_null]}
- {name: manufacturer, data_type: TEXT, data_tests: [not_null]}
- {name: brand, data_type: TEXT, data_tests: [not_null]}
- {name: part_type, data_type: TEXT, data_tests: [not_null]}
- {name: container, data_type: TEXT, data_tests: [not_null]}
- {name: part_size, data_type: 'NUMBER(38,0)', data_tests: [not_null]}
- {name: retail_price, data_type: 'NUMBER(12,2)', data_tests: [not_null]}

unit_tests:
- name: uses_header_order_date_and_excludes_order_total_price
model: fct_line_items
given:
- input: ref('stg_tpch__line_items')
rows:
- {order_key: 1, line_number: 1, part_key: 10, supplier_key: 100, quantity: 3, gross_amount: 123.45, discount_rate: 0.05, tax_rate: 0.08, discount_amount: 6.1725, net_revenue: 117.2775, return_flag: N, line_status: O, ship_date: '1992-01-03', commit_date: '1992-01-02', receipt_date: '1992-01-05', ship_mode: MAIL, ship_instruction: NONE}
- input: ref('stg_tpch__orders')
rows:
- {order_key: 1, customer_key: 1000, order_status: O, order_total_price: 126.66, order_date: '1992-01-01', order_priority: 1-URGENT, clerk: Clerk#000000001}
expect:
rows:
- {order_key: 1, line_number: 1, order_date: '1992-01-01', order_year: 1992, customer_key: 1000, part_key: 10, supplier_key: 100, order_status: O, order_priority: 1-URGENT, quantity: 3, gross_amount: 123.45, discount_rate: 0.05, tax_rate: 0.08, discount_amount: 6.1725, net_revenue: 117.2775, return_flag: N, line_status: O, ship_date: '1992-01-03', commit_date: '1992-01-02', receipt_date: '1992-01-05', ship_mode: MAIL, ship_instruction: NONE}

Share with Collaborators​

Use the Share button to add team members:

Share with collaborators

Next Steps​