// Read-only audit run that writes the full summary to a log file. import { appendFileSync, existsSync, readFileSync } from "node:fs"; import { resolve } from "node:path"; import { beforeAll, describe, expect, it } from "vitest"; const runLive = process.env.RUN_CATALOG_AUDIT_LIVE === "1"; const LOG = "/tmp/catalog-audit-summary.log"; const log = (msg: string) => { appendFileSync(LOG, `${msg}\n`); }; describe.skipIf(!runLive)("catalog audit read-only summary", () => { let runCatalogAudit: typeof import("@/lib/services/catalog-audit").runCatalogAudit; beforeAll(async () => { const envFile = resolve(process.cwd(), ".env"); if (existsSync(envFile)) { for (const line of readFileSync(envFile, "utf8").split(/\r?\n/)) { const m = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/); if (!m) continue; let value = m[2].trim(); if ( (value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'")) ) { value = value.slice(1, -1); } process.env[m[1]] = value; } } const auditMod = await import("@/lib/services/catalog-audit"); runCatalogAudit = auditMod.runCatalogAudit; }); it("reports the full audit summary", async () => { expect(process.env.DATABASE_URL).toMatch(/@/); const events: Array> = []; await runCatalogAudit( (evt) => events.push(evt as unknown as Record), {}, ); const last = events[events.length - 1]; expect(last?.type).toBe("batch_complete"); const summary = last.summary as Record; const issues = last.issues as Array<{ type: string; severity: string; message: string; classname?: string; }>; const unrepairable = last.unrepairable as Array<{ classname: string; itemId: number; missing: Array; }>; log("=== SUMMARY ==="); log(JSON.stringify(summary, null, 2)); log("=== ISSUES ==="); log(JSON.stringify(issues, null, 2)); log("=== UNREPAIRABLE ==="); log(JSON.stringify(unrepairable, null, 2)); }, 300000); });