11# REVIEW.md — datapilot-cli
22
33Python CLI (` altimate-datapilot-cli ` on PyPI) that parses dbt ` manifest.json ` /` catalog.json `
4- artifacts across dbt manifest schema versions (vendored ` dbt-artifacts-parser ` , v1–v12) and runs
4+ artifacts (vendored ` dbt-artifacts-parser ` schema types span manifest v1–v12) and runs
55data-quality "insight" checks over dbt projects, usable standalone or as a pre-commit hook.
6+ Insight-check processing itself is narrower — ` DBTFactory.get_manifest_wrapper ` only wraps
7+ v10/v11/v12, raising ` AltimateNotSupportedError ` for older versions.
68
79## Goal: catch what CI cannot
810
@@ -17,7 +19,9 @@ This repo's `pre-commit` + `tox` pipeline (ruff, black) already enforces, so nev
1719- Unused imports/variables, bare ` except ` , raise-from style (` RUF ` , ` RSE ` ), bugbear patterns (` B ` ),
1820 comprehension style (` C4 ` ), pathlib usage (` PTH ` ), quote style (` Q ` ), pytest style (` PT ` ).
1921- Naive ` datetime ` construction — ruff's ` DTZ ` rule already catches this.
20- - Basic ` flake8-bandit ` (` S ` ) security smells (e.g. ` assert ` in non-test code, ` eval ` /` exec ` ).
22+ - ` eval ` /` exec ` usage (` flake8-bandit ` ` S102 ` /` S307 ` , still enforced). Exception: ` S101 ` (assert)
23+ is ignored in ` pyproject.toml ` , so CI does NOT catch ` assert ` in non-test code — flag it (it also
24+ vanishes under ` python -O ` ).
2125- Line length (140 cols, ruff-enforced).
2226- Whether tests exist/pass — ` tox ` runs the suite; that's CI's job, not yours.
2327Pre-existing issues in code the diff doesn't touch are out of scope — only review changed lines
@@ -53,9 +57,10 @@ call site actually surfaces failures to the user before claiming error handling
53572 . ** Fields marked required on node wrapper models** (#98 , #95 , #96 — ` identifier ` ,
5458 ` resource_type ` made optional after crashing on ` Disabled* ` /unit-test nodes). A field required
5559 on the "normal" node case often isn't populated on disabled nodes, unit-test nodes, or older
56- manifest versions. Flag any new required (non-` Optional ` ) field added to an ` Altimate* ` node
57- model; verify it's actually present across disabled/unit-test/seed/source variants, not just
58- the common model case.
60+ manifest versions. Note: with ` pydantic>=2.0 ` , ` Optional[str] ` without a default (` = None ` ) is
61+ still required — don't treat ` Optional ` -typed as automatically safe. Flag any new required field
62+ added to an ` Altimate* ` node model; verify it's actually present across
63+ disabled/unit-test/seed/source variants, not just the common model case.
5964
60653 . ** Version-specific field access without a version guard** (e.g. ` deferred ` not present on v12
6166 ` RPCNode ` ; behavior tied to a specific dbt/artifact-parser version). Flag direct attribute
@@ -71,39 +76,36 @@ call site actually surfaces failures to the user before claiming error handling
7176 ` dbt docs generate ` output can be stale relative to the manifest. Flag catalog/manifest
7277 ` .nodes[x] ` / ` .columns[y] ` access without a ` None ` /` KeyError ` guard in insight-check code.
7378
74- 6 . ** Mutable default arguments** (explicitly flagged in review — "list is mutable, weird things can
75- happen" — not reliably caught by this repo's ruff config). Flag ` def f(x=[]) ` , ` def f(x={}) ` , or
76- a list/dict class attribute mutated in place across calls instead of copied per-instance.
79+ 6 . ** Mutable default arguments** (flagged in review — not reliably caught by this repo's ruff
80+ config). Flag ` def f(x=[]) ` , ` def f(x={}) ` , or a list/dict class attribute mutated in place
81+ across calls instead of copied per-instance.
7782
78- 7 . ** Hardcoded materialization/dialect assumptions in insight checks** (" dialects may have
79- multiple materializations and it might flag something we don't want to flag", "use the VIEW
80- constant, we have it somewhere"). Flag magic materialization strings (` "view" ` , ` "table" ` ,
81- ` "incremental" ` ) instead of the shared constant, and any check that assumes one dialect's
82- materialization vocabulary applies to all configured warehouses.
83+ 7 . ** Hardcoded materialization/dialect assumptions in insight checks** (some dialects support
84+ multiple materializations for a given config; use the shared ` VIEW ` -style constant). Flag magic
85+ materialization strings (` "view" ` , ` "table" ` , ` "incremental" ` ) instead of the shared constant ,
86+ and any check that assumes one dialect's materialization vocabulary applies to all configured
87+ warehouses.
8388
84898 . ** Duplicated logic across check/insight classes** ("put this in the base ` DBTCheck ` class so
8590 it's not repeated", "make it a reusable util"). Flag near-identical blocks copy-pasted across
8691 files under the insights/checks package instead of factored onto a shared base class or util.
8792
88- 9 . ** API-client failures not surfaced to the CLI user** ("should handle exceptions and not-200s
89- nicely", "get the response code and log it", "return the status so we inform the user what
90- happened"). The API client intentionally doesn't raise on non-2xx (see Known-intentional) — the
91- bug class is the CLI layer silently swallowing that failure instead of reporting it to the
92- user. Flag call sites that ignore or only debug-log a non-2xx/error API response.
93+ 9 . ** API-client failures not surfaced to the CLI user** . The API client intentionally doesn't raise
94+ on non-2xx (see Known-intentional) — the bug class is the CLI layer silently swallowing that
95+ failure instead of reporting it to the user. Flag call sites that ignore or only debug-log a
96+ non-2xx/error API response.
9397
94- 10 . ** Hardcoded environment-specific defaults** ("needs to be injectable from the CLI/environment,
95- not hardcoded"). Flag new hardcoded endpoint/host/instance defaults added to config or client
96- code that aren't also exposed as a CLI flag or env var override.
98+ 10 . ** Hardcoded environment-specific defaults** . Flag new hardcoded endpoint/host/instance defaults
99+ added to config or client code that aren't also exposed as a CLI flag or env var override.
97100
98- 11 . ** Enum/resource-type completeness across manifest versions** ("how is it mapping between the
99- enums", "not sure all types have labels"). ` AltimateResourceType ` /` AltimateAccess ` -style enums
100- must track new dbt node/resource types introduced by an artifact-parser version bump. Flag a
101- vendored-parser bump or new node type handled without a corresponding Altimate enum member.
101+ 11 . ** Enum/resource-type completeness across manifest versions** .
102+ ` AltimateResourceType ` /` AltimateAccess ` -style enums must track new dbt node/resource types
103+ introduced by an artifact-parser version bump. Flag a vendored-parser bump or new node type
104+ handled without a corresponding Altimate enum member.
102105
10310612 . ** Release/version-bump workflow trigger conditions** (` .bumpversion.cfg ` , ` bump-version.yml ` ,
104- ` tag-release.yml ` — "won't this always release a tag? should be manual"). Flag changes to
105- release-workflow ` on: ` triggers; verify a routine merge to main can't unintentionally fire a
106- tag/release.
107+ ` tag-release.yml ` ). Flag changes to release-workflow ` on: ` triggers; verify a routine merge to
108+ main can't unintentionally fire a tag/release.
107109
108110## Repo invariants & landmines
109111
@@ -113,11 +115,14 @@ call site actually surfaces failures to the user before claiming error handling
113115 vendored dbt-artifacts-parser", "use forked dbt-artifacts-parser") — it exists because upstream
114116 didn't support something needed here; don't "clean up" divergence from upstream as if it were
115117 drift.
116- - Two distinct run modes with different data completeness: a full CLI run (`datapilot dbt
117- project-health`) vs. the pre-commit hook, which partially generates manifest/catalog from only
118- changed files. Manifest-loading changes need to work under both.
119- - Minimum supported Python is 3.7 per README — avoid relying on syntax/stdlib features unavailable
120- there unless the actual tox/CI matrix has been checked.
118+ - Two run modes, both load the * full* manifest/catalog from disk (` load_manifest_file ` /
119+ ` load_catalog_file ` , default ` target/manifest.json ` /` target/catalog.json ` ): a full CLI run
120+ (` datapilot dbt project-health ` ) vs. the pre-commit hook. The hook's ` process_changed_files ` only
121+ narrows which models get insight-checked — it does not generate a partial manifest/catalog.
122+ Manifest-loading changes need to work under both.
123+ - Minimum supported Python is 3.8 (` setup.py ` ` python_requires=">=3.8" ` , ` pyproject.toml ` /` tox.ini `
124+ ` target-version = "py38" ` ) — README's "3.7 or higher" is stale; avoid syntax/stdlib features
125+ unavailable in 3.8 unless the tox/CI matrix has been checked.
121126- ` --catalog-path ` is optional; code paths must degrade gracefully (skip catalog-dependent
122127 insights) rather than assume catalog data is present.
123128
0 commit comments