[object Object]

← back to Designer Wallcoverings

Kravet roll-add: add unit-mismatch guard (skip mural/panel/high-price products from per-roll variants) + write-audit-before-mutation pattern (survives process death). Cody FIX-FIRST items.

74ddf8b9ffdc529998e31a511566d1089ce4326c · 2026-08-18 15:34:22 -0700 · Steve

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 74ddf8b9ffdc529998e31a511566d1089ce4326c
Author: Steve <steve@designerwallcoverings.com>
Date:   Tue Aug 18 15:34:22 2026 -0700

    Kravet roll-add: add unit-mismatch guard (skip mural/panel/high-price products from per-roll variants) + write-audit-before-mutation pattern (survives process death). Cody FIX-FIRST items.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 .../scripts/cadence/add-kravet-roll-variants.js    | 30 +++++++++++++++++-----
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/shopify/scripts/cadence/add-kravet-roll-variants.js b/shopify/scripts/cadence/add-kravet-roll-variants.js
index fe249772..94ecaae3 100644
--- a/shopify/scripts/cadence/add-kravet-roll-variants.js
+++ b/shopify/scripts/cadence/add-kravet-roll-variants.js
@@ -155,6 +155,15 @@ function rollLabel(tags) {
     const label = rollLabel((p.tags || []).join(' '));
     const rollSku = (c.variant_sku || '').replace(/-sample$/i, '');
     const price = c.map.toFixed(2);
+    // UNIT-MISMATCH GUARD (2026-08-18, Cody FIX-FIRST): never create a "Sold Per Single Roll"
+    // variant on a mural/panel/meter product. Signal = mural/panel/scenic/tapestry/embroider in
+    // title/tags, OR a high MAP with no detected roll width (bare label). Skip + emit metric.
+    const ROLL_MAP_CEILING = 1500;
+    const muralish = /\b(mural|panel|scenic|tapestry|embroider)\b/i.test(`${c.title || ''} ${(p.tags || []).join(' ')}`);
+    if (muralish || (c.map > ROLL_MAP_CEILING && !/In Wide/i.test(label))) {
+      skip++; console.log(`  ⚠ SKIP-REVIEW (unit-mismatch?) ${c.mfr_sku} @ $${price} label:"${label}" ${(c.title || '').slice(0, 40)}`);
+      continue;
+    }
     const variantInput = [{
       price,
       inventoryPolicy: 'CONTINUE',
@@ -166,23 +175,32 @@ function rollLabel(tags) {
       console.log(`  + [${c.map_src}] ${c.mfr_sku}  add "${label}" @ $${price}  opt:${optName}  sku:${rollSku}  ${(c.title||'').slice(0,32)}`);
       added++; continue;
     }
+    // WRITE-AUDIT-BEFORE-MUTATION (2026-08-18, Cody FIX-FIRST): record intent (committed=false,
+    // no variant id) BEFORE creating, then UPDATE to committed after the API confirms. Survives a
+    // process death between create and log — the flaw that leaked 12 untracked variants.
+    const esc = s => String(s == null ? '' : s).replace(/'/g, "''");
+    let auditId = null;
+    try {
+      auditId = psql(`INSERT INTO kravet_roll_add_audit(shopify_id,mfr_sku,roll_sku,option_name,option_value,map_price,map_source,committed,note)
+        VALUES ('${c.shopify_id}','${esc(c.mfr_sku)}','${esc(rollSku)}','${esc(optName)}','${esc(label)}',${c.map},'${esc(c.map_src)}',false,'PENDING pre-mutation') RETURNING id;`);
+    } catch (e) { console.log(`  ⚠ pre-audit INSERT failed ${c.mfr_sku}: ${String(e.message || e).slice(0, 100)}`); }
     const res = await gqlRetry(MUT_CREATE, { pid: c.shopify_id, variants: variantInput });
     const r = res.json && res.json.data && res.json.data.productVariantsBulkCreate;
     const ue = r && r.userErrors;
     const good = res.status === 200 && ue && ue.length === 0 && r.productVariants && r.productVariants.length;
     const vid = good ? r.productVariants[0].id : null;
-    // AUDIT-WRITE GUARD (2026-08-18): the variant is already created above; a failed
-    // audit INSERT must NOT crash the run and leak an untracked variant. Wrap + emit vid.
+    const noteVal = good ? "'created'" : `'${esc(JSON.stringify(ue || res.raw || res.err)).slice(0, 150)}'`;
     try {
-      psql(`INSERT INTO kravet_roll_add_audit(shopify_id,mfr_sku,roll_sku,option_name,option_value,map_price,map_source,created_variant_id,committed,note)
-      VALUES ('${c.shopify_id}','${(c.mfr_sku||'').replace(/'/g,"''")}','${rollSku.replace(/'/g,"''")}','${optName.replace(/'/g,"''")}','${label.replace(/'/g,"''")}',${c.map},'${c.map_src}',${vid?`'${vid}'`:'NULL'},${good},${good?'NULL':`'${JSON.stringify(ue||res.raw||res.err).slice(0,150).replace(/'/g,"''")}'`});`);
+      if (auditId) psql(`UPDATE kravet_roll_add_audit SET committed=${good}, created_variant_id=${vid ? `'${vid}'` : 'NULL'}, note=${noteVal} WHERE id=${auditId};`);
+      else psql(`INSERT INTO kravet_roll_add_audit(shopify_id,mfr_sku,roll_sku,option_name,option_value,map_price,map_source,created_variant_id,committed,note)
+        VALUES ('${c.shopify_id}','${esc(c.mfr_sku)}','${esc(rollSku)}','${esc(optName)}','${esc(label)}',${c.map},'${esc(c.map_src)}',${vid ? `'${vid}'` : 'NULL'},${good},${noteVal});`);
     } catch (e) {
-      console.log(`  ⚠ AUDIT-WRITE FAILED (variant WAS created — record manually): shopify_id=${c.shopify_id} sku=${rollSku} vid=${vid||'?'} map=${c.map} src=${c.map_src} err=${String(e.message||e).slice(0,120)}`);
+      console.log(`  ⚠ AUDIT-UPDATE FAILED (variant vid=${vid || '?'} created — record manually): ${String(e.message || e).slice(0, 100)}`);
     }
     if (good) { added++; console.log(`  ✓ ${c.mfr_sku}  +${label} @ $${price}`); }
     else { fail++; console.log(`  ✗ ${c.mfr_sku} ${JSON.stringify(ue || res.raw || res.err).slice(0,150)}`); }
   }
-  console.log(`\n${COMMIT ? 'DONE' : 'PREVIEW'}: ${added} ${COMMIT ? 'added' : 'would add'}, ${already} already-have-roll, ${fail} failed.`);
+  console.log(`\n${COMMIT ? 'DONE' : 'PREVIEW'}: ${added} ${COMMIT ? 'added' : 'would add'}, ${already} already-have-roll, ${skip} skipped-review (unit-mismatch), ${fail} failed.`);
   if (COMMIT) console.log('Audit + rollback ids in dw_unified.kravet_roll_add_audit.');
   else console.log(`\nDRY-RUN — no writes. Re-run with --commit (--limit ${LIMIT}) to add roll variants.`);
 })();

← 252e2e9f Kravet roll-add: guard audit INSERT in try/catch so a loggin  ·  back to Designer Wallcoverings  ·  Kravet roll-add: harden unit-mismatch ceiling — drop the wid 67771259 →