[object Object]

← back to Designerwallcoverings

TK-11635: re-check each variant immediately before its delete, not only in the pre-flight

5f814e0372b3d5b85bb55562703810a8e719e08e · 2026-09-13 16:30:03 -0700 · Steve Abrams

The upfront guard clears all 462 in one pass, then deletes stream out over ~15 minutes of
paced batches. The re-stamper has fired six times; a variant could flip orderable inside that
window and the pre-flight verdict would be stale. Now one read per product right before its
delete, with the same guard — skip on any change, hard-stop if it went orderable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXQjayvMLrRoUmj3pFfcAB

Files touched

Diff

commit 5f814e0372b3d5b85bb55562703810a8e719e08e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sun Sep 13 16:30:03 2026 -0700

    TK-11635: re-check each variant immediately before its delete, not only in the pre-flight
    
    The upfront guard clears all 462 in one pass, then deletes stream out over ~15 minutes of
    paced batches. The re-stamper has fired six times; a variant could flip orderable inside that
    window and the pre-flight verdict would be stale. Now one read per product right before its
    delete, with the same guard — skip on any change, hard-stop if it went orderable.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01PXQjayvMLrRoUmj3pFfcAB
---
 scripts/tk11635-fentucci-zerovariant-delete.mjs | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/scripts/tk11635-fentucci-zerovariant-delete.mjs b/scripts/tk11635-fentucci-zerovariant-delete.mjs
index c2abdbf..2cb506b 100644
--- a/scripts/tk11635-fentucci-zerovariant-delete.mjs
+++ b/scripts/tk11635-fentucci-zerovariant-delete.mjs
@@ -147,6 +147,23 @@ for (let i = 0; i < cleared.length; i += BATCH) {
   const batch = cleared.slice(i, i + BATCH);
   console.error(`\nbatch ${Math.floor(i / BATCH) + 1}/${Math.ceil(cleared.length / BATCH)}  (${batch.length} products)`);
   for (const c of batch) {
+    // RE-CHECK IMMEDIATELY BEFORE THE DELETE, not just in the upfront pass.
+    // The upfront guard runs over all 462 in one go, then deletes stream out over ~15 minutes.
+    // The re-stamper has fired six times; a variant could flip orderable inside that window and
+    // the upfront verdict would be stale. One extra read per product is cheap next to deleting
+    // something whose shape changed under us.
+    const rc = await gql(VQ, { ids: [c.variant_gid] });
+    const rn = rc?.nodes?.[0];
+    const rlive = rn ? { vendor: rn.product.vendor, title: rn.title, price: rn.price,
+      availableForSale: rn.availableForSale, inventoryPolicy: rn.inventoryPolicy,
+      inventoryQuantity: rn.inventoryQuantity,
+      siblings: rn.product.variants.nodes.filter(v => v.id !== rn.id) } : null;
+    const rReason = guard(c, rlive);
+    if (rReason) {
+      console.error(`\n  SKIP (changed since pre-flight) ${c.handle}: ${rReason}`);
+      if (isHardStop(rReason)) { console.error('  HARD STOP mid-run — a $0 variant became orderable. Stopping.'); process.exit(7); }
+      err++; continue;
+    }
     const d = await gql(M, { productId: c.product_gid, ids: [c.variant_gid] });
     const ue = d?.productVariantsBulkDelete?.userErrors || [];
     if (d?.__err || ue.length) { err++; console.error(`  ERR ${c.handle}:`, JSON.stringify(d?.__err || ue)); continue; }

← 230e03d TK-11574: exhaustive phrasing-agnostic title_tag backstop (r  ·  back to Designerwallcoverings  ·  auto-data-snapshot: 2026-09-13T16:30:12 (10 data files) — .g 7b7ff51 →