-
Notifications
You must be signed in to change notification settings - Fork 135
feat: dbt_project_health tool — reuse altimate-core dbt health checks #1030
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
base: main
Are you sure you want to change the base?
Changes from all commits
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,25 @@ | ||
| --- | ||
| description: infer a dbt health-check config from the project's own conventions and write .altimate/dbt-health.yml | ||
| agent: build | ||
| subtask: true | ||
| --- | ||
|
|
||
| Generate a dbt health-check configuration by inferring it from a dbt project's **existing conventions** (deterministic — no guessing). | ||
|
|
||
| ## Target project | ||
|
|
||
| Use `$ARGUMENTS` as the dbt project directory if provided. Otherwise, locate the dbt project in the current worktree by finding the directory that contains a `dbt_project.yml` (run `project_scan` if you need to discover it). If there are **multiple** dbt projects, do this for **each** one — every project gets its own `.altimate/dbt-health.yml`. | ||
|
|
||
| ## Steps | ||
|
|
||
| 1. For each target project directory, call the **`dbt_health_config`** tool: | ||
| `dbt_health_config({ project_dir: "<dir>" })` | ||
| This deterministically infers the config from the project (modal tags / meta keys / tests, configured schemas & databases, naming contracts, distribution-ratcheted thresholds) and writes it to `<dir>/.altimate/dbt-health.yml`. | ||
|
|
||
| 2. Then run **`dbt_project_health`** on the same directory: | ||
| `dbt_project_health({ project_dir: "<dir>" })` | ||
| It auto-discovers the freshly written `.altimate/dbt-health.yml`, so the report now reflects the inferred rules. | ||
|
|
||
| 3. Summarize for the user: the path(s) written, which config-driven checks were activated (tags, meta keys, tests, naming contracts, parent schema/database whitelists, thresholds), and the resulting finding counts by severity. Tell them the file is committed with the project and can be hand-edited — re-running this command regenerates it deterministically. | ||
|
|
||
| Do not fabricate values; everything comes from the two tools above. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,55 @@ | ||||||||||||||||||||||||||||||||||||||||||||
| import { mkdir } from "node:fs/promises" | ||||||||||||||||||||||||||||||||||||||||||||
| import { dirname } from "node:path" | ||||||||||||||||||||||||||||||||||||||||||||
| import z from "zod" | ||||||||||||||||||||||||||||||||||||||||||||
| import { Tool } from "../../tool/tool" | ||||||||||||||||||||||||||||||||||||||||||||
| import { Dispatcher } from "../native" | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| /** Relative path (from the dbt project root) where the inferred config is written. */ | ||||||||||||||||||||||||||||||||||||||||||||
| export const DBT_HEALTH_CONFIG_RELPATH = ".altimate/dbt-health.yml" | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| export const DbtHealthConfigTool = Tool.define("dbt_health_config", { | ||||||||||||||||||||||||||||||||||||||||||||
| description: | ||||||||||||||||||||||||||||||||||||||||||||
| "Deterministically infer a dbt health-check config from a dbt project's EXISTING conventions (modal tags/meta keys/tests, configured schemas & databases, naming contracts, distribution-ratcheted thresholds) and write it to <project_dir>/.altimate/dbt-health.yml. This activates the config-driven governance checks (which are no-ops until configured). Per-project: each dbt project gets its own config file. Reproducible — no LLM, same project always yields the same file.", | ||||||||||||||||||||||||||||||||||||||||||||
| parameters: z.object({ | ||||||||||||||||||||||||||||||||||||||||||||
| project_dir: z.string().describe("Path to the dbt project root (the directory containing dbt_project.yml)"), | ||||||||||||||||||||||||||||||||||||||||||||
| write: z | ||||||||||||||||||||||||||||||||||||||||||||
| .boolean() | ||||||||||||||||||||||||||||||||||||||||||||
| .optional() | ||||||||||||||||||||||||||||||||||||||||||||
| .describe("Write the config to <project_dir>/.altimate/dbt-health.yml (default true). If false, only return the YAML."), | ||||||||||||||||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||||||||||||||||
| async execute(args, _ctx) { | ||||||||||||||||||||||||||||||||||||||||||||
| const result = await Dispatcher.call("altimate_core.dbt_health_infer_config", { | ||||||||||||||||||||||||||||||||||||||||||||
| project_dir: args.project_dir, | ||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| if (!result.success) { | ||||||||||||||||||||||||||||||||||||||||||||
| const error = result.error ?? "unknown error" | ||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||
| title: "dbt health config: ERROR", | ||||||||||||||||||||||||||||||||||||||||||||
| metadata: { error }, | ||||||||||||||||||||||||||||||||||||||||||||
| output: `Failed to infer dbt health config: ${error}`, | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| const yaml = String((result.data as { config?: unknown }).config ?? "") | ||||||||||||||||||||||||||||||||||||||||||||
| const outPath = `${args.project_dir.replace(/\/+$/, "")}/${DBT_HEALTH_CONFIG_RELPATH}` | ||||||||||||||||||||||||||||||||||||||||||||
|
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. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- file outline ---'
ast-grep outline packages/opencode/src/altimate/tools/dbt-health-config.ts --view expanded || true
echo '--- relevant lines ---'
sed -n '1,120p' packages/opencode/src/altimate/tools/dbt-health-config.ts
echo '--- path semantics probe ---'
node - <<'JS'
const path = require('node:path');
const rel = 'dbt_health_config.yml';
const inputs = [
'/',
'/tmp/',
'C:/',
'C:/work/',
'C:\\',
'C:\\work\\',
'relative/',
];
for (const p of inputs) {
const stripped = `${p.replace(/\/+$/, '')}/${rel}`;
const joined = path.join(p, rel);
const posixJoined = path.posix.join(p, rel);
const winJoined = path.win32.join(p, rel);
console.log(JSON.stringify({ p, stripped, joined, posixJoined, winJoined }));
}
JSRepository: AltimateAI/altimate-code Length of output: 4011 🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '1,120p' packages/opencode/src/altimate/tools/dbt-health-config.ts
node - <<'JS'
const path = require('node:path');
const rel = 'dbt_health_config.yml';
for (const p of ['/', '/tmp/', 'C:/', 'C:/work/', 'C:\\', 'C:\\work\\', 'relative/']) {
const stripped = `${p.replace(/\/+$/, '')}/${rel}`;
const joined = path.join(p, rel);
console.log(JSON.stringify({ p, stripped, joined }));
}
JSRepository: AltimateAI/altimate-code Length of output: 3259 🏁 Script executed: #!/bin/bash
set -euo pipefail
node - <<'JS'
const path = require('node:path');
const samples = [
'/.altimate/dbt-health.yml',
'C:/.altimate/dbt-health.yml',
'C:\\/.altimate/dbt-health.yml',
'C:/work/.altimate/dbt-health.yml',
'C:\\work\\/.altimate/dbt-health.yml',
'//server/share/.altimate/dbt-health.yml',
];
for (const s of samples) {
console.log(JSON.stringify({
s,
posix_dirname: path.posix.dirname(s),
win_dirname: path.win32.dirname(s),
posix_isAbs: path.posix.isAbsolute(s),
win_isAbs: path.win32.isAbsolute(s),
normalized_win: path.win32.normalize(s),
}));
}
JSRepository: AltimateAI/altimate-code Length of output: 1352 Build the output path with 🤖 Prompt for AI AgentsThere 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: The output path is built with manual slash-trimming and template concatenation, but Prompt for AI agents
Contributor
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. [🔴 HIGH] Unsafe path construction and potential directory traversal. The output path is constructed using simple string concatenation. If the AI agent provides an empty string, Consider importing Suggested change:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| let written = false | ||||||||||||||||||||||||||||||||||||||||||||
| if (args.write !== false) { | ||||||||||||||||||||||||||||||||||||||||||||
| await mkdir(dirname(outPath), { recursive: true }) | ||||||||||||||||||||||||||||||||||||||||||||
|
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: The Prompt for AI agents |
||||||||||||||||||||||||||||||||||||||||||||
| await Bun.write(outPath, yaml) | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+39
to
+40
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. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n== File outline ==\n'
ast-grep outline packages/opencode/src/altimate/tools/dbt-health-config.ts --view expanded || true
printf '\n== File contents (relevant slice) ==\n'
wc -l packages/opencode/src/altimate/tools/dbt-health-config.ts
sed -n '1,220p' packages/opencode/src/altimate/tools/dbt-health-config.ts | cat -n
printf '\n== Search for related path / symlink handling ==\n'
rg -n "symlink|realpath|canonical|containment|mkdir\\(|Bun\\.write\\(|dbt-health.yml|\\.altimate|project_dir|projectDir|outPath" packages/opencode/src -SRepository: AltimateAI/altimate-code Length of output: 41320 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n== util/filesystem.ts excerpt ==\n'
sed -n '200,280p' packages/opencode/src/util/filesystem.ts | cat -n
printf '\n== write helpers / containment usages ==\n'
rg -n "containsReal|containsPath|mkdir\\(|writeFile\\(|Bun\\.write\\(" packages/opencode/src/util packages/opencode/src/altimate packages/opencode/src/cli -SRepository: AltimateAI/altimate-code Length of output: 6872 Prevent symlink escapes in the write path. 🤖 Prompt for AI AgentsSource: Coding guidelines |
||||||||||||||||||||||||||||||||||||||||||||
| written = true | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+37
to
+42
Contributor
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. [🔴 HIGH] Unhandled exceptions in file system operations and inconsistent FS API usage.
Suggested change:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| const checkCount = (yaml.match(/^ {2}\S/gm) ?? []).length | ||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||
| title: written | ||||||||||||||||||||||||||||||||||||||||||||
| ? `dbt health config written (${checkCount} checks tuned) → ${outPath}` | ||||||||||||||||||||||||||||||||||||||||||||
| : `dbt health config inferred (${checkCount} checks tuned)`, | ||||||||||||||||||||||||||||||||||||||||||||
| metadata: { path: outPath, written, project_dir: args.project_dir }, | ||||||||||||||||||||||||||||||||||||||||||||
| output: written | ||||||||||||||||||||||||||||||||||||||||||||
| ? `Wrote inferred config to ${outPath}:\n\n${yaml}` | ||||||||||||||||||||||||||||||||||||||||||||
| : `Inferred config (not written):\n\n${yaml}`, | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,100 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import z from "zod" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Tool } from "../../tool/tool" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Dispatcher } from "../native" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** A single finding returned by `altimate_core.dbt_project_health` (Rust `HealthFinding`). */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface HealthFinding { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| code: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alias: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resource_type: "model" | "source" | "exposure" | "macro" | "project" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unique_id?: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| file?: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| severity: "error" | "warning" | "info" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| message: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recommendation?: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| reason_to_flag?: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| metadata?: unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const SEVERITY_ORDER: Record<string, number> = { error: 0, warning: 1, info: 2 } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const DbtProjectHealthTool = Tool.define("dbt_project_health", { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "Run dbt project health checks (governance, modelling, documentation, tests, sources) directly against a dbt project's files — no compiled manifest.json required. Reads .sql models (via the dbt Jinja AST parser), schema.yml properties and dbt_project.yml. Optionally uses a catalog.json for column-level checks; otherwise columns are inferred from the SQL parser.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parameters: z.object({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| project_dir: z.string().describe("Path to the dbt project root (the directory containing dbt_project.yml)"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config_path: z | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .string() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .optional() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .describe("Optional path to a JSON health-check config (disabled checks, severity overrides, options)"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| catalog_path: z | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .string() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .optional() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .describe("Optional path to a dbt catalog.json to power column-aware checks"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async execute(args, _ctx) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Explicit config_path wins; otherwise auto-discover a per-project inferred config | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // at <project_dir>/.altimate/dbt-health.{yml,yaml,json} (YAML or JSON both parse). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let config_json: string | undefined | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const candidates = args.config_path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? [args.config_path] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `${args.project_dir.replace(/\/+$/, "")}/.altimate/dbt-health.yml`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `${args.project_dir.replace(/\/+$/, "")}/.altimate/dbt-health.yaml`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `${args.project_dir.replace(/\/+$/, "")}/.altimate/dbt-health.json`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const candidate of candidates) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const file = Bun.file(candidate) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (await file.exists()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config_json = await file.text() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
+52
Contributor
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. [🟠 MEDIUM] If Suggested change:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const result = await Dispatcher.call("altimate_core.dbt_project_health", { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| project_dir: args.project_dir, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config_json, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| catalog_path: args.catalog_path, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!result.success) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const error = result.error ?? "unknown error" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title: "dbt health: ERROR", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| metadata: { error }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output: `Failed to run dbt health checks: ${error}`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const findings = ((result.data.findings as HealthFinding[] | undefined) ?? []).slice() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| findings.sort( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (a, b) => (SEVERITY_ORDER[a.severity] ?? 3) - (SEVERITY_ORDER[b.severity] ?? 3) || a.code.localeCompare(b.code), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const counts = { error: 0, warning: 0, info: 0 } as Record<string, number> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const f of findings) counts[f.severity] = (counts[f.severity] ?? 0) + 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+69
to
+75
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. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '1,220p' packages/opencode/src/altimate/tools/dbt-project-health.ts
printf '\n---- search HealthFinding ----\n'
rg -n "HealthFinding|findings" packages/opencode/src/altimate -g '!**/dist/**' -g '!**/build/**'Repository: AltimateAI/altimate-code Length of output: 27057 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '--- file ---\n'
nl -ba packages/opencode/src/altimate/tools/dbt-project-health.ts | sed -n '1,220p'
printf '\n--- search definitions ---\n'
rg -n "type HealthFinding|interface HealthFinding|Schema.*HealthFinding|findings:" packages/opencode/src/altimate -g '!**/dist/**' -g '!**/build/**'Repository: AltimateAI/altimate-code Length of output: 253 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- altimate-core dbt_project_health references ---'
rg -n "dbt_project_health|HealthFinding|JSON.parse\\(json\\)" packages/opencode/src/altimate/native/altimate-core.ts packages/opencode/src/altimate/native -g '!**/dist/**' -g '!**/build/**'
printf '\n%s\n' '--- dispatcher definition ---'
rg -n "class Dispatcher|export const Dispatcher|call\\(" packages/opencode/src/altimate/native packages/opencode/src/altimate -g '!**/dist/**' -g '!**/build/**'Repository: AltimateAI/altimate-code Length of output: 14037 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- native altimate_core.dbt_project_health implementation ---'
nl -ba packages/opencode/src/altimate/native/altimate-core.ts | sed -n '260,285p'
printf '\n%s\n' '--- dispatcher return typing ---'
nl -ba packages/opencode/src/altimate/native/types.ts | sed -n '1238,1260p'
printf '\n%s\n' '--- dispatcher implementation ---'
rg -n "class Dispatcher|export class Dispatcher|static async call|async call" packages/opencode/src/altimate/native packages/opencode/src/altimate -g '!**/dist/**' -g '!**/build/**'Repository: AltimateAI/altimate-code Length of output: 265 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- native altimate_core.dbt_project_health implementation ---'
nl -ba packages/opencode/src/altimate/native/altimate-core.ts | sed -n '260,285p'
printf '%s\n' '--- dispatcher return typing ---'
nl -ba packages/opencode/src/altimate/native/types.ts | sed -n '1238,1260p'
printf '%s\n' '--- dispatcher implementation ---'
rg -n "class Dispatcher|export class Dispatcher|static async call|async call" packages/opencode/src/altimate/native packages/opencode/src/altimate -g '!**/dist/**' -g '!**/build/**'Repository: AltimateAI/altimate-code Length of output: 265 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- native altimate_core.dbt_project_health implementation ---'
sed -n '268,278p' packages/opencode/src/altimate/native/altimate-core.ts | cat -n
printf '\n%s\n' '--- native types entry ---'
sed -n '1242,1254p' packages/opencode/src/altimate/native/types.ts | cat -n
printf '\n%s\n' '--- dispatcher implementation files ---'
fd -a "dispatcher*.ts" packages/opencode/src/altimate packages/opencode/src -E dist -E buildRepository: AltimateAI/altimate-code Length of output: 1545 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- dispatcher.ts ---'
sed -n '1,260p' packages/opencode/src/altimate/native/dispatcher.ts | cat -n
printf '\n%s\n' '--- AltimateCoreResult definition ---'
rg -n "type AltimateCoreResult|interface AltimateCoreResult|export type AltimateCoreResult" packages/opencode/src/altimate/native/types.ts packages/opencode/src/altimate/native -g '!**/dist/**' -g '!**/build/**'Repository: AltimateAI/altimate-code Length of output: 3918 Validate the native findings payload at runtime. 🤖 Prompt for AI AgentsSource: Coding guidelines |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title: `dbt health: ${findings.length} finding(s) — ${counts.error} error, ${counts.warning} warning, ${counts.info} info`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| metadata: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| finding_count: findings.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| error_count: counts.error, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| warning_count: counts.warning, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| info_count: counts.info, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output: formatFindings(findings), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function formatFindings(findings: HealthFinding[]): string { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (findings.length === 0) return "✓ No dbt health issues found." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const lines: string[] = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const f of findings) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const where = f.file ? ` (${f.file})` : f.unique_id ? ` (${f.unique_id})` : "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lines.push(`[${f.severity.toUpperCase()}] ${f.code} ${f.alias}${where}`) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+93
to
+95
Contributor
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. [🔵 LOW] According to the review checklist, nested ternary expressions are not allowed. Please refactor this to use an Suggested change:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lines.push(` ${f.message}`) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (f.recommendation) lines.push(` → ${f.recommendation}`) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return lines.join("\n") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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.
[🔴 HIGH] Potential runtime
TypeError. Accessing.configdirectly on the typecastedresult.datawill throw aTypeError: Cannot read properties of undefinedifresult.dataisnullorundefined(even whenresult.successis true). Please use optional chaining (?.config) to ensure safe access.Suggested change: