altimate-code 0.4.9 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +22 -60
  3. package/package.json +54 -14
  4. package/postinstall.mjs +35 -0
  5. package/skills/cost-report/SKILL.md +134 -0
  6. package/skills/data-viz/SKILL.md +135 -0
  7. package/skills/data-viz/references/component-guide.md +394 -0
  8. package/skills/dbt-analyze/SKILL.md +130 -0
  9. package/skills/dbt-analyze/references/altimate-dbt-commands.md +66 -0
  10. package/skills/dbt-analyze/references/lineage-interpretation.md +58 -0
  11. package/skills/dbt-develop/SKILL.md +151 -0
  12. package/skills/dbt-develop/references/altimate-dbt-commands.md +66 -0
  13. package/skills/dbt-develop/references/common-mistakes.md +49 -0
  14. package/skills/dbt-develop/references/incremental-strategies.md +118 -0
  15. package/skills/dbt-develop/references/layer-patterns.md +158 -0
  16. package/skills/dbt-develop/references/medallion-architecture.md +125 -0
  17. package/skills/dbt-develop/references/yaml-generation.md +90 -0
  18. package/skills/dbt-docs/SKILL.md +99 -0
  19. package/skills/dbt-docs/references/altimate-dbt-commands.md +66 -0
  20. package/skills/dbt-docs/references/documentation-standards.md +94 -0
  21. package/skills/dbt-test/SKILL.md +121 -0
  22. package/skills/dbt-test/references/altimate-dbt-commands.md +66 -0
  23. package/skills/dbt-test/references/custom-tests.md +59 -0
  24. package/skills/dbt-test/references/schema-test-patterns.md +103 -0
  25. package/skills/dbt-test/references/unit-test-guide.md +121 -0
  26. package/skills/dbt-troubleshoot/SKILL.md +187 -0
  27. package/skills/dbt-troubleshoot/references/altimate-dbt-commands.md +66 -0
  28. package/skills/dbt-troubleshoot/references/compilation-errors.md +57 -0
  29. package/skills/dbt-troubleshoot/references/runtime-errors.md +71 -0
  30. package/skills/dbt-troubleshoot/references/test-failures.md +95 -0
  31. package/skills/lineage-diff/SKILL.md +64 -0
  32. package/skills/pii-audit/SKILL.md +117 -0
  33. package/skills/query-optimize/SKILL.md +86 -0
  34. package/skills/schema-migration/SKILL.md +119 -0
  35. package/skills/sql-review/SKILL.md +118 -0
  36. package/skills/sql-translate/SKILL.md +68 -0
  37. package/skills/teach/SKILL.md +54 -0
  38. package/skills/train/SKILL.md +51 -0
  39. package/skills/training-status/SKILL.md +45 -0
