[object Object]

← 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

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 →