[object Object]

← back to Dw Yolo Loop

schu roll-adds: complete all 81 (41 clean + 36 edge + 4 oddball); make edge script idempotent across cap-blocked partial runs

5c719ab563620012a74909a155db3c1b0d1adab1 · 2026-06-16 10:20:34 -0700 · Steve Abrams

Edge bug: a prior cap-blocked run renamed Title->Size/Default Title->Sample but
died before creating the Roll variant; created.json only records after a
successful create, so re-runs found no 'Default Title' and skipped all 36.
Fix: handle already-renamed (Size:Sample) state + skip(roll exists) guard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files touched

Diff

commit 5c719ab563620012a74909a155db3c1b0d1adab1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jun 16 10:20:34 2026 -0700

    schu roll-adds: complete all 81 (41 clean + 36 edge + 4 oddball); make edge script idempotent across cap-blocked partial runs
    
    Edge bug: a prior cap-blocked run renamed Title->Size/Default Title->Sample but
    died before creating the Roll variant; created.json only records after a
    successful create, so re-runs found no 'Default Title' and skipped all 36.
    Fix: handle already-renamed (Size:Sample) state + skip(roll exists) guard.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 scripts/price-sheets/add-roll-variant-edge.mjs | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/scripts/price-sheets/add-roll-variant-edge.mjs b/scripts/price-sheets/add-roll-variant-edge.mjs
index 0a85b71..b74a9a4 100644
--- a/scripts/price-sheets/add-roll-variant-edge.mjs
+++ b/scripts/price-sheets/add-roll-variant-edge.mjs
@@ -60,14 +60,24 @@ const LOCATION=loc.locations.nodes[0].id;
 
 let ok=0,err=0,invok=0,inverr=0;
 for(const t of targets){
-  // 1) rename option Title->Size and its value Default Title->Sample
+  // 1) rename option Title->Size and its value Default Title->Sample.
+  //    Idempotent: a prior cap-blocked run may have already renamed (Size:Sample)
+  //    but never created the Roll (created.json only records AFTER a create), so
+  //    handle the already-renamed state instead of skipping it.
   const ov=await gql(QOV,{id:t.pid});
   const opt=ov?.node?.options?.[0];
-  const valId=opt?.optionValues?.find(x=>x.name==='Default Title')?.id;
-  if(!opt||!valId){err++;console.log('  skip(no opt val)',t.ssku);continue;}
-  const ru=await gql(OPTU,{productId:t.pid,option:{id:opt.id,name:'Size'},optionValuesToUpdate:[{id:valId,name:'Sample'}]});
-  const rue=ru?.__err||ru?.productOptionUpdate?.userErrors;
-  if(ru?.__err||(rue&&rue.length)){err++;if(err<=10)console.log('  rename-err',t.ssku,JSON.stringify(rue).slice(0,140));continue;}
+  if(!opt){err++;console.log('  skip(no opt)',t.ssku);continue;}
+  const vals=opt.optionValues||[];
+  // already has the Roll variant? skip (idempotent re-run)
+  if(vals.some(x=>x.name==='Roll')){console.log('  skip(roll exists)',t.rsku);continue;}
+  const dtId=vals.find(x=>x.name==='Default Title')?.id;
+  if(opt.name==='Size'&&vals.some(x=>x.name==='Sample')){
+    // rename already done by a prior run — go straight to create
+  }else if(dtId){
+    const ru=await gql(OPTU,{productId:t.pid,option:{id:opt.id,name:'Size'},optionValuesToUpdate:[{id:dtId,name:'Sample'}]});
+    const rue=ru?.__err||ru?.productOptionUpdate?.userErrors;
+    if(ru?.__err||(rue&&rue.length)){err++;if(err<=10)console.log('  rename-err',t.ssku,JSON.stringify(rue).slice(0,140));continue;}
+  }else{err++;console.log('  skip(no opt val)',t.ssku,`opt=${opt.name}:[${vals.map(v=>v.name).join(',')}]`);continue;}
   // 2) add Size:Roll @ retail
   const d=await gql(C,{productId:t.pid,variants:[{price:t.retail.toFixed(2),inventoryItem:{sku:t.rsku,tracked:true},optionValues:[{optionName:'Size',name:'Roll'}]}]});
   const ue=d?.__err||d?.productVariantsBulkCreate?.userErrors;

← fabc295 alt-text coverage audit: repped-vendor image alt-text (read-  ·  back to Dw Yolo Loop  ·  enrichment-board: local synthesis of c26/c28/c29/GMC into on c79083c →