/** `snapshot-db` — publish one transaction-consistent conductor.db snapshot. */ import type { CommandContext } from "./context.ts"; import { dbBackupDirFor, loadConfig } from "../config.ts"; import type { Store } from "../types.ts"; import { DB_SNAPSHOT_RETENTION, dbPath, openStore, pruneDbSnapshots, snapshotDb, } from "../store.ts"; export async function snapshotDbCommand(ctx: CommandContext): Promise { if (ctx.projectFlag !== undefined) { process.stderr.write("omp-conductor: snapshot-db does not take a project — the store is host-wide\n"); process.exit(2); } if (ctx.argv.length > 1) { process.stderr.write(`omp-conductor: snapshot-db: unexpected argument "${ctx.argv[1]}"\n`); process.exit(2); } const cfg = loadConfig(); const directory = dbBackupDirFor(cfg); const published = snapshotDb(dbPath(), directory); // Publication is already durable. Print its path before secondary accounting // so a ledger/prune failure cannot turn success into an invisible file. process.stdout.write(`snapshot published: ${published}\n`); let store: Store | undefined; try { const opened = openStore(dbPath()); store = opened; const now = Date.now(); const eventIds = cfg.projects.map((project) => opened.recordMaterialEvent({ project: project.name, category: "db-snapshot", summary: "published manual conductor.db snapshot", evidence: published, occurredAt: now, recordedAt: now, }).id, ); process.stdout.write(`ledger events recorded: ${eventIds.join(", ")}\n`); } catch (err) { process.stderr.write( `warning: snapshot published, but its ledger event could not be recorded: ${ err instanceof Error ? err.message : String(err) }\n`, ); } finally { store?.close(); } try { const pruned = pruneDbSnapshots(directory, DB_SNAPSHOT_RETENTION); process.stdout.write(`retention ${DB_SNAPSHOT_RETENTION} (${pruned} pruned)\n`); } catch (err) { process.stderr.write( `warning: snapshot published, but retention pruning failed: ${ err instanceof Error ? err.message : String(err) }\n`, ); } }