Governance, Documentation, and Data Quality
Governance questions test whether consumers can find, trust, and correctly use what you build: documentation coverage, ownership and exposure metadata, test design, contract enforcement, and how quality failures surface to the people on call.
Documentation and metadata
persist_docs writes model and column descriptions into the warehouse (Snowflake and BigQuery support comments), so BI users see definitions without opening dbt docs. meta carries owner, PII classification, and SLA fields that are queryable from the manifest. exposures declare dashboards, ML models, and reverse-ETL jobs so lineage reaches actual consumers and state:modified can select them. Doc blocks keep long definitions DRY across models.
Test design
Generic tests are unique, not_null, accepted_values, and relationships; singular tests are SQL queries returning failing rows. severity: warn records a warning without blocking; error is the default and, under dbt build, skips downstream models. Always pair failing-row tests with store_failures: true and a limit so you keep evidence instead of rerunning to investigate. where narrows tests to the rows that matter, and a config block at model level applies tests across columns.
Unit tests and contracts
Unit tests feed static input rows into a model and assert the output, catching logic bugs without warehouse data. Contracts enforce column names and data types and are the backbone of a stable mart interface; combine them with model versions when a change is breaking.
Freshness as an SLA
loaded_at_field plus warn_after and error_after on a source turns staleness into a scheduled check. Freshness is only meaningful where the pipeline actually runs it - a freshness threshold nobody executes is just documentation.
Worked example
A revenue mart feeds an executive dashboard. Declare an exposure with depends_on: ref('fct_revenue') and owner meta; add not_null and relationships tests on customer_id; add a singular test reconciling monthly totals to the ledger with severity: warn and store_failures: true; and add a unit test covering refunds. A schema change is then caught in CI by the contract, and staleness by the freshness check.
Traps
- Tests without
store_failures, so failures leave no evidence. accepted_valueslists that go stale and do not account for nulls.- Documentation generated once and never refreshed after deployment.
- Warn-severity tests that nobody monitors or alerts on.
- PII columns documented as sensitive but never masked in the warehouse.