From 47e17644de60d8ed9d41ac79f6c4a248afbd9143 Mon Sep 17 00:00:00 2001 From: Thomas Joise Date: Sun, 19 Jul 2026 21:00:41 +0530 Subject: [PATCH] chore(d35): script to apply approved client-name corrections (audited) Reads the reviewed name-review.json and applies each changed name via updateClient (audited, guarded: only updates when the stored name still matches what was reviewed). Ran on live data after a backup: 187 names corrected (co-op style unified to CO-OPERATIVE, run-on splits, ARP00KARA->ARPOOKARA, double spaces), 0 skipped. Co-Authored-By: Claude Fable 5 --- apps/hq/scripts/apply-name-fixes.ts | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 apps/hq/scripts/apply-name-fixes.ts diff --git a/apps/hq/scripts/apply-name-fixes.ts b/apps/hq/scripts/apply-name-fixes.ts new file mode 100644 index 0000000..15b6dbf --- /dev/null +++ b/apps/hq/scripts/apply-name-fixes.ts @@ -0,0 +1,37 @@ +// apps/hq/scripts/apply-name-fixes.ts — one-off (D35 data correction): apply the approved +// client-name corrections from name-review.json via the audited updateClient path. +// REVIEW_JSON= DATABASE_URL=postgres://… npx tsx apps/hq/scripts/apply-name-fixes.ts +import { readFileSync } from 'node:fs' +import { openDb } from '../src/db' +import { openPgDb } from '../src/db-pg' +import { updateClient } from '../src/repos-clients' + +interface Row { id: string; current: string; suggested: string; changed: boolean } + +async function main() { + const path = process.env['REVIEW_JSON'] + if (path === undefined) throw new Error('Set REVIEW_JSON to the name-review.json path') + const rows = JSON.parse(readFileSync(path, 'utf8')) as Row[] + const pgUrl = process.env['DATABASE_URL'] ?? '' + const db = pgUrl !== '' ? await openPgDb(pgUrl) : openDb(process.env['HQ_DATA_DIR']) + + let applied = 0, skipped = 0 + for (const r of rows) { + if (!r.changed || r.suggested === r.current) continue + try { + // Guard: only touch a client whose stored name still matches what was reviewed. + const cur = await db.get<{ name: string }>(`SELECT name FROM client WHERE id=?`, r.id) + if (cur === undefined || cur.name !== r.current) { skipped++; continue } + await updateClient(db, 'system', r.id, { name: r.suggested }) + applied++ + } catch (e) { + skipped++ + // eslint-disable-next-line no-console + console.error(` skip ${r.current}: ${e instanceof Error ? e.message : String(e)}`) + } + } + // eslint-disable-next-line no-console + console.log(`Name corrections: ${applied} applied, ${skipped} skipped.`) +} + +main().catch((e) => { console.error(e); process.exit(1) })