[object Object]

← back to Fix Live Board

last5: treat showroom lines (Phillip Jeffries) as sample-only-correct — waive sellable+price, show 'showroom' pill; config/showroom-vendors.json editable

d014212fb405bfd1d81fdb344bfd150c0848df26 · 2026-09-02 14:03:17 -0700 · Steve

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

Files touched

Diff

commit d014212fb405bfd1d81fdb344bfd150c0848df26
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Sep 2 14:03:17 2026 -0700

    last5: treat showroom lines (Phillip Jeffries) as sample-only-correct — waive sellable+price, show 'showroom' pill; config/showroom-vendors.json editable
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01KkjHuJKiariXaTtFujZxWC
---
 config/showroom-vendors.json |  1 +
 probes/shopify-recent.mjs    | 19 +++++++++++++++----
 public/board.html            |  2 +-
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/config/showroom-vendors.json b/config/showroom-vendors.json
new file mode 100644
index 0000000..095e28f
--- /dev/null
+++ b/config/showroom-vendors.json
@@ -0,0 +1 @@
+["Phillip Jeffries"]
diff --git a/probes/shopify-recent.mjs b/probes/shopify-recent.mjs
index d5645e7..f812242 100644
--- a/probes/shopify-recent.mjs
+++ b/probes/shopify-recent.mjs
@@ -7,9 +7,15 @@ import https from 'https';
 import fs from 'fs';
 import path from 'path';
 import os from 'os';
+import { fileURLToPath } from 'url';
 
+const ROOT = path.dirname(fileURLToPath(import.meta.url));
 const SHOP = 'designer-laboratory-sandbox.myshopify.com';
 const DAYS = parseInt(process.env.DAYS || '5', 10);
+// Showroom lines are SAMPLE-ONLY by design — a sample with no sellable roll/price is CORRECT, not
+// broken. Editable list; seeded with Phillip Jeffries.
+let SHOWROOM = new Set(['phillip jeffries']);
+try { SHOWROOM = new Set(JSON.parse(fs.readFileSync(path.join(ROOT, '..', 'config', 'showroom-vendors.json'), 'utf8')).map(s => String(s).trim().toLowerCase())); } catch (e) {}
 function token() {
   if (process.env.SHOPIFY_ADMIN_TOKEN) return process.env.SHOPIFY_ADMIN_TOKEN.trim();
   try { const env = fs.readFileSync(path.join(os.homedir(), 'Projects/secrets-manager/.env'), 'utf8'); const m = env.match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m); if (m) return m[1].trim(); } catch (e) {}
@@ -51,10 +57,12 @@ function gql(query, variables) {
     const sellV = vs.find(v => v.sku && !isSample(v)); // sellable = a real (non-sample) variant
     const sellPrice = sellV ? (parseFloat(sellV.price) || 0) : 0;
     const tags = n.tags || [];
+    const showroom = SHOWROOM.has((n.vendor || '').trim().toLowerCase());
     const f = {
       sample: !!sampleV,
-      sellable: !!sellV,
-      price: sellPrice > 0,
+      // showroom lines are sample-only by design → sellable + price are waived (shown satisfied)
+      sellable: showroom ? true : !!sellV,
+      price: showroom ? true : sellPrice > 0,
       desc: !!(n.descriptionHtml && n.descriptionHtml.replace(/<[^>]*>/g, '').trim().length > 0),
       tags: tags.length >= 2,
       image: !!(n.featuredImage && n.featuredImage.url)
@@ -66,8 +74,11 @@ function gql(query, variables) {
       title: '[' + (n.vendor || '?') + '] ' + n.title,
       status: n.status, price: sellPrice,
       img: (n.featuredImage && n.featuredImage.url) || null,
-      created: n.createdAt, fields: f,
-      fixed: f.sample && f.sellable && f.price && f.desc && f.tags && f.image
+      created: n.createdAt, note: showroom ? 'showroom' : undefined, fields: f,
+      // showroom lines are fixed when the sample + quality fields are present (no sellable/price needed)
+      fixed: showroom
+        ? (f.sample && f.desc && f.tags && f.image)
+        : (f.sample && f.sellable && f.price && f.desc && f.tags && f.image)
     };
   });
   process.stdout.write(JSON.stringify(rows));
diff --git a/public/board.html b/public/board.html
index 8cf738c..4845640 100644
--- a/public/board.html
+++ b/public/board.html
@@ -76,7 +76,7 @@ function render(){
       +'<div class="body">'
       +'<div class="ttl" title="'+esc(r.title||r.id)+'">'+esc(r.title||r.id)+'</div>'
       +'<div class="meta"><span>'+esc(r.sku||r.id)+'</span><span class="price">'+(r.price>0?('$'+Number(r.price).toFixed(2)):'—')+'</span></div>'
-      +'<div class="chips">'+(r.status?'<span class="pill">'+esc(r.status)+'</span>':'')+chips+'</div>'
+      +'<div class="chips">'+(r.status?'<span class="pill">'+esc(r.status)+'</span>':'')+(r.note?'<span class="pill" style="border-color:#5a4a1e;color:var(--warn)">'+esc(r.note)+'</span>':'')+chips+'</div>'
       +(r.created?'<div class="when" title="'+esc(r.created)+'">🕓 '+fmtWhen(r.created)+'</div>':'')
       +'</div></div>';
   }).join('');

← 5f15a19 add last5 job: last-5-days new-products go-live board (live  ·  back to Fix Live Board  ·  board UX upgrade: day/night toggle, click-to-drill detail dr edfc58b →