[object Object]

← back to Designer Wallcoverings

Archive confirmed-duplicate Zoffany DWZF-187385 (-1 dup-handle clone); keep DWZF-187037 live

959ae44241ec0134750129d60f6741672481ce40 · 2026-06-21 13:49:45 -0700 · SteveStudio2

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

Files touched

Diff

commit 959ae44241ec0134750129d60f6741672481ce40
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Sun Jun 21 13:49:45 2026 -0700

    Archive confirmed-duplicate Zoffany DWZF-187385 (-1 dup-handle clone); keep DWZF-187037 live
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 .../today-audit-2026-06-21/zoffany-archive-dup.js  | 66 ++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/shopify/scripts/data/today-audit-2026-06-21/zoffany-archive-dup.js b/shopify/scripts/data/today-audit-2026-06-21/zoffany-archive-dup.js
new file mode 100644
index 00000000..09d17b19
--- /dev/null
+++ b/shopify/scripts/data/today-audit-2026-06-21/zoffany-archive-dup.js
@@ -0,0 +1,66 @@
+// Archive the confirmed-duplicate Zoffany product DWZF-187385 (the `-1` dup-handle clone).
+// KEEP DWZF-187037 (original, created first) live & untouched.
+// ARCHIVE ONLY — no delete, no merge, no touch to DWZF-187037 or any other product.
+// Canonical Shopify path/token reused from today-audit-2026-06-21 scripts.
+const https=require("https"),fs=require("fs"),os=require("os");
+const env=fs.readFileSync(os.homedir()+"/Projects/secrets-manager/.env","utf8");
+const TOKEN=(env.match(/^SHOPIFY_ADMIN_TOKEN=(.*)$/m)||[])[1].replace(/['"]/g,"").trim();
+const STORE="designer-laboratory-sandbox.myshopify.com",API="2024-10";
+const sleep=ms=>new Promise(r=>setTimeout(r,ms));
+function gql(q,v={}){return new Promise((res,rej)=>{const b=JSON.stringify({query:q,variables:v});
+const r=https.request({host:STORE,path:`/admin/api/${API}/graphql.json`,method:"POST",headers:{"Content-Type":"application/json","X-Shopify-Access-Token":TOKEN,"Content-Length":Buffer.byteLength(b)}},x=>{let d="";x.on("data",c=>d+=c);x.on("end",()=>{try{res(JSON.parse(d))}catch(e){rej(d)}})});r.on("error",rej);r.write(b);r.end();});}
+async function gqlR(q,v={},t=5){for(let i=0;i<t;i++){let r;try{r=await gql(q,v)}catch(e){r={errors:[{message:String(e).slice(0,120)}]}}if(r&&!r.errors)return r;await sleep(1500*(i+1));}return gql(q,v);}
+
+// HARD-PINNED targets (verified via zoffany-investigate.js before-state)
+const DUP={sku:"DWZF-187385",gid:"gid://shopify/Product/7865417760819",handle:"pompadour-print-indigo-wallcovering-zoffany-1"};
+const KEEP={sku:"DWZF-187037",gid:"gid://shopify/Product/7865417728051",handle:"pompadour-print-indigo-wallcovering-zoffany"};
+
+async function statusBySku(sku){
+ const q=`query($q:String!){productVariants(first:5,query:$q){nodes{sku product{id legacyResourceId handle title status vendor}}}}`;
+ const r=await gqlR(q,{q:`sku:${sku}`});
+ const vn=r.data?.productVariants?.nodes||[];
+ const m=vn.find(v=>v.sku===sku)||vn[0];
+ return m?m.product:null;
+}
+
+(async()=>{
+ // 1. Re-confirm before-state straight from Shopify
+ const dupBefore=await statusBySku(DUP.sku);
+ const keepBefore=await statusBySku(KEEP.sku);
+ if(!dupBefore){console.error("ABORT: DUP "+DUP.sku+" not found");process.exit(1);}
+ if(!keepBefore){console.error("ABORT: KEEP "+KEEP.sku+" not found");process.exit(1);}
+ // Safety pins: gid + handle must match exactly so we never archive the wrong product
+ if(dupBefore.id!==DUP.gid){console.error("ABORT: DUP gid mismatch "+dupBefore.id);process.exit(1);}
+ if(dupBefore.handle!==DUP.handle){console.error("ABORT: DUP handle mismatch "+dupBefore.handle);process.exit(1);}
+ if(keepBefore.id!==KEEP.gid){console.error("ABORT: KEEP gid mismatch "+keepBefore.id);process.exit(1);}
+
+ console.log("BEFORE:");
+ console.log("  DUP  "+DUP.sku+"  status="+dupBefore.status+"  handle="+dupBefore.handle+"  ("+dupBefore.id+")");
+ console.log("  KEEP "+KEEP.sku+"  status="+keepBefore.status+"  handle="+keepBefore.handle+"  ("+keepBefore.id+")");
+
+ // 2. Archive ONLY the duplicate
+ const m=`mutation($input:ProductInput!){productUpdate(input:$input){product{id status} userErrors{field message}}}`;
+ const r=await gqlR(m,{input:{id:DUP.gid,status:"ARCHIVED"}});
+ const ue=r.data?.productUpdate?.userErrors||[];
+ if(ue.length){console.error("ARCHIVE FAILED:",JSON.stringify(ue));process.exit(1);}
+ const archived=r.data?.productUpdate?.product;
+ console.log("\nMUTATION RESULT: "+DUP.sku+" -> "+archived?.status);
+
+ await sleep(1500);
+
+ // 3. Verify after-state from Shopify
+ const dupAfter=await statusBySku(DUP.sku);
+ const keepAfter=await statusBySku(KEEP.sku);
+ console.log("\nAFTER:");
+ console.log("  DUP  "+DUP.sku+"  status="+dupAfter.status+"  ("+dupAfter.id+")");
+ console.log("  KEEP "+KEEP.sku+"  status="+keepAfter.status+"  ("+keepAfter.id+")");
+
+ const ok = dupAfter.status==="ARCHIVED" && keepAfter.status==="ACTIVE";
+ console.log("\nVERIFY: "+(ok?"PASS":"FAIL")+" — DUP must be ARCHIVED & KEEP must be ACTIVE");
+
+ fs.writeFileSync("/tmp/zoffany-archive-dup-result.json",JSON.stringify({
+  before:{dup:{sku:DUP.sku,status:dupBefore.status},keep:{sku:KEEP.sku,status:keepBefore.status}},
+  after:{dup:{sku:DUP.sku,status:dupAfter.status},keep:{sku:KEEP.sku,status:keepAfter.status}},
+  verify:ok?"PASS":"FAIL",ts:new Date().toISOString()},null,2));
+ process.exit(ok?0:2);
+})();

← 54abca22 Zoffany title audit (2026-06-21): clean redundant colorway o  ·  back to Designer Wallcoverings  ·  Zoffany batch title normalization (2026-06-21): backtick->ap daa2dccb →