> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getcanonic.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Guide: Jaffle Shop (dbt + MetricFlow)

> The classic dbt Jaffle Shop dataset, with MetricFlow semantic models as modeling-tier evidence.

A canonic project backed by the classic [dbt Jaffle Shop](https://github.com/dbt-labs/jaffle-shop) dataset, demonstrating canonic's full Phase 1 feature set with a dbt manifest that includes **MetricFlow semantic models and metrics**: not just table/column evidence.

<Info>Full source: [`examples/jaffle-shop/`](https://github.com/mischuh/canonic/tree/main/examples/jaffle-shop)</Info>

## Schema

```
customers ──< orders ──< order_items >── products
                 │
               stores
```

| Table         | Rows | Description                              |
| ------------- | ---- | ---------------------------------------- |
| `customers`   | 20   | Individual and business accounts         |
| `stores`      | 5    | Physical Jaffle Shop locations           |
| `products`    | 10   | Jaffles and beverages                    |
| `orders`      | 25   | One row per order with payment breakdown |
| `order_items` | 37   | One row per line item                    |

## Setup

Bundled DuckDB file: no server, no credentials.

```bash theme={null}
cd examples/jaffle-shop   # canonic commands must run from here
canonic status
# Canonic project: jaffle-shop-demo (version 1)
```

## Quickstart

```bash theme={null}
canonic ingest --bootstrap                              # introspects DuckDB + loads dbt manifest as modeling-tier evidence
canonic query --metrics revenue --dimensions store_id    # revenue by store
canonic mcp start                                        # expose metrics to any MCP-compatible agent
```

`canonic status`, `canonic ingest --bootstrap`, `canonic query`, and `canonic mcp start` never call the LLM: every table here has a declared primary key, so grain is inferred deterministically. `CANONIC_LLM_API_KEY` and `llm:` in `canonic.yaml` only matter if you point canonic at a schema with undeclared keys, where low-confidence grain-drafting falls back to the model.

## What canonic extracts from the dbt manifest

The `jaffle_dbt` connection parses `manifest.json` (schema v11, dbt 1.7, MetricFlow) as modeling-tier evidence, which ranks higher than live DuckDB introspection during reconciliation:

```yaml theme={null}
  - id: jaffle_dbt
    type: dbt
    params:
      manifest_path: dbt/manifest.json
      target_connection: jaffle_duckdb   # the physical connection these models describe
```

`target_connection` is what makes this a companion to `jaffle_duckdb` rather than an independent source: it attributes the dbt-derived evidence to `jaffle_duckdb`'s connection id, so it enriches `semantics/jaffle_duckdb/*.yaml` instead of proposing separate, same-named files under `semantics/jaffle_dbt/` (see [Connectors](/concepts/connectors#definition)). From the manifest, canonic extracts:

* **5 model nodes** → `RelationSchema` with named columns, types, primary keys, and foreign-key paths.
* **2 semantic models** → entity (grain), foreign-join paths, named measure and dimension definitions.
* **3 metrics** → `revenue`, `order_count`, `units_sold`.

Because MetricFlow's semantic models name measures explicitly, the resulting semantic sources in `semantics/jaffle_duckdb/` carry business-meaningful measure names (`revenue`, `order_count`) rather than generic inferred ones (`total_amount`, `row_count`), the clearest illustration in these examples of why [modeling-tier evidence outranks raw introspection](/concepts/connectors#schema-acquisition-ladder).

## Metrics

`contracts/metrics/` ships **8** metric contracts. Three are the canonical showcase bindings straight from the dbt manifest's MetricFlow metrics. The rest are supporting ratio and count metrics the bootstrap also drafted from the same manifest.

| Metric                            | Source · measure                       | Notes                          |
| --------------------------------- | -------------------------------------- | ------------------------------ |
| `revenue`                         | `orders.revenue`                       | Canonical, named by MetricFlow |
| `order_count`                     | `orders.order_count`                   | Canonical, named by MetricFlow |
| `units_sold`                      | `order_items.units_sold`               | Canonical, named by MetricFlow |
| `avg_revenue`                     | ratio: `revenue` / `num_customers`     | Supporting metric              |
| `avg_product_price`               | ratio: `total_price` / `product_count` | Supporting metric              |
| `num_customers` / `product_count` | `customers`/`products` row counts      | Supporting metric              |
| `total_price`                     | `products.total_price`                 | Supporting metric              |

No guardrails or assertions ship in this example.

## Regenerating the artifacts

```bash theme={null}
bash scripts/build.sh
```

Clones the upstream `dbt-labs/jaffle-shop`, runs `dbt build` with `dbt-duckdb`, and copies the resulting database and manifest back into the example directory.
