← 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
M scripts/tk11635-fentucci-zerovariant-delete.mjs
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 →