← back to Tk 11331 Exec
scripts/d3b_refresh_rollback.mjs
36 lines
#!/usr/bin/env node
// TK-11331 D3b — reverse the recovery refresh (alt_sku backfill) using data/d3b-refresh-restore.jsonl.
// For op:update rows, restores old field values (alt_sku back to its prior blank/null).
// For op:insert rows (only present if a full --commit non-alt-only run inserted), DELETEs them.
// DRY-RUN by default; --apply to execute. Run with NODE_PATH=$HOME/Projects/AbramsOS/node_modules
import { createRequire } from 'module';
import fs from 'fs';
const require = createRequire(import.meta.url);
const { Pool } = require('pg');
const HERE = new URL('..', import.meta.url).pathname;
const RESTORE = HERE + 'data/d3b-refresh-restore.jsonl';
const APPLY = process.argv.includes('--apply');
const pool = new Pool({ connectionString: 'postgresql://dw_admin:DW2024!@127.0.0.1:5432/dw_unified' });
async function main() {
const rows = fs.readFileSync(RESTORE, 'utf8').split('\n').filter(Boolean).map(l => JSON.parse(l));
const upd = rows.filter(r => r.op === 'update'), ins = rows.filter(r => r.op === 'insert');
console.log(`restore map: ${upd.length} updates to revert, ${ins.length} inserts to delete. ${APPLY ? 'APPLYING' : 'DRY-RUN'}`);
if (!APPLY) { await pool.end(); return; }
const c = await pool.connect(); let reverted = 0, deleted = 0;
try {
await c.query('BEGIN');
for (const r of upd) {
const cols = Object.keys(r.old); if (!cols.length) continue;
const sets = cols.map((k, i) => `${k}=$${i + 1}`);
await c.query(`UPDATE momentum_colorways SET ${sets.join(',')},updated_at=now() WHERE id=$${cols.length + 1}`,
[...cols.map(k => r.old[k]), r.id]); reverted++;
}
for (const r of ins) { await c.query(`DELETE FROM momentum_colorways WHERE id=$1`, [r.id]); deleted++; }
await c.query('COMMIT');
console.log(`REVERTED ${reverted} updates, DELETED ${deleted} inserts.`);
} catch (e) { await c.query('ROLLBACK'); console.error('ROLLBACK:', e.message); process.exitCode = 1; }
finally { c.release(); await pool.end(); }
}
main().catch(e => { console.error(e); process.exit(1); });