[object Object]

← back to Flock Fix Viewer

non-astek flock (c): house private-label flock specs for 8 ROP/ERE/PRNC (unverifiable MFR); reversible

258c4cf659fe2f6a557bb073206778396f384801 · 2026-09-02 14:54:25 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A8mCr1GHE1PGSWJd1yydnh

Files touched

Diff

commit 258c4cf659fe2f6a557bb073206778396f384801
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Sep 2 14:54:25 2026 -0700

    non-astek flock (c): house private-label flock specs for 8 ROP/ERE/PRNC (unverifiable MFR); reversible
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01A8mCr1GHE1PGSWJd1yydnh
---
 spec-privatelabel-flock-snapshot.json | 50 +++++++++++++++++++++++
 spec-privatelabel-flock.mjs           | 75 +++++++++++++++++++++++++++++++++++
 2 files changed, 125 insertions(+)

diff --git a/spec-privatelabel-flock-snapshot.json b/spec-privatelabel-flock-snapshot.json
new file mode 100644
index 0000000..8d8deff
--- /dev/null
+++ b/spec-privatelabel-flock-snapshot.json
@@ -0,0 +1,50 @@
+[
+ {
+  "id": "gid://shopify/Product/1496450334832",
+  "handle": "byzantium-flock-velvet-rop-73674",
+  "sku": "ROP-73674",
+  "oldWidth": "20.5\"x16.5'"
+ },
+ {
+  "id": "gid://shopify/Product/1497608421488",
+  "handle": "arc-de-triomphe-flock-wallpaper-ere-44505",
+  "sku": "ERE-44505",
+  "oldWidth": "20.5\" x 16.5'"
+ },
+ {
+  "id": "gid://shopify/Product/3928405508161",
+  "handle": "madame-belles-lace-flocked-velvet-prnc-26102",
+  "sku": "PRNC-26102",
+  "oldWidth": "20.5\" x 16.5' per single roll"
+ },
+ {
+  "id": "gid://shopify/Product/3928405835841",
+  "handle": "crystal-palace-saloon-lace-flocked-velvet-prnc-26130",
+  "sku": "PRNC-26130",
+  "oldWidth": "20.5\" x 16.5' per single roll"
+ },
+ {
+  "id": "gid://shopify/Product/3928407179329",
+  "handle": "lafayettes-ballroom-flocked-velvet-prnc-26701",
+  "sku": "PRNC-26701",
+  "oldWidth": "20.5\" x 16.5' per single roll"
+ },
+ {
+  "id": "gid://shopify/Product/6754522005555",
+  "handle": "copy-of-crystal-palace-saloon-lace-flocked-velvet-1",
+  "sku": "PRNC-11001",
+  "oldWidth": "20.5\" x 16.5' per single roll"
+ },
+ {
+  "id": "gid://shopify/Product/6754523349043",
+  "handle": "copy-of-crystal-palace-saloon-lace-flocked-velvet-2",
+  "sku": "PRNC-11008",
+  "oldWidth": "20.5\" x 16.5' per single roll"
+ },
+ {
+  "id": "gid://shopify/Product/6754524364851",
+  "handle": "copy-of-crystal-palace-saloon-lace-flocked-velvet-3",
+  "sku": "PRNC-48305",
+  "oldWidth": "20.5\" x 16.5' per single roll"
+ }
+]
\ No newline at end of file
diff --git a/spec-privatelabel-flock.mjs b/spec-privatelabel-flock.mjs
new file mode 100644
index 0000000..1bda3f4
--- /dev/null
+++ b/spec-privatelabel-flock.mjs
@@ -0,0 +1,75 @@
+// (c) House private-label defaults for ROP/ERE/PRNC flock (Phillipe Romano). Real MFR unverifiable
+// feed-side (absent from vendor_catalog/romo_catalog/clean staging) — Steve authorized house defaults.
+// American paper-backed flocked-velvet spec set + sqft from each product's OWN roll data. No per-pattern
+// repeat (unverified). No price. Reversible + ledgered + snapshot. --apply to write.
+import fs from 'fs'; import os from 'os'; import path from 'path';
+const SHOP='designer-laboratory-sandbox.myshopify.com';
+const TOKEN=fs.readFileSync(new URL('./.token',import.meta.url),'utf8').trim();
+const LEDGER=path.join(os.homedir(),'.claude/yolo-queue/executed-reversible/ledger.jsonl');
+const SNAP=new URL('./spec-privatelabel-flock-snapshot.json',import.meta.url);
+const DRY=!process.argv.includes('--apply');
+const API=`https://${SHOP}/admin/api/2024-10`;
+const H={'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json'};
+const sleep=ms=>new Promise(r=>setTimeout(r,ms));
+const gql=async(q,v={})=>(await (await fetch(`${API}/graphql.json`,{method:'POST',headers:H,body:JSON.stringify({query:q,variables:v})})).json());
+const MULTILINE=new Set(['custom.material','custom.google_product_category']);
+const typeFor=(ns,k)=>MULTILINE.has(ns+'.'+k)?'multi_line_text_field':'single_line_text_field';
+const r2=n=>Math.round(n*100)/100;
+const HOUSE=[ // [globalKey, customKey, value]
+  ['Match','match_type','Straight'],
+  ['application','application','Paste the Paper'],
+  ['Substrate','backing','Paper'],
+  ['removability','removal','Strippable'],
+  ['print_type','print_type','Flock'],
+  ['material','material','Flocked Velvet'],
+];
+// parse width_in + single-roll length_ft from strings like  20.5"x16.5'  |  20.5" x 16.5' per single roll
+function parseWL(s){ if(!s) return null;
+  const nums=(String(s).match(/[\d.]+/g)||[]).map(parseFloat);
+  if(nums.length<2) return null;
+  const [w,l]=nums;
+  if(!(w>=12&&w<=56)) return null;         // sane flock width in inches
+  if(!(l>=3&&l<=40)) return null;          // single-roll length in feet
+  return {wi:w, lenft:l};
+}
+(async()=>{
+  let cur=null,all=[];
+  const Q=`query($c:String){ products(first:100, query:"vendor:'Phillipe Romano' status:active", after:$c){ pageInfo{hasNextPage endCursor}
+    edges{node{ id handle title
+      variants(first:4){edges{node{sku title}}}
+      w:metafield(namespace:"global",key:"width"){value}
+      gpt:metafield(namespace:"global",key:"print_type"){value}
+    }}}}`;
+  do{const r=await gql(Q,{c:cur});const p=r?.data?.products;if(!p){console.error(JSON.stringify(r));break;}all=all.concat(p.edges);cur=p.pageInfo.hasNextPage?p.pageInfo.endCursor:null;}while(cur);
+  const rollSku=n=>{const v=n.variants.edges.map(e=>e.node).find(v=>!/sample/i.test(v.title||''))||n.variants.edges[0]?.node;return v?.sku||'';};
+  const targets=all.map(e=>e.node).filter(n=>/^(ROP|ERE|PRNC)-/i.test(rollSku(n)) && /flock/i.test(n.title));
+  console.log('active Phillipe Romano ROP/ERE/PRNC flock:',targets.length);
+  const snap=[]; let applied=0, skipped=[];
+  for(const n of targets){
+    const wl=parseWL(n.w?.value);
+    if(!wl){ skipped.push(`${rollSku(n)} bad-width "${n.w?.value}"`); continue; }
+    const sr=r2((wl.wi/12)*wl.lenft), dr=r2(sr*2);
+    const pairs=[
+      ['width',null,`${wl.wi} in`],
+      ['length',null,`${wl.lenft} ft (single roll)`],
+      ...HOUSE,
+      ['sqft_single_roll',null,sr+' Sq Ft'],['sqft_double_roll',null,dr+' Sq Ft'],
+    ];
+    if(DRY){ console.log(`  ${rollSku(n).padEnd(13)} W=${wl.wi}in L=${wl.lenft}ft SR=${sr} DR=${dr}  ${n.title.slice(0,40)}`); continue; }
+    const mf=[];
+    for(const [gk,ck,val] of pairs){ if(val==null) continue;
+      mf.push({ownerId:n.id,namespace:'global',key:gk,type:typeFor('global',gk),value:val});
+      if(ck) mf.push({ownerId:n.id,namespace:'custom',key:ck,type:typeFor('custom',ck),value:val});
+    }
+    mf.push({ownerId:n.id,namespace:'custom',key:'sqft_single_roll',type:'single_line_text_field',value:sr+' Sq Ft'});
+    mf.push({ownerId:n.id,namespace:'custom',key:'sqft_double_roll',type:'single_line_text_field',value:dr+' Sq Ft'});
+    const rr=await gql('mutation($mf:[MetafieldsSetInput!]!){metafieldsSet(metafields:$mf){userErrors{field message}}}',{mf});
+    const errs=rr?.data?.metafieldsSet?.userErrors; if(errs&&errs.length){console.log('  FAIL',n.handle,JSON.stringify(errs));continue;}
+    snap.push({id:n.id,handle:n.handle,sku:rollSku(n),oldWidth:n.w?.value||null});
+    fs.appendFileSync(LEDGER,JSON.stringify({ts:new Date().toISOString(),agent:'vp-dw-commerce:spec-pl-flock',ticket:'TK-11128',action:`house private-label flock specs (${rollSku(n)}: ${wl.wi}in x ${wl.lenft}ft single, paper flock paste-the-paper strippable, sqft; no per-pattern repeat) on ${n.handle}`,blast_radius:1,undo_cmd:`delete added spec metafields on ${n.id} (old width="${n.w?.value}")`,verify:'PDP shows flock spec set + sqft'})+'\n');
+    applied++; await sleep(220);
+  }
+  if(!DRY) fs.writeFileSync(SNAP,JSON.stringify(snap,null,1));
+  console.log(`${DRY?'DRY':'DONE'} applied=${applied} skipped=${skipped.length}`);
+  if(skipped.length) console.log('  SKIP:',skipped.join(' | '));
+})();

← 93a9bfd non-astek flock (b): verified specs to 29 real-brand flock (  ·  back to Flock Fix Viewer  ·  auto-data-snapshot: 2026-09-02T15:21:07 (1 data files) — sad 348c48a →