A Kimball star schema with dbt on AdventureWorks
A step-by-step tutorial repository that builds a Kimball star schema with dbt on the AdventureWorks sample data, on DuckDB by default with a Postgres option. The fact table, fct_sales, holds 1 row per order detail. It joins a seeded dim_date plus 5 more tables (dim_product, dim_customer, dim_address, dim_credit_card, dim_order_status), and dbt_utils.generate_surrogate_key generates every key.
The tutorial works in the Kimball order: choose the business process, declare the grain, then name the dimensions and the facts. Sales orders arrive as a header and its detail lines, so the grain decision is in plain view: a column that belongs to the order, repeated on every detail row, is counted once per line by any SUM. Surrogate keys decouple the model from the source system's ids, and the seeded date dimension (the dbt_date package does not support DuckDB) shows why every star carries its own calendar.
Extend it by adding a second fact at a different grain, such as 1 row per order, and a uniqueness test on each fact's key. Then write the grain of every table as 1 sentence in the model's documentation, which is the habit every later project on this list relies on.
The first question in most modeling rounds is the grain of the fact table. After this project you answer it in 1 sentence, name the test that enforces it and explain the double count it prevents, which is the difference between knowing the vocabulary of a star schema and having built one.



