[object Object]

← back to Dw Yolo Loop

Schumacher add-roll: idempotent skip + accumulate revert-log across runs; 2-product live test verified (Sample+Roll @ retail, inv 2026)

11048a70c1ce911ecc00163339e380af836f6ccc · 2026-06-15 10:58:09 -0700 · Steve Abrams

Files touched

Diff

commit 11048a70c1ce911ecc00163339e380af836f6ccc
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Jun 15 10:58:09 2026 -0700

    Schumacher add-roll: idempotent skip + accumulate revert-log across runs; 2-product live test verified (Sample+Roll @ retail, inv 2026)
---
 scripts/price-sheets/add-roll-variant.mjs | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/scripts/price-sheets/add-roll-variant.mjs b/scripts/price-sheets/add-roll-variant.mjs
index 528ea6e..b24339e 100644
--- a/scripts/price-sheets/add-roll-variant.mjs
+++ b/scripts/price-sheets/add-roll-variant.mjs
@@ -29,6 +29,12 @@ const sleep=ms=>new Promise(r=>setTimeout(r,ms));
 async function gql(q,v){for(let a=0;a<8;a++){let j;try{const r=await fetch(URL,{method:'POST',headers:{'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v})});j=await r.json();}catch(e){await sleep(1500*(a+1));continue;}if(j.errors){if(JSON.stringify(j.errors).includes('THROTTLED')){await sleep(2000*(a+1));continue;}return{__err:j.errors};}const t=j.extensions?.cost?.throttleStatus;if(t&&t.currentlyAvailable<400)await sleep(1200);return j.data;}throw new Error('retries');}
 
 let targets=fs.readFileSync('/tmp/schu-addroll-targets.csv','utf8').trim().split('\n').map(l=>{const[pid,svid,ssku,rsku,retail,cost]=l.split(',');return{pid,svid,ssku,rsku,retail:+retail,cost:+cost};});
+// idempotent: skip products that already got a roll variant (recorded in created json)
+let donePids=new Set();
+try{donePids=new Set(JSON.parse(fs.readFileSync('data/price-sheets/addroll-created.json','utf8')).map(c=>c.pid));}catch{}
+const skipDone=targets.filter(t=>donePids.has(t.pid)).length;
+targets=targets.filter(t=>!donePids.has(t.pid));
+if(skipDone)console.log(`(skipping ${skipDone} already-created)`);
 if(Number.isFinite(LIMIT))targets=targets.slice(0,LIMIT);
 console.log(`add-roll-variant — mode: ${APPLY?'⚠️  LIVE APPLY':'DRY-RUN'} | targets: ${targets.length} (of 532)`);
 
@@ -54,7 +60,9 @@ const C=`mutation($productId:ID!,$variants:[ProductVariantsBulkInput!]!){product
 const INV=`mutation($input:InventorySetOnHandQuantitiesInput!){inventorySetOnHandQuantities(input:$input){userErrors{field message}}}`;
 const QII=`query($id:ID!){node(id:$id){... on ProductVariant{inventoryItem{id}}}}`;
 
-const created=[]; let ok=0,err=0,invok=0,inverr=0;
+// accumulate created records across runs (don't clobber prior runs' revert log)
+let created=[]; try{created=JSON.parse(fs.readFileSync('data/price-sheets/addroll-created.json','utf8'));}catch{}
+let ok=0,err=0,invok=0,inverr=0;
 for(const t of targets){
   // 1) add the Roll variant
   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'}]}]});

← d8390e1 Kravet dedup: archived 18 duplicate products live + 301 redi  ·  back to Dw Yolo Loop  ·  Add Schumacher edge add-roll handler (37 Default-Title via o e96c972 →