Skip to content

docs(examples): add a commerce semantic model - #695

Closed
ekut wants to merge 1 commit into
apache:mainfrom
ekut:add-commerce-example
Closed

ekut wants to merge 1 commit into
apache:mainfrom
ekut:add-commerce-example

Conversation

@ekut

@ekut ekut commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

The roadmap lists "Curated domain-specific semantic model templates" among its deliverables, with retail among the models that organizations keep recreating. Its Developer Experience section asks for "annotated examples, especially for AI context fields" (discussion #9). This adds a model of an online store whose ai_context is written for an agent. examples/commerce.yaml is entities/commerce.yaml of the dactopus-data-models 0.11.1 release (https://github.com/Dactopus/dactopus-data-models/releases/tag/v0.11.1), unchanged except for the license header and a title comment. The model keeps developing in the library; this copy is a snapshot of the tag, and the checks below reproduce from it.

What it shows:

  • Model-level ai_context.instructions for an agent: how the platforms' sales reports count orders, customers, categories and brands, and which metric answers which question. ai_context is set on 99 of the 100 fields and on all 43 metrics.
  • One model over canonical tables that a package of the store's platform fills, so a Shopify store and a WooCommerce store answer the same questions from the same model.
  • Keys and relationships over (source_id, id): source_id is the store a row comes from, so several stores share one deployment.
  • 10 datasets, 100 fields, 25 dataset-scoped metrics and 18 model-level metrics over 9 many-to-one relationships, expressions in the sql form.

Two parts of the model go beyond Layer 3 (core-spec/wide_table_semantics.md):

  • The instructions and four descriptions (orders.average_order_value, line_categories.category_path, line_categories.is_direct, product_categories.is_direct) suggest a filter on the many side, such as the average order value of the orders with a line in a category. Appendix A.1 lists such existence filters for a later version.
  • Each of the 18 model-level metrics reads orders and one of its line or refund datasets in one aggregate. Section 5.2 rejects that for now as deferred.

The model's answers are checked against fixtures of two stores, one on Shopify and one on WooCommerce. The fixtures are the canonical tables as CSV, with DDL in standard SQL. With them come 95 questions and expected rows derived by hand (tests/<package>/questions.yaml in the library, run by tests/run_canon.py). On ClickHouse 26.9, through dactopus-ossie-clickhouse 0.13.0, all 95 return the expected rows. On DuckDB 1.5.6 with the community extension ossie 0.3.0 the runner first lifts the dataset-scoped metrics to the model level, because the extension does not read them yet. Then 72 questions return the same rows. The extension refuses 19 (two grains in one question, a filter on the many side, a question without a metric). The other 4 differ because it emits every join as INNER, as its docs/limitations.md says, so rows without a match drop out.

validation/validate.py on main (0a908aa) passes. The PR also adds the file to .github/workflows/validation-ci.yml next to the other examples, so a schema change that breaks it fails CI. version stays 0.2.0.dev0; if #691 lands first, I will bump it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant