Milestone: #82
Depends on: #91, #93
Context
src/tycoon/commands/transform.py _capture_dbt_and_refresh_safe() is called after every dbt invocation. It currently calls observability.capture_dbt_safe() and capture_dbt_manifest_safe(). dbt writes its run results to dbt_project_dir / "target" / "run_results.json" after every invocation.
Goal
At the end of _capture_dbt_and_refresh_safe(), after the existing calls, read run_results.json (if present) and append a DbtRunCompleted event. The JSON structure is:
{
"elapsed_time": 4.23,
"results": [
{"status": "success"},
{"status": "error"}
]
}
Build the event:
results = data.get("results", [])
event = DbtRunCompleted(
source_id="dbt",
runtime_id="dbt",
command=command, # the dbt subcommand: "run", "build", "test"
target=resolved_target,
models_run=len(results),
models_passed=sum(1 for r in results if r.get("status") == "success"),
models_errored=sum(1 for r in results if r.get("status") == "error"),
duration_seconds=data.get("elapsed_time", 0.0),
)
Wrap in try/except Exception: pass.
Acceptance
After tycoon data transform run, running the DuckDB query from #95 shows a dbt_run_completed event.
Milestone: #82
Depends on: #91, #93
Context
src/tycoon/commands/transform.py_capture_dbt_and_refresh_safe()is called after every dbt invocation. It currently callsobservability.capture_dbt_safe()andcapture_dbt_manifest_safe(). dbt writes its run results todbt_project_dir / "target" / "run_results.json"after every invocation.Goal
At the end of
_capture_dbt_and_refresh_safe(), after the existing calls, readrun_results.json(if present) and append aDbtRunCompletedevent. The JSON structure is:{ "elapsed_time": 4.23, "results": [ {"status": "success"}, {"status": "error"} ] }Build the event:
Wrap in
try/except Exception: pass.Acceptance
After
tycoon data transform run, running the DuckDB query from #95 shows adbt_run_completedevent.