import { Database } from 'bun:sqlite'; import { ensureFinancialIngestionSchemaHealthy, inspectFinancialIngestionSchema, resolveFinancialSchemaRepairMode } from '../lib/server/db/financial-ingestion-schema'; import { resolveSqlitePath } from './dev-env'; function parseArgs(argv: string[]) { const flags = new Set(argv); return { dryRun: flags.has('--dry-run'), verbose: flags.has('--verbose'), failOnDrift: flags.has('--fail-on-drift') }; } function resolveDatabasePath() { const raw = process.env.DATABASE_URL?.trim() || 'file:data/fiscal.sqlite'; const databasePath = resolveSqlitePath(raw); if (!databasePath || databasePath.includes('://')) { throw new Error(`DATABASE_URL must resolve to a SQLite file path. Received: ${raw}`); } return databasePath; } const options = parseArgs(process.argv.slice(2)); const databasePath = resolveDatabasePath(); const client = new Database(databasePath, { create: true }); try { client.exec('PRAGMA foreign_keys = ON;'); const mode = options.dryRun ? 'check-only' : resolveFinancialSchemaRepairMode(process.env.FINANCIAL_SCHEMA_REPAIR_MODE); const before = inspectFinancialIngestionSchema(client); const result = ensureFinancialIngestionSchemaHealthy(client, { mode }); console.info(`[repair-financial-ingestion-schema] db=${databasePath}`); console.info(`[repair-financial-ingestion-schema] mode=${mode}`); console.info(`[repair-financial-ingestion-schema] status=${result.mode}`); console.info(`[repair-financial-ingestion-schema] missing_indexes_before=${before.missingIndexes.join(',') || 'none'}`); console.info(`[repair-financial-ingestion-schema] duplicate_groups_before=${before.duplicateGroups}`); if (result.repair) { console.info(`[repair-financial-ingestion-schema] indexes_created=${result.repair.indexesCreated.join(',') || 'none'}`); console.info(`[repair-financial-ingestion-schema] indexes_recreated=${result.repair.indexesRecreated.join(',') || 'none'}`); console.info(`[repair-financial-ingestion-schema] duplicate_rows_deleted=${result.repair.duplicateRowsDeleted}`); console.info(`[repair-financial-ingestion-schema] bundle_cache_cleared=${result.repair.bundleCacheCleared ? 'yes' : 'no'}`); } if (options.verbose) { console.info(JSON.stringify({ before, after: result }, null, 2)); } if (options.failOnDrift && !result.ok) { process.exit(1); } } finally { client.close(); }