← back to Hollywood Optc
build-restore-map.mjs
129 lines
#!/usr/bin/env node
// TK-10633 Option C — REVERSIBLE PREP. Build the HW-<hash> restore-map for the 646
// ACTIVE Momentum-real DWHD-* products. READ-ONLY: reads the local dw_unified mirror,
// writes ONLY a local restore file. Fires NOTHING at Shopify or dw_unified.
//
// Hash REUSED VERBATIM from hollywood-import/momentum-feed/assign-sku.mjs (canary-steve's
// forward-fix): HW-<sha256(String(number)).slice(0,12).toUpperCase()>. Must match so
// generator-minted codes and these retroactive codes agree.
import { createRequire } from 'module';
import { createHash } from 'node:crypto';
import { writeFileSync } from 'node:fs';
const require = createRequire(import.meta.url);
const { Pool } = require('pg');
// --- canary-steve's canonical hash (assign-sku.mjs lines 70-72) ---
const PL_PREFIX = process.env.HW_PL_PREFIX || 'HW';
const HASH_LEN = Number(process.env.HW_HASH_LEN || 12);
const plSku = num => `${PL_PREFIX}-${createHash('sha256').update(String(num)).digest('hex').slice(0, HASH_LEN).toUpperCase()}`;
const pool = new Pool({ connectionString: (process.env.PGCONNSTRING || 'postgresql://dw_admin@127.0.0.1:5432/dw_unified?host=/tmp') });
const BASE = `status='ACTIVE' AND variant_sku ~ '^DWHD' AND (metafields->'dwc'->'real_vendor'->>'value')='Momentum'`;
async function main() {
// The 646 targets. variant_sku in the mirror is the SAMPLE variant (DWHD-#####-Sample);
// the customer-facing BASE sku is that minus '-Sample'. mfr number = custom.manufacturer_sku.
const { rows } = await pool.query(
`SELECT variant_id, variant_sku, title, handle,
(metafields->'custom'->'manufacturer_sku'->>'value') AS mfr_custom,
(metafields->'dwc'->'manufacturer_sku'->>'value') AS mfr_dwc,
(metafields->'global'->'dw_sku'->>'value') AS gdw,
(metafields->'dwc'->'dw_sku'->>'value') AS ddw,
(metafields->'custom'->'dw_sku'->>'value') AS cdw
FROM shopify_products WHERE ${BASE}
ORDER BY variant_sku`);
if (rows.length !== 646) console.warn(`WARN: expected 646, got ${rows.length}`);
const map = [];
const problems = [];
for (const r of rows) {
const mfr = r.mfr_custom || r.mfr_dwc;
if (!mfr) { problems.push({ variant_sku: r.variant_sku, why: 'no manufacturer_sku' }); continue; }
// base customer-facing sku = sample sku minus trailing -Sample (case-insensitive)
const oldBase = r.variant_sku.replace(/-sample$/i, '');
const newBase = plSku(mfr);
const newSample = `${newBase}-Sample`;
// which dw_sku metafields are polluted with a DWH* code (need HW-hash too)
const polluted = [];
if ((r.gdw || '').match(/^DWH/)) polluted.push('global.dw_sku');
if ((r.ddw || '').match(/^DWH/)) polluted.push('dwc.dw_sku');
if ((r.cdw || '').match(/^DWH/)) polluted.push('custom.dw_sku');
map.push({
variant_id: r.variant_id,
old_variant_sku: r.variant_sku, // DWHD-#####-Sample (the actual stored/sellable-sample sku)
old_base_sku: oldBase, // DWHD-#####
manufacturer_sku: mfr, // UNTOUCHED internal Momentum number
new_base_sku: newBase, // HW-<hash>
new_variant_sku: newSample, // HW-<hash>-Sample
mfr_is_bare_number: /^[0-9]+$/.test(mfr),
polluted_dw_sku_metafields: polluted, // which dw_sku mfs to rewrite HW-<hash>
dw_sku_old: { global: r.gdw, dwc: r.ddw, custom: r.cdw },
title: r.title, handle: r.handle,
});
}
// --- VERIFY (a): HW-hash collisions across all 646 ---
// A collision here is NOT a hash weakness (48-bit @ n=646 is astronomically safe) but a
// SHARED manufacturer_sku: Momentum gave two distinct colorways the same supplier number,
// so the deterministic hash collapses them. We must NOT collapse two live products to one
// SKU, and we must NOT fabricate a distinguishing number. So: split the set into a CLEAN
// apply-set (unique mfr number) and a HELD collision-exception set (stays DWHD until the
// true distinct Momentum numbers are recovered — same "never fabricate" discipline as the
// whole Hollywood reconciliation).
const codeCount = {};
for (const m of map) codeCount[m.new_base_sku] = (codeCount[m.new_base_sku] || 0) + 1;
const collidingCodes = new Set(Object.entries(codeCount).filter(([, n]) => n > 1).map(([c]) => c));
const collisionExceptions = map.filter(m => collidingCodes.has(m.new_base_sku));
const applySet = map.filter(m => !collidingCodes.has(m.new_base_sku));
const collisionsWithin = [...collidingCodes];
// --- VERIFY (a2): zero collision against EXISTING live SKUs (any product NOT in this set) ---
const targetVids = new Set(map.map(m => m.variant_id));
const { rows: existing } = await pool.query(
`SELECT variant_id, variant_sku FROM shopify_products
WHERE variant_sku ~* '^HW-' `);
const existingHW = existing.filter(e => !targetVids.has(e.variant_id))
.map(e => e.variant_sku.replace(/-sample$/i, ''));
const existingHWset = new Set(existingHW.map(s => s.toUpperCase()));
// check the APPLY-SET codes against existing live HW SKUs
const applyCodes = applySet.map(m => m.new_base_sku);
const collisionsExisting = [...new Set(applyCodes.filter(c => existingHWset.has(c.toUpperCase())))];
// --- VERIFY (b): zero DWHD/DWHW residue in the NEW codes ---
const residue = map.filter(m => /^DWH/i.test(m.new_base_sku) || /DWHD|DWHW/i.test(m.new_variant_sku));
// --- VERIFY (c): no HW code accidentally equals a real Momentum (bare) number ---
// HW codes are prefixed 'HW-' + hex; a bare Momentum number is all digits. Structurally
// impossible to equal, but assert anyway.
const equalsMomentum = map.filter(m => /^[0-9]+$/.test(m.new_base_sku.replace(/^HW-/, '')) === false ? false : true)
.filter(m => m.new_base_sku === m.manufacturer_sku);
const summary = {
generated_at: new Date().toISOString(),
ticket: 'TK-10633',
hash_source: 'hollywood-import/momentum-feed/assign-sku.mjs (HW-<sha256(String(num)).slice(0,12).toUpperCase()>)',
hash_prefix: PL_PREFIX, hash_len: HASH_LEN,
total_targeted: map.length,
apply_set_count: applySet.length, // clean, unique-mfr rows to remap
held_collision_rows: collisionExceptions.length, // shared-mfr rows held at DWHD
skipped_no_mfr: problems.length,
polluted_dw_sku_metafield_rows: applySet.filter(m => m.polluted_dw_sku_metafields.length).length,
verify: {
collisions_within_apply_set: 0, // by construction (collisions removed)
shared_mfr_collision_groups: collisionsWithin.length, // held out, NOT applied
collisions_vs_existing_live_HW: collisionsExisting.length, // MUST be 0
dwhd_dwhw_residue_in_new_applyset: applySet.filter(m => /^DWH/i.test(m.new_base_sku) || /DWHD|DWHW/i.test(m.new_variant_sku)).length, // MUST be 0
new_code_equals_momentum_number: equalsMomentum.length, // MUST be 0
collision_codes: collisionsWithin,
collision_rows: collisionExceptions.map(m => ({ old: m.old_variant_sku, mfr: m.manufacturer_sku, title: m.title })),
},
};
writeFileSync('data/hw-restore-map.json', JSON.stringify({ summary, problems, apply_set: applySet, held_collision_rows: collisionExceptions, full_map: map }, null, 2));
console.log(JSON.stringify(summary, null, 2));
await pool.end();
}
main().catch(e => { console.error(e); process.exit(1); });