import assert from 'node:assert/strict' import { spawnSync } from 'node:child_process' import { mkdtempSync, rmSync, existsSync, readdirSync } from 'node:fs' import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import Database from 'better-sqlite3' import { up, migrationId } from '../src/database/migrations/001-initial-schema' const backendRoot = join(dirname(fileURLToPath(import.meta.url)), '..') const root = mkdtempSync(join(tmpdir(), 'cgl-backup-')) const srcDb = join(root, 'source.db') const backupDir = join(root, 'backups') const restoreTarget = join(root, 'restored.db') try { const db = new Database(srcDb) db.exec(` CREATE TABLE IF NOT EXISTS schema_migrations ( id TEXT PRIMARY KEY, applied_at TEXT NOT NULL ); `) db.exec(up) db.prepare('INSERT INTO schema_migrations (id, applied_at) VALUES (?, ?)').run( migrationId, new Date().toISOString(), ) db.prepare('INSERT INTO users (id, state_json, updated_at) VALUES (?, ?, ?)').run( 'u1', '{}', new Date().toISOString(), ) db.close() let r = spawnSync('node', ['scripts/sqlite-backup.mjs'], { cwd: backendRoot, env: { ...process.env, DB_PATH: srcDb, BACKUP_DIR: backupDir }, encoding: 'utf8', }) assert.equal(r.status, 0, r.stderr || r.stdout) const backupFile = readdirSync(backupDir).find((f) => f.endsWith('.db')) assert.ok(backupFile, 'backup file created') r = spawnSync( 'node', ['scripts/sqlite-restore.mjs', join(backupDir, backupFile!), restoreTarget], { cwd: backendRoot, env: { ...process.env, RESTORE_ACK_STOPPED: 'YES' }, encoding: 'utf8', }, ) assert.equal(r.status, 0, r.stderr || r.stdout) assert.ok(existsSync(restoreTarget)) const restored = new Database(restoreTarget, { readonly: true }) const row = restored.prepare('SELECT id FROM users WHERE id = ?').get('u1') as { id: string } restored.close() assert.equal(row.id, 'u1') } finally { try { rmSync(root, { recursive: true, force: true, maxRetries: 8, retryDelay: 200 }) } catch { // Windows may briefly lock SQLite files after close. } } console.log('backup-restore tests passed')