Metadata-Version: 2.4
Name: dbt-vitals
Version: 0.1.3
Summary: Its a static analysis and health scoring for dbt projects — test coverage, duplicate logic, and documentation checks.
Author: Shreeti
License: MIT
Project-URL: Homepage, https://github.com/shivah12/dbt-vitals
Project-URL: Issues, https://github.com/shivah12/dbt-vitals/issues
Keywords: dbt,data-engineering,static-analysis,sql,linter,data-quality
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Database
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.1
Requires-Dist: rich>=13.0
Requires-Dist: networkx>=3.0
Requires-Dist: sqlglot>=23.0
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"
Dynamic: license-file

# dbt-vitals

Its a static analysis and health scoring for dbt projects — the "cargo clippy for dbt."

Unlike a SQL linter (indentation, keyword casing), dbt-vitals looks at your
project's *structure*: dead models, missing tests, duplicated business logic,
documentation coverage, and (given warehouse stats) incremental-model
candidates. It parses `manifest.json` / `catalog.json` — the artifacts dbt
already generates — so it needs no warehouse credentials of its own.

```
Overall Health
76/100
Warnings: 8   Critical: 0   Info: 4
```

## What it checks

| Module | What it flags | Needs `catalog.json`? |
|---|---|---|
| Lineage | Dead/unused models, circular dependencies | No |
| Testing | Models missing `unique`/`not_null` on their likely primary key | No |
| Duplicate Logic | Repeated `CASE WHEN` blocks across models (candidates for a macro) | No |
| Documentation | Model/column description coverage % | No |
| Incremental Candidates | Large `table`-materialized models that could be `incremental` | Yes |

## Local setup

Requires Python 3.9+.

```bash
git clone https://github.com/shivah12/dbt-vitals.git
cd dbt-vitals

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate

pip install -e ".[dev]"
```

Run the test suite against the bundled synthetic example project:

```bash
pytest
```

Try the CLI against the bundled example (no real dbt project needed):

```bash
dbt-vitals analyze . --manifest examples/sample_manifest.json --catalog examples/sample_catalog.json
```

Run it against a real dbt project:

```bash
cd /path/to/your/dbt/project
dbt compile               # or `dbt docs generate` to also get catalog.json
dbt-vitals analyze .
```

### CLI options

```bash
dbt-vitals analyze <target_dir>          # target_dir defaults to "."
  --manifest PATH        # override manifest.json location
  --catalog PATH         # override catalog.json location
  --json                 # machine-readable output
  --ci-comment           # markdown summary for a PR comment
  --fail-under N         # exit 1 if health score < N (CI gating)
```

## CI integration

`.github/workflows/dbt-vitals.yml` is included — it runs `dbt-vitals` on every
PR, posts the health score as a comment, and fails the build if the score
drops below a threshold. Adjust the `dbt compile` step for your adapter/profile.

## Known limitations (by design, for v0.1)

- **Duplicate detection** only looks at `CASE WHEN` expressions, not arbitrary
  repeated subqueries or joins.
- **Incremental candidates** use a fixed row-count threshold, not a real
  cost/runtime estimate — that would require warehouse-specific query plans.
- **Primary key inference** for the testing module is a naming heuristic
  (`id`, `<model>_id`, or any `*_id` column) since dbt's manifest has no
  first-class primary key concept.
- No plugin system yet (warehouse-specific checks) — deliberately deferred,
  see the original scoping notes for why.

## License

MIT — see [LICENSE](LICENSE).
