[object Object]

← back to Designer Wallcoverings

auto-save: 2026-06-30T05:28:32 (4 files) — onboarding/sangetsu-lilycolor/lily-merge.cjs pending-approval/boost-filter-consolidation-2026-06-25 vendor-scrapers/china-seas-refresh shopify/staged/free-samples-banner/apply-banner-to-live.sh

700c353177af614a65d8e9c14d100ac996dcabee · 2026-06-30 05:28:38 -0700 · Steve Abrams

Files touched

Diff

commit 700c353177af614a65d8e9c14d100ac996dcabee
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jun 30 05:28:38 2026 -0700

    auto-save: 2026-06-30T05:28:32 (4 files) — onboarding/sangetsu-lilycolor/lily-merge.cjs pending-approval/boost-filter-consolidation-2026-06-25 vendor-scrapers/china-seas-refresh shopify/staged/free-samples-banner/apply-banner-to-live.sh
---
 onboarding/sangetsu-lilycolor/lily-merge.cjs       | 23 +++++++-
 .../free-samples-banner/apply-banner-to-live.sh    | 64 ++++++++++++++++++++++
 2 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/onboarding/sangetsu-lilycolor/lily-merge.cjs b/onboarding/sangetsu-lilycolor/lily-merge.cjs
index 2ceb94d3..15dc8f70 100644
--- a/onboarding/sangetsu-lilycolor/lily-merge.cjs
+++ b/onboarding/sangetsu-lilycolor/lily-merge.cjs
@@ -32,13 +32,32 @@ for (const p of rd(FEED)) {
 // official per-SKU image manifest (filenames inside the catalog zips; bytes deferred)
 const manifest = fs.existsSync(MANIFEST) ? JSON.parse(fs.readFileSync(MANIFEST, 'utf8')) : {};
 
+// PATTERN-FIRST ordering. The swatch (pattern/texture) must lead; the room/model
+// scene goes last. Shop-feed room shots are named `<SKU>_model.jpg`; swatches are
+// `<SKU>_<uuid>.jpg`. Also prefer images that match THIS exact SKU (feed products
+// bundle sibling colorways' images together).
+const isRoom = (name) => /_model\.|_room|_scene|_R(?:_\d+)?\.|_RS\./i.test(name);
+function orderPreviews(images, sku) {
+  const skuKey = norm(sku);
+  const rank = (u) => {
+    const base = u.split('/').pop().split('?')[0];
+    const mine = norm((base.match(/^([A-Za-z]+-?\d+)/) || [])[1]) === skuKey;
+    const room = isRoom(base);
+    return (room ? 2 : 0) + (mine ? 0 : 1);   // mine-swatch < other-swatch < mine-room < other-room
+  };
+  return [...images].sort((a, b) => rank(a) - rank(b));
+}
+// manifest kind priority: C swatch, P pattern-tile, SP special — all BEFORE R room
+const KIND_RANK = { C: 0, P: 1, SP: 2, R: 3, '?': 4 };
+const orderManifest = (ms) => [...ms].sort((a, b) => (KIND_RANK[a.kind] ?? 9) - (KIND_RANK[b.kind] ?? 9));
+
 const out = [];
 let withAnyImg = 0, withPreview = 0;
 for (const r of rd(PB)) {
   const k = norm(r.mfr_sku);
   const f = feedImg.get(k);
-  const mImgs = manifest[r.mfr_sku] || manifest[k] || [];   // [{zipUrl,name,kind}]
-  const previews = (f && f.images) || [];                   // remote shop-CDN URLs (display now)
+  const mImgs = orderManifest(manifest[r.mfr_sku] || manifest[k] || []);   // pattern-first
+  const previews = orderPreviews((f && f.images) || [], r.mfr_sku);        // pattern-first, this-SKU-first
   if (previews.length) withPreview++;
   if (previews.length || mImgs.length) withAnyImg++;
   out.push({
diff --git a/shopify/staged/free-samples-banner/apply-banner-to-live.sh b/shopify/staged/free-samples-banner/apply-banner-to-live.sh
new file mode 100755
index 00000000..a4b6fe1d
--- /dev/null
+++ b/shopify/staged/free-samples-banner/apply-banner-to-live.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+# GO-LIVE: apply the free-samples banner to the LIVE published main theme 144070803507.
+# Customer-facing — main is published, so the banner goes live the instant this writes.
+# Safe: drift-checks live main vs the pristine snapshot FIRST, backs up, then PUTs the
+# banner version, then verifies the marker. Requires --confirm to actually write.
+set -euo pipefail
+DIR="$(cd "$(dirname "$0")" && pwd)"
+STORE="designer-laboratory-sandbox.myshopify.com"
+THEME="144070803507"
+API="2024-10"
+PRISTINE="$DIR/theme.liquid.144070803507.original"
+WITHBANNER="$DIR/theme.liquid.144088858675.with-banner"
+MARKER="DW-SAMPLES-BANNER v1"
+: "${SHOPIFY_THEME_TOKEN:?Set SHOPIFY_THEME_TOKEN first (route via /secrets). It needs write_themes.}"
+
+base="https://$STORE/admin/api/$API"
+auth=(-H "X-Shopify-Access-Token: $SHOPIFY_THEME_TOKEN")
+
+echo "→ Pulling LIVE main layout/theme.liquid (theme $THEME)…"
+curl -s "${auth[@]}" "$base/themes/$THEME/assets.json?asset%5Bkey%5D=layout/theme.liquid" \
+  | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const v=JSON.parse(s).asset.value;process.stdout.write(v);})' > /tmp/live-main-theme.liquid
+echo "  pulled $(wc -c </tmp/live-main-theme.liquid) bytes"
+
+echo "→ Drift check vs pristine snapshot…"
+if ! diff -q "$PRISTINE" /tmp/live-main-theme.liquid >/dev/null; then
+  echo "✋ DRIFT DETECTED — live main differs from the staged snapshot. STOP."
+  echo "   The patch was verified against the old snapshot; re-stage before applying."
+  echo "   diff: live=/tmp/live-main-theme.liquid  snapshot=$PRISTINE"
+  exit 2
+fi
+echo "  ✓ no drift — live main is byte-identical to the snapshot the banner was built on"
+
+if grep -q "$MARKER" "$WITHBANNER"; then echo "  ✓ banner version contains the marker"; else echo "✋ banner version missing marker"; exit 3; fi
+
+if [[ "${1:-}" != "--confirm" ]]; then
+  echo
+  echo "DRY RUN ok. This WILL put the banner LIVE on $STORE the moment you re-run with --confirm."
+  echo "A timestamped backup of current live main will be saved first. Re-run:  $0 --confirm"
+  exit 0
+fi
+
+ts=$(date +%Y%m%d-%H%M%S)
+cp /tmp/live-main-theme.liquid "$DIR/theme.liquid.LIVE-backup-$ts"
+echo "→ backed up current live main → $DIR/theme.liquid.LIVE-backup-$ts"
+
+echo "→ PUTting banner version to LIVE theme $THEME…"
+node -e '
+const fs=require("fs");
+const value=fs.readFileSync(process.env.WITHBANNER,"utf8");
+process.stdout.write(JSON.stringify({asset:{key:"layout/theme.liquid",value}}));
+' WITHBANNER="$WITHBANNER" \
+  | curl -s -X PUT "${auth[@]}" -H "Content-Type: application/json" --data-binary @- \
+    "$base/themes/$THEME/assets.json" >/tmp/put-resp.json
+echo "  response: $(node -e 'const r=require("/tmp/put-resp.json");console.log(r.asset?("OK "+r.asset.key+" @ "+r.asset.updated_at):JSON.stringify(r))' 2>/dev/null || cat /tmp/put-resp.json)"
+
+echo "→ Verifying marker on live-served HTML…"
+sleep 3
+if curl -s "https://www.designerwallcoverings.com/" | grep -q "$MARKER"; then
+  echo "  ✅ BANNER IS LIVE (marker present on the homepage)."
+else
+  echo "  ⚠️ marker not seen yet (CDN cache?) — check https://www.designerwallcoverings.com/ in a minute."
+fi
+echo
+echo "ROLLBACK any time:  SHOPIFY_THEME_TOKEN=… node -e 'PUT theme.liquid.144070803507.original'  (or re-PUT the LIVE-backup-$ts file)"

← 0af646f8 free-samples phase 3: stage Shopify discount Function (trade  ·  back to Designer Wallcoverings  ·  Lily: selective ZIP-range swatch fetcher -> Henry + viewer s 698dfc9d →