@@ -0,0 +1,90 @@
1
+ # YAML Config Generation
2
+
3
+ ## sources.yml — Define Raw Data Sources
4
+
5
+ Generate from warehouse metadata using:
6
+ ```bash
7
+ altimate-dbt columns-source --source <source_name> --table <table_name>
8
+ ```
9
+
10
+ Template:
11
+ ```yaml
12
+ version: 2
13
+
14
+ sources:
15
+ - name: raw_stripe
16
+ description: Raw Stripe payment data
17
+ database: raw
18
+ schema: stripe
19
+ tables:
20
+ - name: payments
21
+ description: All payment transactions
22
+ columns:
23
+ - name: payment_id
24
+ description: Primary key
25
+ tests:
26
+ - unique
27
+ - not_null
28
+ - name: amount
29
+ description: Payment amount in cents
30
+ - name: created_at
31
+ description: Payment creation timestamp
32
+ tests:
33
+ - not_null
34
+ ```
35
+
36
+ ## schema.yml — Model Documentation and Tests
37
+
38
+ Generate after building a model using:
39
+ ```bash
40
+ altimate-dbt columns --model <model_name>
41
+ ```
42
+
43
+ Template:
44
+ ```yaml
45
+ version: 2
46
+
47
+ models:
48
+ - name: stg_stripe__payments
49
+ description: Staged Stripe payments with renamed columns and type casts
50
+ columns:
51
+ - name: payment_id
52
+ description: Primary key from source
53
+ tests:
54
+ - unique
55
+ - not_null
56
+ - name: amount_dollars
57
+ description: Payment amount converted to dollars
58
+ ```
59
+
60
+ ## Column Pattern Heuristics
61
+
62
+ When auto-generating YAML, infer descriptions and tests from column names:
63
+
64
+ | Pattern | Description Template | Auto-Tests |
65
+ |---------|---------------------|------------|
66
+ | `*_id` | "Foreign key to {table}" or "Primary key" | `unique`, `not_null` |
67
+ | `*_at`, `*_date`, `*_timestamp` | "Timestamp of {event}" | `not_null` |
68
+ | `*_amount`, `*_price`, `*_cost` | "Monetary value" | `not_null` |
69
+ | `is_*`, `has_*` | "Boolean flag for {condition}" | `accepted_values: [true, false]` |
70
+ | `*_type`, `*_status`, `*_category` | "Categorical" | `accepted_values` (if inferable) |
71
+ | `*_count`, `*_total`, `*_sum` | "Aggregated count/total" | — |
72
+ | `*_name`, `*_title`, `*_label` | "Human-readable name" | — |
73
+
74
+ ## File Naming Conventions
75
+
76
+ | Convention | Example |
77
+ |-----------|---------|
78
+ | Sources | `_<source>__sources.yml` |
79
+ | Model schema | `_<model>__models.yml` or `schema.yml` |
80
+ | Properties | `_<model>__models.yml` |
81
+
82
+ Match whatever convention the project already uses. Check existing `.yml` files in the same directory.
83
+
84
+ ## Merging with Existing YAML
85
+
86
+ When YAML files already exist:
87
+ 1. Read the existing file first
88
+ 2. Add new entries without duplicating existing ones
89
+ 3. Preserve human-written descriptions
90
+ 4. Use `edit` tool (not `write`) to merge
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: dbt-docs
3
+ description: Document dbt models and columns in schema.yml with business context — model descriptions, column definitions, and doc blocks. Use when adding or improving documentation for discoverability. Powered by altimate-dbt.
4
+ ---
5
+
6
+ # dbt Documentation
7
+
8
+ ## Requirements
9
+ **Agent:** builder or migrator (requires file write access)
10
+ **Tools used:** bash (runs `altimate-dbt` commands), read, glob, write, edit
11
+
12
+ ## When to Use This Skill
13
+
14
+ **Use when the user wants to:**
15
+ - Add or improve model descriptions in schema.yml
16
+ - Write column-level descriptions with business context
17
+ - Create shared doc blocks for reusable definitions
18
+ - Improve dbt docs site content
19
+
20
+ **Do NOT use for:**
21
+ - Adding tests → use `dbt-test`
22
+ - Creating new models → use `dbt-develop`
23
+ - Generating sources.yml from scratch → use `dbt-develop`
24
+
25
+ ## Workflow
26
+
27
+ ### 1. Understand the Model
28
+
29
+ ```bash
30
+ altimate-dbt columns --model <name> # what columns exist
31
+ altimate-dbt parents --model <name> # what feeds this model
32
+ altimate-dbt children --model <name> # who consumes it
33
+ altimate-dbt compile --model <name> # see the rendered SQL
34
+ ```
35
+
36
+ Read the model SQL to understand the transformations:
37
+ ```bash
38
+ glob models/**/<name>.sql
39
+ read <model_file>
40
+ ```
41
+
42
+ ### 2. Read Existing Documentation
43
+
44
+ Check what's already documented:
45
+ ```bash
46
+ glob models/**/*schema*.yml models/**/*_models.yml
47
+ read <yaml_file>
48
+ ```
49
+
50
+ ### 3. Write Documentation
51
+
52
+ See [references/documentation-standards.md](references/documentation-standards.md) for quality guidelines.
53
+
54
+ #### Model-Level Description
55
+ Cover: **What** (business entity), **Why** (use case), **How** (key transforms), **When** (materialization).
56
+
57
+ ```yaml
58
+ - name: fct_daily_revenue
59
+ description: >
60
+ Daily revenue aggregation by product category. Joins staged orders with
61
+ product dimensions and calculates gross/net revenue. Materialized as
62
+ incremental with unique key on (date_day, category_id). Used by the
63
+ finance team for daily P&L reporting.
64
+ ```
65
+
66
+ #### Column-Level Description
67
+ Describe business meaning, derivation formula, and caveats:
68
+
69
+ ```yaml
70
+ columns:
71
+ - name: net_revenue
72
+ description: >
73
+ Total revenue minus refunds and discounts for the day.
74
+ Formula: gross_revenue - refund_amount - discount_amount.
75
+ Can be negative if refunds exceed sales.
76
+ ```
77
+
78
+ ### 4. Validate
79
+
80
+ ```bash
81
+ altimate-dbt compile --model <name> # ensure YAML is valid
82
+ ```
83
+
84
+ ## Common Mistakes
85
+
86
+ | Mistake | Fix |
87
+ |---------|-----|
88
+ | Restating the column name as the description | `"order_id: The order ID"` → describe business meaning |
89
+ | Empty descriptions | Every column should have a description. If unsure, describe the source. |
90
+ | Not reading the SQL before documenting | Read the model to understand derivation logic |
91
+ | Duplicating descriptions across models | Use doc blocks for shared definitions |
92
+ | Writing implementation details instead of business context | Describe what it means to the business, not how it's computed |
93
+
94
+ ## Reference Guides
95
+
96
+ | Guide | Use When |
97
+ |-------|----------|
98
+ | [references/altimate-dbt-commands.md](references/altimate-dbt-commands.md) | Need the full CLI reference |
99
+ | [references/documentation-standards.md](references/documentation-standards.md) | Writing high-quality descriptions |
@@ -0,0 +1,66 @@
1
+ # altimate-dbt Command Reference
2
+
3
+ All dbt operations use the `altimate-dbt` CLI. Output is JSON to stdout; logs go to stderr.
4
+
5
+ ```bash
6
+ altimate-dbt <command> [args...]
7
+ altimate-dbt <command> [args...] --format text # Human-readable output
8
+ ```
9
+
10
+ ## First-Time Setup
11
+
12
+ ```bash
13
+ altimate-dbt init # Auto-detect project root
14
+ altimate-dbt init --project-root /path # Explicit root
15
+ altimate-dbt init --python-path /path # Override Python
16
+ altimate-dbt doctor # Verify setup
17
+ altimate-dbt info # Project name, adapter, root
18
+ ```
19
+
20
+ ## Build & Run
21
+
22
+ ```bash
23
+ altimate-dbt build --model <name> [--downstream] # compile + run + test
24
+ altimate-dbt run --model <name> [--downstream] # materialize only
25
+ altimate-dbt test --model <name> # run tests only
26
+ altimate-dbt build-project # full project build
27
+ ```
28
+
29
+ ## Compile
30
+
31
+ ```bash
32
+ altimate-dbt compile --model <name>
33
+ altimate-dbt compile-query --query "SELECT * FROM {{ ref('stg_orders') }}" [--model <context>]
34
+ ```
35
+
36
+ ## Execute SQL
37
+
38
+ ```bash
39
+ altimate-dbt execute --query "SELECT count(*) FROM {{ ref('orders') }}" --limit 100
40
+ ```
41
+
42
+ ## Schema & DAG
43
+
44
+ ```bash
45
+ altimate-dbt columns --model <name> # column names and types
46
+ altimate-dbt columns-source --source <src> --table <tbl> # source table columns
47
+ altimate-dbt column-values --model <name> --column <col> # sample values
48
+ altimate-dbt children --model <name> # downstream models
49
+ altimate-dbt parents --model <name> # upstream models
50
+ ```
51
+
52
+ ## Packages
53
+
54
+ ```bash
55
+ altimate-dbt deps # install packages.yml
56
+ altimate-dbt add-packages --packages dbt-utils,dbt-expectations
57
+ ```
58
+
59
+ ## Error Handling
60
+
61
+ All errors return JSON with `error` and `fix` fields:
62
+ ```json
63
+ { "error": "dbt-core is not installed", "fix": "Install it: python3 -m pip install dbt-core" }
64
+ ```
65
+
66
+ Run `altimate-dbt doctor` as the first diagnostic step for any failure.
@@ -0,0 +1,94 @@
1
+ # Documentation Standards
2
+
3
+ ## Model Descriptions
4
+
5
+ A good model description answers four questions:
6
+
7
+ 1. **What**: What business entity or metric does this represent?
8
+ 2. **Why**: Who uses it and for what purpose?
9
+ 3. **How**: Key transformations (joins, filters, aggregations)
10
+ 4. **Grain**: What does one row represent?
11
+
12
+ ### Good Example
13
+ ```yaml
14
+ description: >
15
+ Daily revenue by product category. One row per category per day.
16
+ Joins staged orders with product dimensions, calculates gross and net revenue.
17
+ Used by the finance team for P&L reporting and the marketing team for
18
+ campaign attribution.
19
+ ```
20
+
21
+ ### Bad Example
22
+ ```yaml
23
+ description: "This model contains daily revenue data."
24
+ ```
25
+
26
+ ## Column Descriptions
27
+
28
+ ### Primary Keys
29
+ State that it's a primary key and where it originates:
30
+ ```yaml
31
+ - name: order_id
32
+ description: "Primary key. Unique identifier for each order, sourced from the orders table in Stripe."
33
+ ```
34
+
35
+ ### Foreign Keys
36
+ State what it references:
37
+ ```yaml
38
+ - name: customer_id
39
+ description: "Foreign key to dim_customers. The customer who placed this order."
40
+ ```
41
+
42
+ ### Calculated Columns
43
+ Include the formula:
44
+ ```yaml
45
+ - name: net_revenue
46
+ description: "Gross revenue minus refunds and discounts. Formula: gross_amount - refund_amount - discount_amount. Can be negative."
47
+ ```
48
+
49
+ ### Status/Category Columns
50
+ List the possible values:
51
+ ```yaml
52
+ - name: order_status
53
+ description: "Current order status. Values: pending, shipped, delivered, cancelled, refunded."
54
+ ```
55
+
56
+ ### Timestamps
57
+ State what event they represent:
58
+ ```yaml
59
+ - name: shipped_at
60
+ description: "Timestamp when the order was shipped. NULL if not yet shipped. UTC timezone."
61
+ ```
62
+
63
+ ## Doc Blocks (Shared Definitions)
64
+
65
+ For definitions reused across multiple models, create doc blocks:
66
+
67
+ ```markdown
68
+ -- docs/shared_definitions.md
69
+ {% docs customer_id %}
70
+ Unique identifier for a customer. Sourced from the customers table
71
+ in the CRM system. Used as the primary join key across all
72
+ customer-related models.
73
+ {% enddocs %}
74
+ ```
75
+
76
+ Reference in YAML:
77
+ ```yaml
78
+ - name: customer_id
79
+ description: "{{ doc('customer_id') }}"
80
+ ```
81
+
82
+ ## Anti-Patterns
83
+
84
+ | Anti-Pattern | Why It's Bad | Better Approach |
85
+ |-------------|-------------|-----------------|
86
+ | `"The order ID"` | Just restates the column name | Describe origin and business meaning |
87
+ | `"See code"` | Defeats the purpose of docs | Summarize the logic |
88
+ | `""` (empty) | Missing documentation | Write something, even if brief |
89
+ | Technical jargon only | Business users can't understand | Lead with business meaning, add technical detail after |
90
+
91
+ ## Official Documentation
92
+
93
+ - **dbt documentation**: https://docs.getdbt.com/docs/build/documentation
94
+ - **Doc blocks**: https://docs.getdbt.com/docs/build/documentation#using-docs-blocks
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: dbt-test
3
+ description: Add schema tests, unit tests, and data quality checks to dbt models. Use when validating data integrity, adding test definitions to schema.yml, writing unit tests, or practicing test-driven development in dbt. Powered by altimate-dbt.
4
+ ---
5
+
6
+ # dbt Testing
7
+
8
+ ## Requirements
9
+ **Agent:** builder or migrator (requires file write access)
10
+ **Tools used:** bash (runs `altimate-dbt` commands), read, glob, write, edit, altimate_core_testgen, altimate_core_validate
11
+
12
+ ## When to Use This Skill
13
+
14
+ **Use when the user wants to:**
15
+ - Add tests to a model's schema.yml (unique, not_null, relationships, accepted_values)
16
+ - Write dbt unit tests (mock inputs → expected outputs)
17
+ - Create custom generic or singular tests
18
+ - Debug why a test is failing
19
+ - Practice test-driven development in dbt
20
+
21
+ **Do NOT use for:**
22
+ - Creating or modifying model SQL → use `dbt-develop`
23
+ - Writing model descriptions → use `dbt-docs`
24
+ - Debugging build/compilation errors → use `dbt-troubleshoot`
25
+
26
+ ## The Iron Rule
27
+
28
+ **Never modify a test to make it pass without understanding why it's failing.**
29
+
30
+ A failing test is information. It means either:
31
+ 1. The data has a real quality issue (fix the data or the model)
32
+ 2. The test expectation is wrong (update the test with justification)
33
+ 3. The model logic is wrong (fix the model)
34
+
35
+ Option 2 requires explicit user confirmation. Do not silently weaken tests.
36
+
37
+ ## Schema Test Workflow
38
+
39
+ ### 1. Discover Columns
40
+
41
+ ```bash
42
+ altimate-dbt columns --model <name>
43
+ altimate-dbt column-values --model <name> --column <col>
44
+ ```
45
+
46
+ ### 2. Read Existing Tests
47
+
48
+ ```bash
49
+ glob models/**/*schema*.yml models/**/*_models.yml
50
+ read <yaml_file>
51
+ ```
52
+
53
+ ### 3. Generate Tests
54
+
55
+ **Auto-generate with `altimate_core_testgen`:** Pass the compiled SQL and schema to generate boundary-value, NULL-handling, and edge-case test assertions automatically. This produces executable test SQL covering cases you might miss manually.
56
+
57
+ ```
58
+ altimate_core_testgen(sql: <compiled_sql>, schema_context: <schema_object>)
59
+ ```
60
+
61
+ Review the generated tests — keep what makes sense, discard trivial ones. Then apply test rules based on column patterns — see [references/schema-test-patterns.md](references/schema-test-patterns.md).
62
+
63
+ ### 4. Write YAML
64
+
65
+ Merge into existing schema.yml (don't duplicate). Use `edit` for existing files, `write` for new ones.
66
+
67
+ ### 5. Validate SQL
68
+
69
+ Before running, validate the compiled model SQL to catch syntax and schema errors early:
70
+
71
+ ```
72
+ altimate_core_validate(sql: <compiled_sql>, schema_context: <schema_object>)
73
+ ```
74
+
75
+ ### 6. Run Tests
76
+
77
+ ```bash
78
+ altimate-dbt test --model <name> # run tests for this model
79
+ altimate-dbt build --model <name> # build + test together
80
+ ```
81
+
82
+ ## Unit Test Workflow
83
+
84
+ See [references/unit-test-guide.md](references/unit-test-guide.md) for the full unit test framework.
85
+
86
+ ### Quick Pattern
87
+
88
+ ```yaml
89
+ unit_tests:
90
+ - name: test_order_total_calculation
91
+ model: fct_orders
92
+ given:
93
+ - input: ref('stg_orders')
94
+ rows:
95
+ - { order_id: 1, quantity: 3, unit_price: 10.00 }
96
+ - { order_id: 2, quantity: 1, unit_price: 25.00 }
97
+ expect:
98
+ rows:
99
+ - { order_id: 1, order_total: 30.00 }
100
+ - { order_id: 2, order_total: 25.00 }
101
+ ```
102
+
103
+ ## Common Mistakes
104
+
105
+ | Mistake | Fix |
106
+ |---------|-----|
107
+ | Testing every column with `not_null` | Only test columns that should never be null. Think about what NULL means. |
108
+ | Missing `unique` test on primary keys | Every primary key needs `unique` + `not_null` |
109
+ | `accepted_values` with incomplete list | Use `altimate-dbt column-values` to discover real values first |
110
+ | Modifying a test to make it pass | Understand WHY it fails first. The test might be right. |
111
+ | No `relationships` test on foreign keys | Add `relationships: {to: ref('parent'), field: parent_id}` |
112
+ | Unit testing trivial logic | Don't unit test `SELECT a, b FROM source`. Test calculations and business logic. |
113
+
114
+ ## Reference Guides
115
+
116
+ | Guide | Use When |
117
+ |-------|----------|
118
+ | [references/altimate-dbt-commands.md](references/altimate-dbt-commands.md) | Need the full CLI reference |
119
+ | [references/schema-test-patterns.md](references/schema-test-patterns.md) | Adding schema.yml tests by column pattern |
120
+ | [references/unit-test-guide.md](references/unit-test-guide.md) | Writing dbt unit tests |
121
+ | [references/custom-tests.md](references/custom-tests.md) | Creating generic or singular tests |
@@ -0,0 +1,66 @@
1
+ # altimate-dbt Command Reference
2
+
3
+ All dbt operations use the `altimate-dbt` CLI. Output is JSON to stdout; logs go to stderr.
4
+
5
+ ```bash
6
+ altimate-dbt <command> [args...]
7
+ altimate-dbt <command> [args...] --format text # Human-readable output
8
+ ```
9
+
10
+ ## First-Time Setup
11
+
12
+ ```bash
13
+ altimate-dbt init # Auto-detect project root
14
+ altimate-dbt init --project-root /path # Explicit root
15
+ altimate-dbt init --python-path /path # Override Python
16
+ altimate-dbt doctor # Verify setup
17
+ altimate-dbt info # Project name, adapter, root
18
+ ```
19
+
20
+ ## Build & Run
21
+
22
+ ```bash
23
+ altimate-dbt build --model <name> [--downstream] # compile + run + test
24
+ altimate-dbt run --model <name> [--downstream] # materialize only
25
+ altimate-dbt test --model <name> # run tests only
26
+ altimate-dbt build-project # full project build
27
+ ```
28
+
29
+ ## Compile
30
+
31
+ ```bash
32
+ altimate-dbt compile --model <name>
33
+ altimate-dbt compile-query --query "SELECT * FROM {{ ref('stg_orders') }}" [--model <context>]
34
+ ```
35
+
36
+ ## Execute SQL
37
+
38
+ ```bash
39
+ altimate-dbt execute --query "SELECT count(*) FROM {{ ref('orders') }}" --limit 100
40
+ ```
41
+
42
+ ## Schema & DAG
43
+
44
+ ```bash
45
+ altimate-dbt columns --model <name> # column names and types
46
+ altimate-dbt columns-source --source <src> --table <tbl> # source table columns
47
+ altimate-dbt column-values --model <name> --column <col> # sample values
48
+ altimate-dbt children --model <name> # downstream models
49
+ altimate-dbt parents --model <name> # upstream models
50
+ ```
51
+
52
+ ## Packages
53
+
54
+ ```bash
55
+ altimate-dbt deps # install packages.yml
56
+ altimate-dbt add-packages --packages dbt-utils,dbt-expectations
57
+ ```
58
+
59
+ ## Error Handling
60
+
61
+ All errors return JSON with `error` and `fix` fields:
62
+ ```json
63
+ { "error": "dbt-core is not installed", "fix": "Install it: python3 -m pip install dbt-core" }
64
+ ```
65
+
66
+ Run `altimate-dbt doctor` as the first diagnostic step for any failure.
@@ -0,0 +1,59 @@
1
+ # Custom dbt Tests
2
+
3
+ ## Generic Tests (Reusable)
4
+
5
+ Generic tests are macros in `tests/generic/` or `macros/` that accept parameters:
6
+
7
+ ```sql
8
+ -- tests/generic/test_positive_values.sql
9
+ {% test positive_values(model, column_name) %}
10
+
11
+ select *
12
+ from {{ model }}
13
+ where {{ column_name }} < 0
14
+
15
+ {% endtest %}
16
+ ```
17
+
18
+ Usage in schema.yml:
19
+ ```yaml
20
+ columns:
21
+ - name: amount
22
+ tests:
23
+ - positive_values
24
+ ```
25
+
26
+ ## Singular Tests (One-Off)
27
+
28
+ Singular tests are standalone SQL files in `tests/` that return failing rows:
29
+
30
+ ```sql
31
+ -- tests/assert_no_orphan_orders.sql
32
+ -- Orders must have a matching customer
33
+ select o.order_id
34
+ from {{ ref('fct_orders') }} o
35
+ left join {{ ref('dim_customers') }} c on o.customer_id = c.customer_id
36
+ where c.customer_id is null
37
+ ```
38
+
39
+ A passing test returns zero rows.
40
+
41
+ ## When to Use Which
42
+
43
+ | Type | Use When |
44
+ |------|----------|
45
+ | Schema tests (built-in) | `unique`, `not_null`, `accepted_values`, `relationships` |
46
+ | dbt-utils tests | `expression_is_true`, `unique_combination_of_columns` |
47
+ | Generic tests (custom) | Reusable validation logic across multiple models |
48
+ | Singular tests | One-off business rules, cross-model assertions |
49
+ | Unit tests | Testing calculation logic with mocked inputs |
50
+
51
+ ## Naming Conventions
52
+
53
+ - Generic tests: `test_<what_it_checks>.sql` in `tests/generic/`
54
+ - Singular tests: `assert_<business_rule>.sql` in `tests/`
55
+
56
+ ## Official Documentation
57
+
58
+ - **Data tests**: https://docs.getdbt.com/docs/build/data-tests
59
+ - **Custom generic tests**: https://docs.getdbt.com/docs/build/data-tests#generic-data-tests
@@ -0,0 +1,103 @@
1
+ # Schema Test Patterns
2
+
3
+ ## Test Generation Rules
4
+
5
+ Apply tests based on column name patterns:
6
+
7
+ | Column Pattern | Tests |
8
+ |---|---|
9
+ | `*_id` (primary key) | `unique`, `not_null` |
10
+ | `*_id` (foreign key) | `not_null`, `relationships: {to: ref('parent'), field: id}` |
11
+ | `status`, `type`, `category` | `accepted_values` (discover values with `altimate-dbt column-values`) |
12
+ | `*_at`, `*_date`, `*_timestamp` | `not_null` (if event timestamp that should always exist) |
13
+ | `is_*`, `has_*` (booleans) | `accepted_values: [true, false]` |
14
+ | Columns in JOIN conditions | `not_null` (nulls cause dropped rows in INNER JOIN) |
15
+
16
+ ## Test Priority Framework
17
+
18
+ Not every column needs every test. Prioritize:
19
+
20
+ ### Tier 1: Always Test (Primary Keys)
21
+ ```yaml
22
+ - name: order_id
23
+ tests:
24
+ - unique
25
+ - not_null
26
+ ```
27
+
28
+ ### Tier 2: Test Foreign Keys
29
+ ```yaml
30
+ - name: customer_id
31
+ tests:
32
+ - not_null
33
+ - relationships:
34
+ to: ref('dim_customers')
35
+ field: customer_id
36
+ ```
37
+
38
+ ### Tier 3: Test Business-Critical Columns
39
+ ```yaml
40
+ - name: order_status
41
+ tests:
42
+ - not_null
43
+ - accepted_values:
44
+ values: ['pending', 'shipped', 'delivered', 'cancelled']
45
+ ```
46
+
47
+ ### Tier 4: Test Derived Columns (When Logic is Complex)
48
+ ```yaml
49
+ - name: net_revenue
50
+ tests:
51
+ - not_null
52
+ - dbt_utils.expression_is_true:
53
+ expression: ">= 0"
54
+ ```
55
+
56
+ ## Discovering Values for accepted_values
57
+
58
+ Before adding `accepted_values`, discover what actually exists:
59
+
60
+ ```bash
61
+ altimate-dbt column-values --model <name> --column status
62
+ ```
63
+
64
+ This prevents false test failures from values you didn't know about.
65
+
66
+ ## Cost-Conscious Testing
67
+
68
+ For large tables, add `where` clauses to expensive tests:
69
+
70
+ ```yaml
71
+ - name: order_id
72
+ tests:
73
+ - unique:
74
+ config:
75
+ where: "order_date >= current_date - interval '30 days'"
76
+ ```
77
+
78
+ ## dbt-utils Test Extensions
79
+
80
+ Common additional tests from `dbt-utils`:
81
+
82
+ ```yaml
83
+ # Ensure expression evaluates to true for all rows
84
+ - dbt_utils.expression_is_true:
85
+ expression: "amount >= 0"
86
+
87
+ # Ensure no duplicate combinations
88
+ - dbt_utils.unique_combination_of_columns:
89
+ combination_of_columns:
90
+ - date_day
91
+ - customer_id
92
+
93
+ # Ensure referential integrity across multiple columns
94
+ - dbt_utils.relationships_where:
95
+ to: ref('dim_products')
96
+ field: product_id
97
+ from_condition: "product_id is not null"
98
+ ```
99
+
100
+ ## Official Documentation
101
+
102
+ - **dbt tests**: https://docs.getdbt.com/docs/build/data-tests
103
+ - **dbt-utils tests**: https://github.com/dbt-labs/dbt-utils#generic-tests