← back to Designer Wallcoverings
TWIL grasscloth: apply Jerry Boyas email pricing (cost*0.75/yd) to sheet + 47 Shopify variants; activate 12 leak-free, retitle 26, archive 11 dups (scripts read token from .env, no hardcoded secret)
1ee9aa14ee86a2311f0a800fe462271e108e6496 · 2026-06-24 14:49:30 -0700 · steve@designerwallcoverings.com
Files touched
A pending-approval/twil_golive2.pyA pending-approval/twil_price_update.pyA pending-approval/twil_prices.jsonA pending-approval/twil_sheet_price.pyM shopify/scripts/cadence/data/cadence-cursor.jsonM shopify/scripts/cadence/data/cadence-plan-pm-2026-06-24.jsonM shopify/scripts/cadence/data/upload-restore-2026-06-24.jsonl
Diff
commit 1ee9aa14ee86a2311f0a800fe462271e108e6496
Author: steve@designerwallcoverings.com <steve@designerwallcoverings.com>
Date: Wed Jun 24 14:49:30 2026 -0700
TWIL grasscloth: apply Jerry Boyas email pricing (cost*0.75/yd) to sheet + 47 Shopify variants; activate 12 leak-free, retitle 26, archive 11 dups (scripts read token from .env, no hardcoded secret)
---
pending-approval/twil_golive2.py | 146 ++++++++
pending-approval/twil_price_update.py | 150 ++++++++
pending-approval/twil_prices.json | 415 +++++++++++++++++++++
pending-approval/twil_sheet_price.py | 32 ++
shopify/scripts/cadence/data/cadence-cursor.json | 2 +-
.../cadence/data/cadence-plan-pm-2026-06-24.json | 210 +++++------
.../cadence/data/upload-restore-2026-06-24.jsonl | 10 +
7 files changed, 859 insertions(+), 106 deletions(-)
diff --git a/pending-approval/twil_golive2.py b/pending-approval/twil_golive2.py
new file mode 100644
index 00000000..4e5ce27c
--- /dev/null
+++ b/pending-approval/twil_golive2.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python3
+"""TWIL grasscloth go-live v2 (Steve-approved: clean 9 + name/enrich/activate rest, leak-free).
+ KEEPER -> activate+publish. DUP/leaky-twin -> archive.
+ RAW-ONLY '| TWIL' -> retitle 'Fentucci {Material} Grasscloth Wallcovering{ — Color}',
+ vendor=Fentucci, enrich (width/length/desc/color/img from sheet), then ACTIVATE iff has image+width; else DRAFT+Needs-Image.
+ DRY default; CONFIRM=1 executes."""
+import os,sys,json,time,re,urllib.request
+import gspread
+from collections import defaultdict
+SHOP="designer-laboratory-sandbox.myshopify.com";API="2024-10"
+DRY=os.environ.get("CONFIRM","0")!="1"
+TOKEN=os.environ.get("SHOPIFY_ADMIN_TOKEN","")
+if not TOKEN:
+ for l in open(os.path.expanduser("~/Projects/secrets-manager/.env")):
+ if l.startswith("SHOPIFY_ADMIN_TOKEN="): TOKEN=l.strip().split("=",1)[1];break
+BASE=f"https://{SHOP}/admin/api/{API}";H={"X-Shopify-Access-Token":TOKEN,"Content-Type":"application/json"}
+def api(m,p,pl=None):
+ d=json.dumps(pl).encode() if pl is not None else None
+ r=urllib.request.Request(BASE+p,data=d,headers=H,method=m)
+ with urllib.request.urlopen(r,timeout=60) as x: return x.status,json.loads(x.read().decode())
+def gql(q,v=None): return api("POST","/graphql.json",{"query":q,"variables":v or {}})[1]
+def norm(s): return (s or "").strip().upper().rstrip("T")
+def tc(s): return " ".join(w[:1].upper()+w[1:].lower() if w else w for w in (s or "").split())
+
+MATS=[("HERRINGBONE","Herringbone"),("SMALL DIAMOND","Small Diamond"),("PANAMA","Panama Weave"),
+("PAPERWEAVE","Paperweave"),("PAPERWEAV","Paperweave"),("BURLAP","Burlap"),("RAW JUT","Jute"),("JUTE","Jute"),
+("RAFFIA","Raffia"),("ABACA","Abaca"),("ARROWROOT","Arrowroot"),("GRANITE QUARTZ","Mica"),("MICA","Mica"),
+("HALEY HEMP","Hemp"),("HEMP","Hemp"),("CORK","Cork"),("BOODLE","Boodle"),("TRIANGLE GRASS","Triangle Grass"),("SISAL","Sisal")]
+jraw=json.load(open("/tmp/twil_prices.json"))
+def material(n):
+ for x in jraw:
+ if norm(x["code"])==n:
+ blob=(x.get("desc","")+" "+x.get("long","")).upper()
+ for kw,lab in MATS:
+ if kw in blob: return lab
+ return ""
+PRICE={norm(x["code"]):round(x["list_per_sr"]*0.75,2) for x in jraw if x["list_per_sr"] is not None}
+
+# sheet enrichment
+SA="/Users/stevestudio2/Projects/secrets-manager/gmc-sa-146735262.json"
+gc=gspread.service_account(filename=SA);ws=gc.open_by_key("1trKNm-ymqlbs96XJfndDUz19mzH8A11ktaw2lfQ2VQo").sheet1
+vals=ws.get_all_values();SH=defaultdict(dict)
+def norm_w(v):
+ v=(v or '').strip().lower().replace('"',' inches').replace('inches','Inches')
+ return tc(v) if v else ''
+for r in vals[1:]:
+ b=(r[1] or '').strip()
+ if not b: continue
+ n=norm(b);c=SH[n]
+ def g(i): return (r[i] or '').strip() if len(r)>i else ''
+ for k,i in [('img1',6),('img2',7),('alt',8),('desc',9),('color',10),('width',15),('length',16)]:
+ if g(i) and not c.get(k): c[k]=g(i)
+ SH[n]=c
+
+# pull products
+Q="""query($c:String){products(first:100,query:"vendor:Fentucci",after:$c){pageInfo{hasNextPage endCursor}
+ edges{node{id legacyResourceId title status
+ img:images(first:1){edges{node{id}}}
+ w:metafield(namespace:"global",key:"width"){value} w2:metafield(namespace:"custom",key:"width"){value}
+ mf:metafield(namespace:"custom",key:"manufacturer_sku"){value} mf2:metafield(namespace:"dwc",key:"manufacturer_sku"){value}}}}}"""
+prods=[];c=None
+while True:
+ d=gql(Q,{"c":c}).get("data",{}).get("products",{})
+ for e in d["edges"]: prods.append(e["node"])
+ if d["pageInfo"]["hasNextPage"]: c=d["pageInfo"]["endCursor"]
+ else: break
+grp=defaultdict(list)
+for p in prods:
+ mfr=(p.get("mf") or {}).get("value") or (p.get("mf2") or {}).get("value") or ""
+ n=norm(mfr)
+ if n not in PRICE: continue
+ p["_n"]=n;p["_mfr"]=mfr;p["_leak"]="| TWIL" in p["title"]
+ p["_named"]=("| Fentucci" in p["title"]) and not re.match(rf"^{re.escape(n)}T?\b",p["title"].upper())
+ p["_img"]=len(p["img"]["edges"])>0
+ p["_width"]=bool((p.get("w") or {}).get("value") or (p.get("w2") or {}).get("value"))
+ grp[n].append(p)
+
+acts=[];arch=[];retitle=[]
+for n,ps in grp.items():
+ keepers=[p for p in ps if p["_named"] or p["status"]=="ACTIVE"]
+ if keepers:
+ keepers.sort(key=lambda z:(z["status"]!="ACTIVE",-len(z["title"])))
+ keep=keepers[0]
+ for p in ps:
+ if p is keep:
+ if keep["status"]!="ACTIVE": acts.append(keep)
+ else: arch.append(p)
+ else:
+ ps.sort(key=lambda z:(not z["_img"],not z["_width"]))
+ retitle.append(ps[0]); arch.extend(ps[1:])
+
+def newtitle(p):
+ mat=material(p["_n"]);col=tc(SH[p["_n"]].get("color",""))
+ return re.sub(r"\s+"," ",f"Fentucci {mat+' ' if mat else ''}Grasscloth Wallcovering{(' — '+col) if col else ''}").strip()
+
+print("=== GO-LIVE PLAN v2 ===")
+print(f"ACTIVATE clean keepers: {len(acts)}")
+for p in acts: print(f" {p['_mfr']:>9} {p['title'][:48]}")
+print(f"\nRETITLE+ENRICH raw-only: {len(retitle)}")
+will_act=0
+for p in retitle:
+ s=SH[p["_n"]];img= '1' if s.get('img1') else '0'
+ gate = bool(s.get('img1')) and bool(s.get('width') or True)
+ if gate: will_act+=1
+ print(f" {p['_mfr']:>9} -> {newtitle(p)[:52]:52} img={img} w={'Y' if s.get('width') else '-'} desc={'Y' if s.get('desc') else '-'} -> {'ACTIVATE' if gate else 'DRAFT/Needs-Image'}")
+print(f" (of {len(retitle)} raw: {will_act} will ACTIVATE, {len(retitle)-will_act} stay DRAFT Needs-Image)")
+print(f"\nARCHIVE dups/leaky twins: {len(arch)}")
+for p in arch: print(f" {p['_mfr']:>9} [{p['status']}] {p['title'][:46]}")
+
+if DRY:
+ print("\n[DRY] CONFIRM=1 to execute."); sys.exit()
+
+# ---- EXECUTE ----
+PUBS=[e["node"]["id"] for e in gql("{publications(first:50){edges{node{id name}}}}").get("data",{}).get("publications",{}).get("edges",[])]
+def publish(pid):
+ return gql("""mutation($id:ID!,$in:[PublicationInput!]!){publishablePublish(id:$id,input:$in){userErrors{message}}}""",
+ {"id":f"gid://shopify/Product/{pid}","in":[{"publicationId":x} for x in PUBS]}).get("data",{}).get("publishablePublish",{}).get("userErrors",[])
+def set_mf(pid,ns,key,val):
+ if not val: return
+ api("POST",f"/products/{pid}/metafields.json",{"metafield":{"namespace":ns,"key":key,"type":"single_line_text_field","value":str(val)}})
+na=nr=nact=nar=0
+for p in acts:
+ api("PUT",f"/products/{p['legacyResourceId']}.json",{"product":{"id":p['legacyResourceId'],"status":"active"}})
+ publish(p['legacyResourceId']);na+=1;print(f" activated {p['_mfr']}");time.sleep(0.4)
+for p in retitle:
+ pid=p['legacyResourceId'];s=SH[p["_n"]];nt=newtitle(p);col=tc(s.get("color",""))
+ imgs=[{"src":u} for u in [s.get('img1'),s.get('img2')] if u]
+ width=norm_w(s.get('width')) or "36 Inches"; length=tc(s.get('length','')) or "8 Yards"
+ tags=["Grasscloth","Natural Wallcovering","Fentucci","TWIL Naturals","display_variant"]
+ gate=bool(imgs)
+ if not gate: tags.append("Needs-Image")
+ if col: tags.append(f"color:{col}")
+ prod={"id":pid,"title":nt,"vendor":"Fentucci","tags":", ".join(tags)}
+ if s.get('desc'): prod["body_html"]=s['desc']
+ if imgs: prod["images"]=imgs
+ if gate: prod["status"]="active"
+ api("PUT",f"/products/{pid}.json",{"product":prod})
+ set_mf(pid,"global","width",width); set_mf(pid,"global","length",length)
+ if col: set_mf(pid,"custom","color",col); set_mf(pid,"global","Color-Way",col)
+ set_mf(pid,"custom","manufacturer_sku",p["_mfr"]); set_mf(pid,"dwc","manufacturer_sku",p["_mfr"])
+ if gate: publish(pid); nact+=1
+ nr+=1;print(f" retitled {p['_mfr']} -> {nt} {'ACTIVE' if gate else 'DRAFT(Needs-Image)'}");time.sleep(0.5)
+for p in arch:
+ api("PUT",f"/products/{p['legacyResourceId']}.json",{"product":{"id":p['legacyResourceId'],"status":"archived"}})
+ nar+=1;print(f" archived {p['_mfr']} ({p['title'][:28]})");time.sleep(0.3)
+print(f"\nDONE — keepers activated {na}, retitled {nr} (of which activated {nact}), archived {nar}")
diff --git a/pending-approval/twil_price_update.py b/pending-approval/twil_price_update.py
new file mode 100644
index 00000000..d9ccdd20
--- /dev/null
+++ b/pending-approval/twil_price_update.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python3
+"""
+twil_price_update.py — apply TWIL vendor email pricing (Jerry Boyas STOCK INFO.xlsx)
+to all Fentucci grasscloth products on Shopify + the TWIL PRices sheet.
+
+Pricing chain (verified against sheet's own existing rows):
+ vendor "List price PER SR" == column C (cost per single roll / 8yd bolt)
+ Cost/yd (L) = cost / 4
+ DW Price (O, sell per yd) = (cost/4)*3 = cost * 0.75 <- the DW retail used at burst
+
+DRY (default): read Shopify + sheet, print plan, no writes.
+CONFIRM=1 : write variant prices, activate priced drafts, update sheet.
+"""
+import os, sys, json, time, urllib.request, urllib.parse
+
+SHOP="designer-laboratory-sandbox.myshopify.com"; API="2024-10"
+DRY = os.environ.get("CONFIRM","0") != "1"
+TOKEN=os.environ.get("SHOPIFY_ADMIN_TOKEN","")
+if not TOKEN:
+ for line in open(os.path.expanduser("~/Projects/secrets-manager/.env")):
+ if line.startswith("SHOPIFY_ADMIN_TOKEN="):
+ TOKEN=line.strip().split("=",1)[1]; break
+assert TOKEN, "no SHOPIFY_ADMIN_TOKEN"
+BASE=f"https://{SHOP}/admin/api/{API}"
+H={"X-Shopify-Access-Token":TOKEN,"Content-Type":"application/json"}
+
+def api(method, path, payload=None):
+ data=json.dumps(payload).encode() if payload is not None else None
+ req=urllib.request.Request(BASE+path, data=data, headers=H, method=method)
+ with urllib.request.urlopen(req, timeout=60) as r:
+ return r.status, json.loads(r.read().decode())
+
+def graphql(query, variables=None):
+ st,res=api("POST","/graphql.json",{"query":query,"variables":variables or {}})
+ return res
+
+# ---- Jerry price map ----
+def norm(s): return (s or "").strip().upper().rstrip("T")
+jerry_raw=json.load(open("/tmp/twil_prices.json"))
+PRICE={} # norm(mfr) -> dw_price
+COST={}
+for x in jerry_raw:
+ c=x["list_per_sr"]
+ if c is None: continue
+ dw=round(c*0.75,2)
+ PRICE[norm(x["code"])]=dw
+ COST[norm(x["code"])]=c
+
+# ---- pull all Fentucci products via GraphQL (paginated) ----
+Q="""
+query($cursor:String){
+ products(first:100, query:"vendor:Fentucci", after:$cursor){
+ pageInfo{hasNextPage endCursor}
+ edges{node{
+ id legacyResourceId title status
+ mfr: metafield(namespace:"custom", key:"manufacturer_sku"){value}
+ mfr2: metafield(namespace:"dwc", key:"manufacturer_sku"){value}
+ variants(first:10){edges{node{ id legacyResourceId title sku price }}}
+ }}
+ }
+}"""
+prods=[]; cursor=None
+while True:
+ res=graphql(Q,{"cursor":cursor})
+ d=res.get("data",{}).get("products",{})
+ if not d:
+ print("GRAPHQL ERR:", json.dumps(res)[:500]); sys.exit(1)
+ for e in d["edges"]: prods.append(e["node"])
+ if d["pageInfo"]["hasNextPage"]: cursor=d["pageInfo"]["endCursor"]
+ else: break
+
+print(f"Fentucci products on Shopify: {len(prods)}")
+print(f"Jerry priced SKUs: {len(PRICE)}\n")
+
+plan=[] # (variant_id, new_price, old_price, product_id, status, mfr, title, action)
+unmatched=[]
+for p in prods:
+ mfr = (p.get("mfr") or {}).get("value") or (p.get("mfr2") or {}).get("value") or ""
+ n=norm(mfr)
+ dw=PRICE.get(n)
+ # find Roll variant (option1 Roll => title 'Roll'); sample is the -Sample sku
+ roll=None
+ for ve in p["variants"]["edges"]:
+ v=ve["node"]
+ if (v.get("title") or "").lower()=="roll" or (v.get("sku","") and not v["sku"].endswith("-Sample") and "Sample" not in (v.get("title") or "")):
+ roll=v; break
+ if roll is None and p["variants"]["edges"]:
+ roll=p["variants"]["edges"][0]["node"]
+ if dw is None:
+ unmatched.append((mfr, p["title"], p["status"]))
+ continue
+ old=roll["price"]
+ pid=p["legacyResourceId"]
+ vid=roll["legacyResourceId"]
+ needs_price = (str(old) != str(dw))
+ needs_activate = (p["status"]!="ACTIVE")
+ action=[]
+ if needs_price: action.append(f"price {old}->{dw}")
+ if needs_activate: action.append("ACTIVATE")
+ if not action: action.append("ok")
+ plan.append({"vid":vid,"pid":pid,"new":dw,"old":old,"status":p["status"],
+ "mfr":mfr,"title":p["title"],"action":", ".join(action),
+ "needs_price":needs_price,"needs_activate":needs_activate})
+
+# report
+chg=[x for x in plan if x["needs_price"] or x["needs_activate"]]
+print(f"=== {len(plan)} matched | {len(chg)} need change | {len(unmatched)} unmatched ===\n")
+for x in sorted(plan,key=lambda z:z["action"]):
+ print(f" {x['mfr']:>10} {x['status']:7} ${str(x['old']):>7} -> ${x['new']:<7} [{x['action']}] {x['title'][:42]}")
+if unmatched:
+ print(f"\n--- {len(unmatched)} Fentucci products NOT in Jerry's price list ---")
+ for m,t,s in unmatched: print(f" {m:>10} {s:7} {t[:50]}")
+
+json.dump(plan, open("/tmp/twil_update_plan.json","w"), indent=2)
+print(f"\nplan -> /tmp/twil_update_plan.json")
+
+if DRY:
+ print("\n[DRY-RUN] no writes. Re-run with CONFIRM=1 to apply.")
+ sys.exit(0)
+
+# ---- EXECUTE ----
+print("\n=== APPLYING ===")
+def all_pubs():
+ res=graphql("{ publications(first:50){edges{node{id name}}} }")
+ return [e["node"]["id"] for e in res.get("data",{}).get("publications",{}).get("edges",[])]
+PUBS=all_pubs()
+def publish(pid):
+ gid=f"gid://shopify/Product/{pid}"
+ q="""mutation pub($id:ID!,$input:[PublicationInput!]!){ publishablePublish(id:$id,input:$input){ userErrors{message} } }"""
+ res=graphql(q,{"id":gid,"input":[{"publicationId":x} for x in PUBS]})
+ return res.get("data",{}).get("publishablePublish",{}).get("userErrors",[])
+
+PRICE_ONLY = os.environ.get("PRICE_ONLY","0")=="1"
+npx=nac=0
+for x in chg:
+ try:
+ if x["needs_price"]:
+ api("PUT", f"/variants/{x['vid']}.json", {"variant":{"id":x["vid"],"price":str(x["new"])}})
+ npx+=1
+ if x["needs_activate"] and not PRICE_ONLY:
+ api("PUT", f"/products/{x['pid']}.json", {"product":{"id":x["pid"],"status":"active"}})
+ errs=publish(x["pid"])
+ nac+=1
+ if errs: print(f" pub err {x['mfr']}: {errs}")
+ print(f" done {x['mfr']:>10} -> ${x['new']} {'ACTIVE' if (x['needs_activate'] and not PRICE_ONLY) else '(draft)'}")
+ time.sleep(0.4)
+ except Exception as e:
+ body=getattr(e,'read',lambda:b'')() if hasattr(e,'read') else b''
+ print(f" ERR {x['mfr']}: {e} {body[:200]}")
+print(f"\nDONE — prices updated: {npx}, activated: {nac}")
diff --git a/pending-approval/twil_prices.json b/pending-approval/twil_prices.json
new file mode 100644
index 00000000..c0e75ee5
--- /dev/null
+++ b/pending-approval/twil_prices.json
@@ -0,0 +1,415 @@
+[
+ {
+ "code": "75085W-01",
+ "desc": "HALEY HEMP",
+ "long": "8 YARD BOLT (RD2510)",
+ "list_per_sr": 63.4,
+ "qoh": 48
+ },
+ {
+ "code": "BA227",
+ "desc": "PAPERWEAVE",
+ "long": "48 YD REEL (S2655)",
+ "list_per_sr": 49.8,
+ "qoh": 138
+ },
+ {
+ "code": "BA454",
+ "desc": "REG. ARROWROOT",
+ "long": "ARROWROOT 8 YARD BOLY",
+ "list_per_sr": 47.0,
+ "qoh": 66
+ },
+ {
+ "code": "C3529T",
+ "desc": "CLASSIC ORIENTAL",
+ "long": "RESOURCE/DBLS 36WD X 4YDS",
+ "list_per_sr": 48.6,
+ "qoh": 0
+ },
+ {
+ "code": "C4539T",
+ "desc": "PAPERWEAVE",
+ "long": "PAPERWEAVE",
+ "list_per_sr": 47.6,
+ "qoh": 108
+ },
+ {
+ "code": "EG501",
+ "desc": "ARROWROOT",
+ "long": "8 YARD BOLT (T7502)(3)",
+ "list_per_sr": 67.2,
+ "qoh": 18
+ },
+ {
+ "code": "MD5056T",
+ "desc": "RAW JUTE",
+ "long": "RAW JUT 8 YARD BOLT",
+ "list_per_sr": 43.8,
+ "qoh": 18
+ },
+ {
+ "code": "MG2012",
+ "desc": "ABACA REGULAR",
+ "long": "ABACA REGULAR WEAVE PRINTED PAPER(ZZ01A)",
+ "list_per_sr": 71.8,
+ "qoh": 78
+ },
+ {
+ "code": "MG2013",
+ "desc": "PAPERWEAVE(15PW517A)",
+ "long": "PAPERWEAVE(15PW517A)(90%PAPER8.5%RAYON1.5%JUTE)",
+ "list_per_sr": 42.6,
+ "qoh": 98
+ },
+ {
+ "code": "MC1717",
+ "desc": "JUTE",
+ "long": "JUTE",
+ "list_per_sr": 50.2,
+ "qoh": 24
+ },
+ {
+ "code": "MG2013",
+ "desc": "PAPERWEAV",
+ "long": "PAPERWEAVE 8 YARD BOLT",
+ "list_per_sr": 42.6,
+ "qoh": 98
+ },
+ {
+ "code": "MG2020",
+ "desc": "RAFFIA (100% RAFFIA(15GC309A)",
+ "long": "RAFFIA (100% RAFFIA(15GC309A)",
+ "list_per_sr": 71.8,
+ "qoh": 372
+ },
+ {
+ "code": "MG2021",
+ "desc": "RAFFIA (100%)(15GC309B)",
+ "long": "RAFFIA (100%)(15GC309B)",
+ "list_per_sr": 71.8,
+ "qoh": 16
+ },
+ {
+ "code": "WNR1213",
+ "desc": "ABACA W/NYLON WARP",
+ "long": "8 YARD BOLT",
+ "list_per_sr": 92.6,
+ "qoh": 104
+ },
+ {
+ "code": "WNR2122",
+ "desc": "RAFFIA",
+ "long": "8 YARD BOLT",
+ "list_per_sr": 65.0,
+ "qoh": 4
+ },
+ {
+ "code": "NAT4018",
+ "desc": "SISAL",
+ "long": "8 YARD BOLT (A0159)",
+ "list_per_sr": 43.8,
+ "qoh": 18
+ },
+ {
+ "code": "SG6013",
+ "desc": "ABACA",
+ "long": "8 YARD BOLT",
+ "list_per_sr": 90.8,
+ "qoh": 40
+ },
+ {
+ "code": "SG6109",
+ "desc": "TRIANGLE GRASS on METALLIC BACKING",
+ "long": "TRIANGLE GRASS on METALLIC BACKING (RD3357)",
+ "list_per_sr": 45.4,
+ "qoh": 0
+ },
+ {
+ "code": "SH1518T",
+ "desc": "BURLAP",
+ "long": "8 YARD BOLT (8) BURLAP",
+ "list_per_sr": 51.4,
+ "qoh": 268
+ },
+ {
+ "code": "SH1519T",
+ "desc": "BURLAP",
+ "long": "8 YARD BOLT (8) BURLAP(RSP204)",
+ "list_per_sr": 51.4,
+ "qoh": 118
+ },
+ {
+ "code": "SH1521T",
+ "desc": "BURLAP",
+ "long": "8 YARD BOLT BURLAP (8)(RSP201)",
+ "list_per_sr": 51.4,
+ "qoh": 90
+ },
+ {
+ "code": "SH5059T",
+ "desc": "REGULAR WEAVE SISAL",
+ "long": "8 YARD BOLT (08-01-416)(3)",
+ "list_per_sr": 43.8,
+ "qoh": 142
+ },
+ {
+ "code": "TSJ4785",
+ "desc": "JAPANESE PAPERWEAVE (SK-4784)",
+ "long": "12 YD BOLT JAPANESE PAPERWEAVE",
+ "list_per_sr": 73.2,
+ "qoh": 51
+ },
+ {
+ "code": "TSJ7553",
+ "desc": "JAPANESE PAPERWV (SK-4784)",
+ "long": "JAPANESE PAPERWV 12 YD BOLT",
+ "list_per_sr": 73.2,
+ "qoh": 6
+ },
+ {
+ "code": "TW68102",
+ "desc": "TWIL",
+ "long": "PAPERWEAVE 8 YARD BOLT SISAL (20047A)",
+ "list_per_sr": 43.8,
+ "qoh": 96
+ },
+ {
+ "code": "WL332T",
+ "desc": "PAPERWEAVE",
+ "long": "PAPERWEAVE 8 YARD BOLT SISAL",
+ "list_per_sr": 51.8,
+ "qoh": 6
+ },
+ {
+ "code": "WNR1150",
+ "desc": "PANAMA WEAVE-CHECKMATE",
+ "long": "PAPER + SILK, METALLIC BACKING (201612-BX117)",
+ "list_per_sr": 50.2,
+ "qoh": 70
+ },
+ {
+ "code": "WNR1161",
+ "desc": "PANAMA WEAVE-BARLEY - PAPERWEAVE",
+ "long": "PAPERWEAVE (G3760) (YM)",
+ "list_per_sr": 46.4,
+ "qoh": 40
+ },
+ {
+ "code": "WNR1164",
+ "desc": "SEVILLE-GUNMETAL",
+ "long": "CORK ON METALLIC BACKING (15CK1001A/3906)",
+ "list_per_sr": 58.6,
+ "qoh": 174
+ },
+ {
+ "code": "WNR2097",
+ "desc": "97% PAPER & 3% VISCOSE RAYON",
+ "long": "97% PAPER & 3% VISCOSE RAYON 8 YARD BOLT",
+ "list_per_sr": 49.6,
+ "qoh": 58
+ },
+ {
+ "code": "WNR2111",
+ "desc": "RAFFIA GRASS AND PAPER",
+ "long": "RAFFIA GRASS AND PAPER (SY19012-9XB)",
+ "list_per_sr": 65.0,
+ "qoh": 0
+ },
+ {
+ "code": "WNR2116",
+ "desc": "97% PAPER & 3% VISCOSE RAYON",
+ "long": "97% PAPER & 3% VISCOSE RAYON (PW302B)",
+ "list_per_sr": 49.6,
+ "qoh": 172
+ },
+ {
+ "code": "WNR2122",
+ "desc": "RAFFIA GRASS AND PAPER",
+ "long": "RAFFIA GRASS AND PAPER ( SY19012-30XB)",
+ "list_per_sr": 65.0,
+ "qoh": 6
+ },
+ {
+ "code": "WOS3466",
+ "desc": "PAPERWEAVE",
+ "long": "8 YARD BOLT (G3071)",
+ "list_per_sr": 47.8,
+ "qoh": 132
+ },
+ {
+ "code": "WOS3467",
+ "desc": "BOODLE & JUTE",
+ "long": "8 YARD BOLT (DZ892)",
+ "list_per_sr": 32.0,
+ "qoh": 12
+ },
+ {
+ "code": "WOS3471",
+ "desc": "BOODLE",
+ "long": "8 YARD BOLT (DZ901)",
+ "list_per_sr": 35.0,
+ "qoh": 114
+ },
+ {
+ "code": "WOS3475",
+ "desc": "PAPERWEAVE",
+ "long": "8 YARD BOLT (G3070)",
+ "list_per_sr": 47.8,
+ "qoh": 132
+ },
+ {
+ "code": "WS4701T",
+ "desc": "R/W SISAL DOUBLE DYE",
+ "long": "W/DYE THREAD (8YDS) (08-01AR-024)(3)",
+ "list_per_sr": 50.4,
+ "qoh": 0
+ },
+ {
+ "code": "WS4723T",
+ "desc": "PAPERWEAVE",
+ "long": "8 YARD BOLTS (S2417)(4)RSP218",
+ "list_per_sr": 51.8,
+ "qoh": 128
+ },
+ {
+ "code": "WS5030",
+ "desc": "WINDSONG BURLAP",
+ "long": "8 YARD BOLT (19BL504A)",
+ "list_per_sr": 51.4,
+ "qoh": 122
+ },
+ {
+ "code": "WS5040",
+ "desc": "WINDSONG SISAL",
+ "long": "8 YARD BOLT (2018-401-LX)",
+ "list_per_sr": 43.8,
+ "qoh": 200
+ },
+ {
+ "code": "WS5043",
+ "desc": "WINDSONG SISAL",
+ "long": "8 YARD BOLT (2018-400-LX)",
+ "list_per_sr": 43.8,
+ "qoh": 122
+ },
+ {
+ "code": "WS5115",
+ "desc": "WINDSONG SISAL",
+ "long": "8 YARD BOLT (2018-403-LX)",
+ "list_per_sr": 43.8,
+ "qoh": 36
+ },
+ {
+ "code": "WS5126",
+ "desc": "WINDSONG SISAL",
+ "long": "8 YARD BOLT (WT2018-136)",
+ "list_per_sr": 43.8,
+ "qoh": 38
+ },
+ {
+ "code": "WS4748T",
+ "desc": "PAPERWEAVE",
+ "long": "8 YARD BOLT",
+ "list_per_sr": 44.4,
+ "qoh": 54
+ },
+ {
+ "code": "ZG1156",
+ "desc": "PAPERWEAVE",
+ "long": "8 YARD BOLT (11PW019A)",
+ "list_per_sr": 44.2,
+ "qoh": 150
+ },
+ {
+ "code": "ZG1502",
+ "desc": "GRANITE QUARTZ - MICA",
+ "long": "MICA (8222)",
+ "list_per_sr": 55.8,
+ "qoh": 46
+ },
+ {
+ "code": "ZG1530",
+ "desc": "POWDER BLUE - ABACA",
+ "long": "PEARL PRINT (RD2754)",
+ "list_per_sr": 81.6,
+ "qoh": 52
+ },
+ {
+ "code": "ZG1535",
+ "desc": "WINDSOR HAZE -",
+ "long": "SISAL PEARL POWDER (2015-LX-515-11)",
+ "list_per_sr": 52.8,
+ "qoh": 58
+ },
+ {
+ "code": "ZG1537",
+ "desc": "SHADOW BLUE - ABACA W/PEARL PRINTED PAPER",
+ "long": "ABACA (RD2777)",
+ "list_per_sr": 73.2,
+ "qoh": 0
+ },
+ {
+ "code": "WP7572",
+ "desc": "",
+ "long": "HERRINGBONE 8 YARD BOLT (8) (24PW0420G)",
+ "list_per_sr": 47.2,
+ "qoh": 116
+ },
+ {
+ "code": "WP7573",
+ "desc": "",
+ "long": "HERRINGBONE 8 YARD BOLT (8) (24PW0420A)",
+ "list_per_sr": 47.2,
+ "qoh": 174
+ },
+ {
+ "code": "WP7574",
+ "desc": "",
+ "long": "HERRINGBONE 8 YARD BOLT (8) (24PW0420E)",
+ "list_per_sr": 47.2,
+ "qoh": 172
+ },
+ {
+ "code": "WP7577",
+ "desc": "",
+ "long": "HERRINGBONE 8 YARD BOLT (8) (24PW0420D)",
+ "list_per_sr": 47.2,
+ "qoh": 80
+ },
+ {
+ "code": "WP7583",
+ "desc": "",
+ "long": "SMALL DIAMOND 8 YARD BOLT (8) (24PW0419B)",
+ "list_per_sr": 47.2,
+ "qoh": 110
+ },
+ {
+ "code": "WP7584",
+ "desc": "",
+ "long": "SMALL DIAMOND 8 YARD BOLT (8) (24PW0419E)",
+ "list_per_sr": 47.2,
+ "qoh": 82
+ },
+ {
+ "code": "WP7585",
+ "desc": "",
+ "long": "SMALL DIAMOND 8 YARD BOLT (8) (24PW0419H)",
+ "list_per_sr": 47.2,
+ "qoh": 126
+ },
+ {
+ "code": "WP7586",
+ "desc": "",
+ "long": "SMALL DIAMOND 8 YARD BOLT (8) (24PW0419C)",
+ "list_per_sr": 47.2,
+ "qoh": 88
+ },
+ {
+ "code": "WP7587",
+ "desc": "",
+ "long": "SMALL DIAMOND 8 YARD BOLT (8) (24PW0418C)",
+ "list_per_sr": 47.2,
+ "qoh": 106
+ }
+]
\ No newline at end of file
diff --git a/pending-approval/twil_sheet_price.py b/pending-approval/twil_sheet_price.py
new file mode 100644
index 00000000..d3cab848
--- /dev/null
+++ b/pending-approval/twil_sheet_price.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+"""Write TWIL email pricing into the TWIL PRices sheet for all 57 Jerry SKUs.
+ C (cost)=Jerry list_per_sr ; L (cost/yd)=cost/4 ; O (DW Price)=cost*0.75.
+ Only touches rows whose B(mfr) matches a Jerry SKU. DRY default; CONFIRM=1 writes."""
+import os, json, gspread
+SA="/Users/stevestudio2/Projects/secrets-manager/gmc-sa-146735262.json"
+KEY="1trKNm-ymqlbs96XJfndDUz19mzH8A11ktaw2lfQ2VQo"
+DRY=os.environ.get("CONFIRM","0")!="1"
+def norm(s): return (s or "").strip().upper().rstrip("T")
+jerry={norm(x['code']):x['list_per_sr'] for x in json.load(open('/tmp/twil_prices.json')) if x['list_per_sr'] is not None}
+gc=gspread.service_account(filename=SA); ws=gc.open_by_key(KEY).sheet1
+vals=ws.get_all_values()
+updates=[]; rows_changed=0
+for i,r in enumerate(vals[1:],start=2):
+ b=(r[1] or '').strip()
+ if not b: continue
+ c=jerry.get(norm(b))
+ if c is None: continue
+ cost=round(c,2); cyd=round(c/4,2); dw=round(c*0.75,2)
+ old=( (r[2] or '').strip(), (r[11] or '').strip() if len(r)>11 else '', (r[14] or '').strip() if len(r)>14 else '' )
+ if (old[0],old[2])==(f"{cost}",f"{dw}"):
+ pass
+ updates.append({'range':f'C{i}','values':[[cost]]})
+ updates.append({'range':f'L{i}','values':[[cyd]]})
+ updates.append({'range':f'O{i}','values':[[dw]]})
+ rows_changed+=1
+ print(f" row {i:>3} {b:>10} C {old[0]or'∅':>7}->{cost:<7} L->{cyd:<7} O {old[2]or'∅':>7}->{dw}")
+print(f"\n{rows_changed} sheet rows to write ({len(updates)} cells)")
+if DRY:
+ print("[DRY] no write. CONFIRM=1 to apply."); raise SystemExit
+ws.batch_update(updates, value_input_option='USER_ENTERED')
+print("WROTE.")
diff --git a/shopify/scripts/cadence/data/cadence-cursor.json b/shopify/scripts/cadence/data/cadence-cursor.json
index 1df8e397..52400e4b 100644
--- a/shopify/scripts/cadence/data/cadence-cursor.json
+++ b/shopify/scripts/cadence/data/cadence-cursor.json
@@ -1,5 +1,5 @@
{
- "idx": 5,
+ "idx": 11,
"lastSlot": "pm",
"lastRun": "2026-06-24"
}
\ No newline at end of file
diff --git a/shopify/scripts/cadence/data/cadence-plan-pm-2026-06-24.json b/shopify/scripts/cadence/data/cadence-plan-pm-2026-06-24.json
index e34e4154..ff0d2aa8 100644
--- a/shopify/scripts/cadence/data/cadence-plan-pm-2026-06-24.json
+++ b/shopify/scripts/cadence/data/cadence-plan-pm-2026-06-24.json
@@ -1,182 +1,182 @@
[
{
- "vendor": "Plains",
- "dw_sku": "DWYP-1000009",
- "cost": 0,
- "retail": 0,
+ "vendor": "Kravet",
+ "dw_sku": "DWKK-102058",
+ "cost": 59.95,
+ "retail": 89.93,
"sample": "4.25",
- "sampleOnly": true,
- "title": "Bahama Cloth II, Persimmon Wallcoverings | Plains",
+ "sampleOnly": false,
+ "title": "Kravet Smart, Seafoam Green Wallcoverings | Kravet",
"willActivate": true
},
{
- "vendor": "Plains",
- "dw_sku": "DWYP-1000010",
- "cost": 0,
- "retail": 0,
+ "vendor": "Kravet",
+ "dw_sku": "DWKK-102059",
+ "cost": 59.95,
+ "retail": 89.93,
"sample": "4.25",
- "sampleOnly": true,
- "title": "Bahama Cloth II, Purple Wallcoverings | Plains",
+ "sampleOnly": false,
+ "title": "Kravet Smart, Light Blue Wallcoverings | Kravet",
"willActivate": true
},
{
- "vendor": "Plains",
- "dw_sku": "DWYP-1000011",
- "cost": 0,
- "retail": 0,
+ "vendor": "Kravet",
+ "dw_sku": "DWKK-102060",
+ "cost": 59.95,
+ "retail": 89.93,
"sample": "4.25",
- "sampleOnly": true,
- "title": "Bahama Cloth II, Navy Wallcoverings | Plains",
+ "sampleOnly": false,
+ "title": "Kravet Smart, Beige Wallcoverings | Kravet",
"willActivate": true
},
{
- "vendor": "Romo",
- "dw_sku": "DWRM-240067",
- "cost": 393.8025,
- "retail": 712.76,
+ "vendor": "Schumacher",
+ "dw_sku": "DWLK-805290",
+ "cost": 64,
+ "retail": 115.84,
"sample": "4.25",
"sampleOnly": false,
- "title": "Papier, Greenware Wallcoverings | Romo",
+ "title": "Floreana, Berry Wallcoverings | Schumacher",
"willActivate": true
},
{
- "vendor": "Romo",
- "dw_sku": "DWRM-240068",
- "cost": 393.8025,
- "retail": 712.76,
+ "vendor": "Schumacher",
+ "dw_sku": "DWLK-805300",
+ "cost": 64,
+ "retail": 115.84,
"sample": "4.25",
"sampleOnly": false,
- "title": "Papier, Jasmine Wallcoverings | Romo",
+ "title": "Floreana, Blue Wallcoverings | Schumacher",
"willActivate": true
},
{
- "vendor": "Romo",
- "dw_sku": "DWRM-240069",
- "cost": 393.8025,
- "retail": 712.76,
+ "vendor": "Schumacher",
+ "dw_sku": "DWLK-805310",
+ "cost": 38,
+ "retail": 68.78,
"sample": "4.25",
"sampleOnly": false,
- "title": "Papier, Powder Wallcoverings | Romo",
+ "title": "Baudin Butterfly, Blush Wallcoverings | Schumacher",
"willActivate": true
},
{
- "vendor": "Thibaut",
- "dw_sku": "DWTT-73426",
- "cost": 134.1,
- "retail": 242.71,
+ "vendor": "Quadrille",
+ "dw_sku": "DWQC-600018",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Cashiers, Aqua on Metallic Gold Wallcoverings | Thibaut",
+ "sampleOnly": true,
+ "title": "Palm Garden, Cadet Blue / Hazelnut on Light Tint Wallcoverings | Quadrille",
"willActivate": true
},
{
- "vendor": "Thibaut",
- "dw_sku": "DWTT-73427",
- "cost": 134.1,
- "retail": 242.71,
+ "vendor": "Quadrille",
+ "dw_sku": "DWQC-600019",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Cashiers, Charcoal and Metallic Copper Wallcoverings | Thibaut",
+ "sampleOnly": true,
+ "title": "Palm Garden, Marine Blue / Hazelnut on Tint Wallcoverings | Quadrille",
"willActivate": true
},
{
- "vendor": "Thibaut",
- "dw_sku": "DWTT-73428",
- "cost": 134.1,
- "retail": 242.71,
+ "vendor": "Quadrille",
+ "dw_sku": "DWQC-600020",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Cashiers, Navy Wallcoverings | Thibaut",
+ "sampleOnly": true,
+ "title": "Palm Garden, Moss Green / Hazelnut on Tint Wallcoverings | Quadrille",
"willActivate": true
},
{
- "vendor": "Designtex",
- "dw_sku": "DWDX-220327",
- "cost": 22,
- "retail": 39.82,
+ "vendor": "Alan Campbell",
+ "dw_sku": "DWAK-700012",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Thatch, Blueberry Wallcoverings | Designtex",
+ "sampleOnly": true,
+ "title": "Putty on Tint Wallcoverings | Alan Campbell",
"willActivate": true
},
{
- "vendor": "Designtex",
- "dw_sku": "DWDX-220328",
- "cost": 22,
- "retail": 39.82,
+ "vendor": "Alan Campbell",
+ "dw_sku": "DWAK-700013",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Ledger, Seashell Wallcoverings | Designtex",
+ "sampleOnly": true,
+ "title": "Coco on Tint Wallcoverings | Alan Campbell",
"willActivate": true
},
{
- "vendor": "Designtex",
- "dw_sku": "DWDX-220329",
- "cost": 22,
- "retail": 39.82,
+ "vendor": "Alan Campbell",
+ "dw_sku": "DWAK-700014",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Ledger, Boulder Wallcoverings | Designtex",
+ "sampleOnly": true,
+ "title": "White on Tint Wallcoverings | Alan Campbell",
"willActivate": true
},
{
- "vendor": "Newwall",
- "dw_sku": "DWXW-1005032",
- "cost": 156,
- "retail": 282.35,
+ "vendor": "Home Couture",
+ "dw_sku": "DWHJ-900012",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Llengües Blue, Blue Wallcoverings | Newwall",
+ "sampleOnly": true,
+ "title": "Multi Beige on Ivory Linen Wallcoverings | Home Couture",
"willActivate": true
},
{
- "vendor": "Newwall",
- "dw_sku": "DWXW-1005033",
- "cost": 156,
- "retail": 282.35,
+ "vendor": "Home Couture",
+ "dw_sku": "DWHJ-900013",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Llengües Cream, Cream Wallcoverings | Newwall",
+ "sampleOnly": true,
+ "title": "Multi Blues on Ivory Linen Wallcoverings | Home Couture",
"willActivate": true
},
{
- "vendor": "Newwall",
- "dw_sku": "DWXW-1005034",
- "cost": 156,
- "retail": 282.35,
+ "vendor": "Home Couture",
+ "dw_sku": "DWHJ-900014",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Llengües Black, Black Wallcoverings | Newwall",
+ "sampleOnly": true,
+ "title": "Turquoise on Tan Wallcoverings | Home Couture",
"willActivate": true
},
{
- "vendor": "Brewster & York",
- "dw_sku": "DWBR-170685",
- "cost": 90,
- "retail": 162.9,
+ "vendor": "Charles Burger",
+ "dw_sku": "DWCY-1100012",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Brittsommar, Navy Blue Wallcoverings | Brewster & York",
+ "sampleOnly": true,
+ "title": "Le Notre Toile, Turquoise Wallcoverings | Charles Burger",
"willActivate": true
},
{
- "vendor": "Brewster & York",
- "dw_sku": "DWBR-170686",
- "cost": 90,
- "retail": 162.9,
+ "vendor": "Charles Burger",
+ "dw_sku": "DWCY-1100013",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Brittsommar, Light Blue Wallcoverings | Brewster & York",
+ "sampleOnly": true,
+ "title": "Riviere Enchantee, Saffron Wallcoverings | Charles Burger",
"willActivate": true
},
{
- "vendor": "Brewster & York",
- "dw_sku": "DWBR-170687",
- "cost": 45,
- "retail": 81.45,
+ "vendor": "Charles Burger",
+ "dw_sku": "DWCY-1100014",
+ "cost": 0,
+ "retail": 0,
"sample": "4.25",
- "sampleOnly": false,
- "title": "Hybbe, Multicolor Wallcoverings | Brewster & York",
+ "sampleOnly": true,
+ "title": "Riviere Enchantee, Saumon Wallcoverings | Charles Burger",
"willActivate": true
}
]
\ No newline at end of file
diff --git a/shopify/scripts/cadence/data/upload-restore-2026-06-24.jsonl b/shopify/scripts/cadence/data/upload-restore-2026-06-24.jsonl
index b35d81ab..6ff0b509 100644
--- a/shopify/scripts/cadence/data/upload-restore-2026-06-24.jsonl
+++ b/shopify/scripts/cadence/data/upload-restore-2026-06-24.jsonl
@@ -209,3 +209,13 @@
{"table":"schumacher_catalog","mfr_sku":"5010690","dw_sku":"DWLK-805310","shopify_product_id":"7867515109427","action":"created","activated":true,"published":true,"sampleOnly":false,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:23.478Z"}
{"table":"quadrille_house_catalog","mfr_sku":"307200F-105","dw_sku":"DWQC-600018","shopify_product_id":"7867515142195","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:27.119Z"}
{"table":"quadrille_house_catalog","mfr_sku":"307200F-126","dw_sku":"DWQC-600019","shopify_product_id":"7867515174963","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:31.390Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"307200F-120","dw_sku":"DWQC-600020","shopify_product_id":"7867515207731","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:34.915Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"AC850-08","dw_sku":"DWAK-700012","shopify_product_id":"7867515240499","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:38.419Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"AC850-10","dw_sku":"DWAK-700013","shopify_product_id":"7867515273267","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:42.044Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"AC855-00","dw_sku":"DWAK-700014","shopify_product_id":"7867515306035","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:45.789Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"HC2040I-20","dw_sku":"DWHJ-900012","shopify_product_id":"7867515371571","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:49.605Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"HC2040I-25","dw_sku":"DWHJ-900013","shopify_product_id":"7867515404339","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:52.983Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"HC1280T-01","dw_sku":"DWHJ-900014","shopify_product_id":"7867515437107","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:56.378Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"1716-04","dw_sku":"DWCY-1100012","shopify_product_id":"7867515469875","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:40:59.951Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"2438-02","dw_sku":"DWCY-1100013","shopify_product_id":"7867515502643","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:41:03.905Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"2438-01","dw_sku":"DWCY-1100014","shopify_product_id":"7867515535411","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-pm-2026-06-24T21-40-02-181Z","ts":"2026-06-24T21:41:07.321Z"}
← e9f90aa9 China Seas mailer: pink Clementine room hero (logo centered)
·
back to Designer Wallcoverings
·
China Seas mailer: pink hero v2 — TV removed (wallpaper patc 6be93c15 →