-
Notifications
You must be signed in to change notification settings - Fork 137
feat: first-run activation menu + bundled dbt sample #1046
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fa3b980
96533a4
c15671f
aa49db3
1e8597f
8f727e8
f524cb0
4848da6
2449a89
c88fd76
2c1eba3
e89955f
eb957f7
883cf21
ff35d93
5f67208
ea6ec07
ae31698
89028ff
6c8b445
33f6e3a
cb53255
53cbde8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # Build/run artifacts that must NOT be committed. `target/*` (not `target/`) | ||
| # so the re-include below actually works — git ignores the CONTENTS of target/ | ||
| # individually, then lets us un-ignore the one pre-compiled artifact we ship. | ||
| # Using `target/` here would exclude the directory as a whole and make the | ||
| # `!target/manifest.json` line inert (git will not descend into an ignored | ||
| # directory to re-include children). | ||
| target/* | ||
| !target/manifest.json | ||
|
|
||
| dbt_packages/ | ||
| logs/ | ||
| .user.yml |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # Jaffle Shop — altimate-code starter sample | ||
|
|
||
| Everything below runs against a local DuckDB file — no cloud warehouse, no | ||
| credentials, no network calls. | ||
|
|
||
| ## What's in here | ||
|
|
||
| ``` | ||
| dbt_project.yml dbt project config | ||
| profiles.yml DuckDB profile — path is project-relative | ||
| sample-manifest.json version metadata used by altimate-code to detect | ||
| stale copies on upgrade | ||
| models/ | ||
| staging/ | ||
| stg_customers.sql renames raw customer columns to snake_case | ||
| stg_orders.sql renames raw order columns | ||
| schema.yml column descriptions + unique/not_null tests | ||
| marts/ | ||
| customers.sql one row per customer, joins in order counts | ||
| orders.sql one row per order, joins in customer names | ||
| schema.yml column descriptions + tests + relationships | ||
| seeds/ | ||
| raw_customers.csv 3 rows of test data | ||
| raw_orders.csv 4 rows of test data | ||
| target/ | ||
| manifest.json PRE-COMPILED dbt manifest — ships with the sample so | ||
| altimate-code's static workflows (/discover, /review) | ||
| work without dbt-core / dbt-duckdb installed | ||
| ``` | ||
|
|
||
| ## What to try (works with zero external tools) | ||
|
|
||
| - `/discover stg_customers` — walk the DAG and see what depends on this model | ||
| - `/review models/marts/customers.sql` — run the reviewer against a mart model | ||
| - Open any `.sql` file and ask altimate-code to explain the transformation | ||
| - Ask altimate-code "what tests would you recommend for `orders`?" | ||
|
|
||
| ## What to try (needs `dbt-core` + `dbt-duckdb` installed) | ||
|
|
||
| ```bash | ||
| pip install dbt-duckdb | ||
| cd ~/altimate-sample-dbt # or wherever you materialized the sample | ||
| dbt seed # load the CSVs into DuckDB | ||
| dbt build # run models + tests | ||
| duckdb target/jaffle.duckdb -c 'select * from customers' | ||
| ``` | ||
|
|
||
| Once `dbt-duckdb` is on your `$PATH`, altimate-code detects it automatically | ||
| and the "run" workflows appear in `/help`. | ||
|
|
||
| ## Bringing your own project | ||
|
|
||
| When you're ready to switch to your real dbt project, `cd` into it and run | ||
| altimate-code again. The scan will pick up your `dbt_project.yml` and offer | ||
| to connect its warehouse. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| name: "jaffle_shop" | ||
| version: "1.0.0" | ||
|
|
||
| profile: "jaffle_shop" | ||
|
|
||
| model-paths: ["models"] | ||
| seed-paths: ["seeds"] | ||
| target-path: "target" | ||
| clean-targets: ["target", "dbt_packages"] | ||
|
|
||
| models: | ||
| jaffle_shop: | ||
| staging: | ||
| +materialized: view | ||
| marts: | ||
| +materialized: table |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| select | ||
| c.customer_id, | ||
| c.first_name, | ||
| c.last_name, | ||
| count(o.order_id) as order_count, | ||
| coalesce(sum(o.amount), 0) as total_amount | ||
| from {{ ref('stg_customers') }} c | ||
| left join {{ ref('stg_orders') }} o on c.customer_id = o.customer_id | ||
| group by c.customer_id, c.first_name, c.last_name |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| select | ||
| o.order_id, | ||
| o.customer_id, | ||
| c.first_name || ' ' || c.last_name as customer_name, | ||
| o.order_date, | ||
| o.amount | ||
| from {{ ref('stg_orders') }} o | ||
| join {{ ref('stg_customers') }} c on o.customer_id = c.customer_id |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| version: 2 | ||
|
|
||
| models: | ||
| - name: customers | ||
| description: One row per customer with total order count and revenue. | ||
| columns: | ||
| - name: customer_id | ||
| description: Primary key. | ||
| data_tests: | ||
| - unique | ||
| - not_null | ||
| - name: order_count | ||
| description: Number of orders placed by the customer (0 when none). | ||
| data_tests: | ||
| - not_null | ||
| - name: total_amount | ||
| description: Sum of all order amounts (0 when none). | ||
| data_tests: | ||
| - not_null | ||
|
|
||
| - name: orders | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: orders model schema omits Prompt for AI agents |
||
| description: One row per order with a joined customer name. | ||
| columns: | ||
| - name: order_id | ||
| description: Primary key. | ||
| data_tests: | ||
| - unique | ||
| - not_null | ||
| - name: customer_id | ||
| description: Foreign key to `stg_customers`. | ||
| data_tests: | ||
| - not_null | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| version: 2 | ||
|
|
||
| models: | ||
| - name: stg_customers | ||
| description: Renamed customer columns from the raw seed. | ||
| columns: | ||
| - name: customer_id | ||
| description: Primary key of the customer. | ||
| data_tests: | ||
| - unique | ||
| - not_null | ||
|
|
||
| - name: stg_orders | ||
| description: Renamed order columns from the raw seed. | ||
| columns: | ||
| - name: order_id | ||
| description: Primary key of the order. | ||
| data_tests: | ||
| - unique | ||
| - not_null | ||
| - name: customer_id | ||
| description: Foreign key to `stg_customers`. | ||
| data_tests: | ||
| - not_null | ||
| - relationships: | ||
| to: ref('stg_customers') | ||
| field: customer_id |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| select | ||
| id as customer_id, | ||
| first_name, | ||
| last_name | ||
| from {{ ref('raw_customers') }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| select | ||
| id as order_id, | ||
| customer_id, | ||
| order_date, | ||
| amount | ||
| from {{ ref('raw_orders') }} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,14 @@ | ||||||||||||||||||||||||||||
| # DuckDB profile — everything runs locally against a single file at | ||||||||||||||||||||||||||||
| # `target/jaffle.duckdb` (created on first `dbt build`). No cloud credentials. | ||||||||||||||||||||||||||||
| # `path:` is unqualified, so dbt-duckdb resolves it against the PROCESS | ||||||||||||||||||||||||||||
| # working directory at build time — NOT the project directory. Run | ||||||||||||||||||||||||||||
| # `dbt build` from the materialized sample dir (`cd <sample-path>`) and | ||||||||||||||||||||||||||||
| # the database lands at `<sample-path>/target/jaffle.duckdb`. | ||||||||||||||||||||||||||||
| # Run it from anywhere else and dbt writes to `$PWD/target/jaffle.duckdb`. | ||||||||||||||||||||||||||||
| jaffle_shop: | ||||||||||||||||||||||||||||
|
Comment on lines
+3
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: Comment incorrectly states that dbt-duckdb resolves the Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||
| target: dev | ||||||||||||||||||||||||||||
| outputs: | ||||||||||||||||||||||||||||
| dev: | ||||||||||||||||||||||||||||
| type: duckdb | ||||||||||||||||||||||||||||
| path: "target/jaffle.duckdb" | ||||||||||||||||||||||||||||
| threads: 1 | ||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| { | ||
| "$comment": "Metadata about this sample project. Distinct from dbt's target/manifest.json — this is our own version stamp for conflict detection on the materialized copy at ~/altimate-sample-dbt/. If you edit any source file below, run ./regenerate.sh and commit the refreshed target/manifest.json alongside your change.", | ||
| "name": "jaffle-shop-duckdb", | ||
| "version": "1.0.0", | ||
| "kind": "altimate-starter-sample", | ||
| "source": "packages/opencode/sample-projects/jaffle-shop-duckdb", | ||
| "requires": { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Prompt for AI agents |
||
| "dbt-core": ">=1.7 <2.0", | ||
| "dbt-duckdb": ">=1.7 <2.0" | ||
| }, | ||
| "notes": [ | ||
| "Renamed profile from the original test fixture: `test_jaffle_shop` → `jaffle_shop`.", | ||
| "DuckDB target file resolves project-relative at `target/jaffle.duckdb`; no host paths bake into the profile.", | ||
| "target/manifest.json ships pre-compiled so static workflows (/discover, /review) work without dbt installed." | ||
| ], | ||
| "$assets_comment": "Single source of truth for the file list shipped to end users. `packages/opencode/src/altimate/onboarding/materialize.ts` copies these into the user's home; `packages/opencode/script/publish.ts` copies the same list into the wrapper npm package at release time; `packages/opencode/test/altimate/onboarding/publish-parity.test.ts` cross-checks both consumers use the same list. Adding a new sample file? Add it here — everything else picks it up automatically.", | ||
| "assets": [ | ||
| { "from": "README.md", "kind": "file", "required": true }, | ||
| { "from": "dbt_project.yml", "kind": "file", "required": true }, | ||
| { "from": "profiles.yml", "kind": "file", "required": true }, | ||
| { "from": "sample-manifest.json", "kind": "file", "required": true }, | ||
| { "from": ".gitignore", "kind": "file", "required": false }, | ||
| { "from": "models", "kind": "dir", "required": true }, | ||
| { "from": "seeds", "kind": "dir", "required": true }, | ||
| { "from": "target/manifest.json", "kind": "file", "required": true } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| id,first_name,last_name | ||
| 1,Alice,Smith | ||
| 2,Bob,Jones | ||
| 3,Carol,White |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| id,customer_id,order_date,amount | ||
| 1,1,2024-01-15,100 | ||
| 2,1,2024-02-20,200 | ||
| 3,2,2024-01-10,150 | ||
| 4,3,2024-03-05,300 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3: The file tree in the 'What's in here' section omits
.gitignore, which is one of the shipped files (confirmed viaMATERIALIZE_ENTRIESinmaterialize.ts). Users who materialize the sample will get a.gitignorewithout seeing it documented. Add it to the tree so the listing stays accurate.Prompt for AI agents