← back to Mfr Review Viewer Corruption
executor: add belongs-to-SKU (skuMatch) guard to execute-time re-verify — refuses to delete a foreign record even if a plan lists it
e24c2874ce942afaf0a5a410d211bab733605213 · 2026-08-27 11:20:30 -0700 · Steve Abrams
Files touched
M scripts/execute-sweep.mjs
Diff
commit e24c2874ce942afaf0a5a410d211bab733605213
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Aug 27 11:20:30 2026 -0700
executor: add belongs-to-SKU (skuMatch) guard to execute-time re-verify — refuses to delete a foreign record even if a plan lists it
---
scripts/execute-sweep.mjs | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/scripts/execute-sweep.mjs b/scripts/execute-sweep.mjs
index 459b0e3..0caa907 100644
--- a/scripts/execute-sweep.mjs
+++ b/scripts/execute-sweep.mjs
@@ -93,7 +93,8 @@ function parseNoteMfr(note) {
// Given a live fieldData object + the dw_sku, compute (sampleOrdered, mfrPlaceholder).
// This IS the execute-time re-verification predicate.
function classifyRecord(fd, dwSku) {
- const tail = numericTail(String(dwSku || '').trim().replace(/[-_ ]?sample$/i, ''));
+ const clean = String(dwSku || '').trim().replace(/[-_ ]?sample$/i, '');
+ const tail = numericTail(clean);
const mfrPattern = String(fd['Mfr Pattern'] || '').trim();
const chaseMemo = String(fd['Vendor Sample - Where is Memo Send 2nd day'] || '').trim();
const mfrNote = mfrPattern || (/#/.test(chaseMemo) ? chaseMemo : '');
@@ -106,7 +107,18 @@ function classifyRecord(fd, dwSku) {
const codeHasAlpha = /[A-Za-z]/.test(noteMfr || '');
const codeDigits = String(noteMfr || mfrPattern || '').replace(/[^0-9]/g, '');
const mfrPlaceholder = !codeHasAlpha && !!tail && codeDigits === tail;
- return { sampleOrdered, mfrPlaceholder, mfrPattern, noteMfr };
+
+ // BELONGS-TO-SKU guard (2026-08-27, critical): a record's Series+JS Pattern must
+ // normalize to THIS dw_sku. A foreign record (e.g. Schumacher SCH|51526 that merely
+ // shares the number 51526 with HSW-51526) is NOT this SKU and must NEVER be deleted,
+ // even though it reads no-sample + placeholder. Mirrors candidates.mjs skuMatch.
+ const normSku = (s) => String(s || '').toUpperCase().replace(/[^A-Z0-9]/g, '');
+ const target = normSku(clean);
+ const storedKey = normSku(String(fd.Series || '') + String(fd['JS Pattern'] || ''));
+ const comboKey = normSku(fd['combo sku']);
+ const skuMatch = !!target && (storedKey === target || comboKey === target);
+
+ return { sampleOrdered, mfrPlaceholder, mfrPattern, noteMfr, skuMatch };
}
// ---- plan loading ----------------------------------------------------------
@@ -253,6 +265,7 @@ async function main() {
const rec = live[rid];
if (!rec) { console.log(` SKIP delete ${rid}: record no longer exists`); skippedMismatch++; continue; }
const c = classifyRecord(rec.fieldData || {}, e.dw_sku);
+ if (!c.skuMatch) { console.log(` SKIP delete ${rid}: does NOT belong to ${e.dw_sku} (foreign record ${rec.fieldData?.Series || ''}|${rec.fieldData?.['JS Pattern'] || ''}) — NEVER delete a different SKU's record`); skippedMismatch++; continue; }
if (c.sampleOrdered) { console.log(` SKIP delete ${rid}: now has SAMPLE history (sampleOrdered) — KEEP`); skippedMismatch++; continue; }
if (!c.mfrPlaceholder) { console.log(` SKIP delete ${rid}: mfr no longer a placeholder ("${c.mfrPattern}") — KEEP`); skippedMismatch++; continue; }
confirmedDeletes.push(rid);
← ac96049 viewer: prominent 'Suggested real mfr → Approve into field'
·
back to Mfr Review Viewer Corruption
·
scope to ACTIVE patterns only: default status='ACTIVE' in bu dcd7c8f →