← back to Sample Followup Sweep
sample-followup: draft gated vid-backfill for 3 verified leaked SKUs (TK-12118)
5b5b893a14fc504e4cca2bc395a0cd51b4febda9 · 2026-09-23 17:33:14 -0700 · Steve Abrams
Files touched
A scripts/tk12118-vid-backfill.mjs
Diff
commit 5b5b893a14fc504e4cca2bc395a0cd51b4febda9
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 23 17:33:14 2026 -0700
sample-followup: draft gated vid-backfill for 3 verified leaked SKUs (TK-12118)
---
scripts/tk12118-vid-backfill.mjs | 74 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/scripts/tk12118-vid-backfill.mjs b/scripts/tk12118-vid-backfill.mjs
new file mode 100644
index 0000000..1010631
--- /dev/null
+++ b/scripts/tk12118-vid-backfill.mjs
@@ -0,0 +1,74 @@
+// TK-12118 — backfill the missing `vid` on the 3 VERIFIED outstanding empty-vid records the
+// coverage-reconcile canary (TK-12117) flagged as LEAKED (outstanding in FileMaker but dropped
+// by the sweep before grouping because vid was blank → never chased, never reported).
+//
+// Vendors verified LIVE against FileMaker sibling records (not prefix guesses):
+// DWTT70793 rec 538622 entered 07/30/2026 -> vid "Thib" (Supplier "Thibaut Wallpaper"; sibling 02/18/2025 carries vid=Thib)
+// GLM9116 rec 541395 entered 09/08/2026 -> vid "FTR" (Company "future Textile"; siblings carry vid=FTR = Future Textiles)
+// DWPN100994 rec 541415 entered 09/08/2026 -> vid "POI" (Supplier "Pointe at Justin David"; sibling carries vid=POI)
+// NOTE: DWPN100994 ARRIVED 09/14/2026 on a twin record — after this backfill the never-false-chase
+// guard (TK-12105) will correctly SUPPRESS it (arrived), not chase it. Expected/correct.
+//
+// NOT included: DWLC1059 (Supplier "LA Walls") — LA Walls has NO vid anywhere in FileMaker or the
+// fleet; assigning one is a vendor-registry decision for Steve. Left as WARN, not backfilled.
+//
+// USAGE:
+// node ~/Projects/sample-followup-sweep/scripts/tk12118-vid-backfill.mjs # backfill + write restore-map
+// node ~/Projects/sample-followup-sweep/scripts/tk12118-vid-backfill.mjs --rollback # undo (set vid back to '')
+// Blast radius = 3 rows. Reversible via the restore-map (data/tk12118-vid-backfill-restore-map.json).
+import { readFileSync, writeFileSync } from 'node:fs';
+import { homedir } from 'node:os';
+import { join } from 'node:path';
+
+const cfg = JSON.parse(readFileSync(join(homedir(), '.claude.json'), 'utf8'));
+const env = cfg?.mcpServers?.filemaker?.env || {};
+for (const k of ['FM_CLOUD_HOST', 'FM_CLARIS_EMAIL', 'FM_CLARIS_PASSWORD']) process.env[k] = env[k];
+const fm = await import('/Users/macstudio3/Projects/filemaker-mcp/src/fm-client.js');
+
+const DB = 'WALLPAPER', LAYOUT = 'Report for old memo samples', FIELD = 'vid';
+const MAP = join(homedir(), 'Projects/sample-followup-sweep/data/tk12118-vid-backfill-restore-map.json');
+const TARGETS = [
+ { sku: 'DWTT70793', recordId: '538622', vid: 'Thib', entered: '07/30/2026' },
+ { sku: 'GLM9116', recordId: '541395', vid: 'FTR', entered: '09/08/2026' },
+ { sku: 'DWPN100994', recordId: '541415', vid: 'POI', entered: '09/08/2026' },
+];
+const ROLLBACK = process.argv.includes('--rollback');
+
+async function readRec(recordId) {
+ const { records } = await fm.findRecords(DB, LAYOUT, { 'recordId': `==${recordId}` }, { limit: 1 })
+ .catch(async () => {
+ // some layouts don't expose recordId as a findable field — fall back to getRecord if available
+ if (fm.getRecord) { const r = await fm.getRecord(DB, LAYOUT, recordId); return { records: r ? [r] : [] }; }
+ return { records: [] };
+ });
+ return records[0] || null;
+}
+
+if (ROLLBACK) {
+ const map = JSON.parse(readFileSync(MAP, 'utf8'));
+ for (const m of map) {
+ await fm.updateRecord(DB, LAYOUT, m.recordId, { [FIELD]: m.oldVid }, { dryRun: false });
+ console.log(`rolled back rec ${m.recordId} (${m.sku}) vid -> "${m.oldVid}"`);
+ }
+ console.log('rollback complete.');
+ process.exit(0);
+}
+
+const restore = [];
+for (const t of TARGETS) {
+ // SAFETY: only write if the record still has an EMPTY vid and matches the expected SKU (guard against drift)
+ const rec = await readRec(t.recordId);
+ const cur = rec ? (rec.fieldData[FIELD] || '').trim() : null;
+ const curSku = rec ? (rec.fieldData['combo sku'] || '').trim() : null;
+ if (!rec) { console.log(`SKIP ${t.sku} rec ${t.recordId}: record not found`); continue; }
+ if (curSku !== t.sku) { console.log(`SKIP ${t.sku} rec ${t.recordId}: SKU mismatch (found "${curSku}") — aborting this row`); continue; }
+ if (cur !== '') { console.log(`SKIP ${t.sku} rec ${t.recordId}: vid already "${cur}" (not empty) — not overwriting`); continue; }
+ restore.push({ sku: t.sku, recordId: t.recordId, oldVid: '' });
+ await fm.updateRecord(DB, LAYOUT, t.recordId, { [FIELD]: t.vid }, { dryRun: false });
+ // read-back verify
+ const after = await readRec(t.recordId);
+ const now = after ? (after.fieldData[FIELD] || '').trim() : '?';
+ console.log(`${now === t.vid ? 'OK ' : 'WARN'} ${t.sku} rec ${t.recordId}: vid "" -> "${now}"${now === t.vid ? '' : ' (expected ' + t.vid + ')'}`);
+}
+writeFileSync(MAP, JSON.stringify(restore, null, 2));
+console.log(`\nrestore-map written: ${MAP} (${restore.length} rows). Rollback: node scripts/tk12118-vid-backfill.mjs --rollback`);
← b9f7fd7 auto-data-snapshot: 2026-09-23T16:24:32 (2 data files) — dat
·
back to Sample Followup Sweep
·
auto-data-snapshot: 2026-09-23T18:30:30 (1 data files) — dat 367e1e4 →