import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import { join } from "node:path"; import test from "node:test"; const source = async (relativePath: string) => { return await readFile( join(process.cwd(), ...relativePath.split("/")), "utf8", ); }; function extractExportSource(sourceText: string, name: string) { const marker = `export const ${name} = `; const declarationIndex = sourceText.indexOf(marker); assert.notEqual(declarationIndex, -1, `Expected declaration for ${name}.`); const openBraceIndex = sourceText.indexOf("{", declarationIndex); let depth = 0; let end = -1; for (let index = openBraceIndex; index < sourceText.length; index += 1) { const char = sourceText[index]; if (char === "{") { depth += 1; } else if (char === "}") { depth -= 1; if (depth === 0) { end = index; break; } } } assert.notEqual(end, -1, `Expected balanced braces for ${name}.`); return sourceText.slice(openBraceIndex, end + 1); } test("audits dashboard query combines final audits with generation runs", async () => { const auditsSource = await source("convex/audits.ts"); const querySource = extractExportSource(auditsSource, "listDashboardRows"); assert.match( auditsSource, /export const listDashboardRows = query/, "Dashboard rows should be exposed as a public Convex query.", ); assert.match( querySource, /requireOperator\(ctx\)/, "Dashboard rows should require an authenticated operator.", ); assert.match( auditsSource, /ctx\.auth\.getUserIdentity\(\)/, "Operator checks should derive identity from Convex auth.", ); assert.match( querySource, /kind:\s*"audit"/, "Final audit documents should be returned as audit rows.", ); assert.match( querySource, /kind:\s*"generation"/, "Audit generation runs should be returned as generation rows.", ); assert.match( querySource, /\.query\("audits"\)/, "Dashboard rows should read finalized audits.", ); assert.match( querySource, /\.query\("agentRuns"\)[\s\S]*\.withIndex\("by_type"/, "Dashboard rows should read audit_generation runs through the type index.", ); assert.match( querySource, /\.query\("auditGenerations"\)[\s\S]*\.withIndex\("by_runId"/, "Dashboard rows should load generation stages by run id.", ); }); test("audits dashboard query suppresses generation rows once a final audit exists", async () => { const auditsSource = await source("convex/audits.ts"); const querySource = extractExportSource(auditsSource, "listDashboardRows"); assert.match( querySource, /finalAuditRunIds/, "Query should track run ids that already have finalized audits.", ); assert.match( querySource, /finalAuditLeadIds/, "Query should track lead ids that already have finalized audits.", ); assert.match( querySource, /\.query\("audits"\)[\s\S]*\.withIndex\("by_leadId"/, "Query should suppress generation rows even when the finalized audit is outside the fetched dashboard page.", ); assert.match( querySource, /ctx\.db\.get\(run\.auditId\)/, "Query should suppress generation rows that directly reference an existing audit.", ); assert.match( querySource, /continue/, "Query should skip duplicate generation rows instead of returning them.", ); assert.match( querySource, /latestStage/, "Generation rows should surface the latest generation stage.", ); assert.match( querySource, /errorSummary/, "Generation rows should surface run or stage errors.", ); }); test("audits dashboard query hides child generation rows behind root audit runs", async () => { const auditsSource = await source("convex/audits.ts"); const querySource = extractExportSource(auditsSource, "listDashboardRows"); assert.match( querySource, /rootAuditRunLeadIds/, "Query should track lead ids that already have root audit runs.", ); assert.match( querySource, /run\.type\s*===\s*"audit_generation"[\s\S]*rootAuditRunLeadIds\.has\(run\.leadId\)/, "Child audit_generation rows should be skipped when a root audit run for the same lead is already visible.", ); assert.match( querySource, /continue/, "Child generation rows should be skipped instead of rendered as a duplicate card.", ); });