/** * Prove the anti-wipe guard: a stale empty in-memory DB must not overwrite * a richer on-disk materials catalog. */ import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import initSqlJs from 'sql.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const dbPath = path.join(__dirname, '..', 'data', 'configurateur.db'); const SQL = await initSqlJs({ locateFile: (f) => path.join(__dirname, '..', 'node_modules', 'sql.js', 'dist', f) }); function count(file) { const db = new SQL.Database(fs.readFileSync(file)); const n = Number(db.exec('SELECT COUNT(*) FROM formex_materials')[0].values[0][0]); db.close(); return n; } const before = count(dbPath); console.log('disk before:', before); if (before < 1) { console.error('FAIL: expected materials on disk before guard test'); process.exit(1); } // Simulate a stale empty process writing the whole file (old wipe mode). const empty = new SQL.Database(); empty.exec(` CREATE TABLE formex_materials ( id INTEGER PRIMARY KEY AUTOINCREMENT, formex_code TEXT UNIQUE NOT NULL, name TEXT NOT NULL, collection TEXT NOT NULL ); `); // Mimic the NEW guarded save from db/index.js function guardedSave(database) { const memCount = Number(database.exec('SELECT COUNT(*) FROM formex_materials')[0]?.values?.[0]?.[0] ?? 0); const diskCount = count(dbPath); if (diskCount > 0 && memCount < diskCount) { console.log(`GUARD OK: refused overwrite (mem=${memCount}, disk=${diskCount})`); return false; } fs.writeFileSync(dbPath, Buffer.from(database.export())); return true; } const wrote = guardedSave(empty); empty.close(); const after = count(dbPath); console.log('disk after:', after); if (wrote || after !== before) { console.error('FAIL: guard did not protect materials'); process.exit(1); } console.log('PASS: scrapes on disk are protected from empty overwrites');