[object Object]

← back to All Designerwallcoverings

all-dw This Item: suppress deep-link for broken/empty vhosts (VENDOR_ITEM excludes up-but-0-product microsites). Partial fix — per-product handle divergence (dw handle != microsite SPA handle) still limits reliability; deploy HELD per yolo final DTD

9769200ce94e5b38273e6a05fc325e7ce3ef36d1 · 2026-07-07 08:21:43 -0700 · steve

Files touched

Diff

commit 9769200ce94e5b38273e6a05fc325e7ce3ef36d1
Author: steve <steve@designerwallcoverings.com>
Date:   Tue Jul 7 08:21:43 2026 -0700

    all-dw This Item: suppress deep-link for broken/empty vhosts (VENDOR_ITEM excludes up-but-0-product microsites). Partial fix — per-product handle divergence (dw handle != microsite SPA handle) still limits reliability; deploy HELD per yolo final DTD
---
 server.js | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/server.js b/server.js
index e78924b..1c0f06a 100644
--- a/server.js
+++ b/server.js
@@ -115,6 +115,7 @@ let LOADED_AT = null;
 let pool = null;
 let STOCK = new Map();          // upper(sku) → public-safe stored stock snapshot (the /livestock FREE path)
 let VENDOR_VIEWER = new Map();  // slugify(vendor) / slug → internal line-viewer URL (the vendor's live microsite)
+let VENDOR_ITEM = new Map();    // same, but ONLY hosts safe for a /product/<handle> deep link (broken/empty vhosts excluded)
 
 // Stored stock snapshot — the FREE /livestock path. PUBLIC-SAFE availability ONLY
 // (in_stock / quantity / lead_time / as-of); cost & price columns are NEVER selected.
@@ -163,16 +164,26 @@ async function loadStock() {
 // vendors without a live line viewer degrade gracefully (the control dims).
 function buildVendorViewer() {
   const map = new Map();
+  const item = new Map();  // slug → host base for the per-PRODUCT deep link (This Item), broken hosts excluded
   try {
     const d = JSON.parse(fs.readFileSync(MICROSITES, 'utf8'));
     for (const s of (d.sites || [])) {
       if (!s.up || !s.host || BANNED.test(s.host)) continue;
       const url = `https://${s.host}/`;
-      if (s.vendor && !BANNED.test(s.vendor)) map.set(slugify(s.vendor), url);
-      if (s.slug) map.set(String(s.slug).toLowerCase(), url);
+      // "This Item" deep-links to /product/<handle> — only safe when the microsite is NOT a
+      // misconfigured/empty vhost. A site that is up + status 200 but serves ZERO products is
+      // broken (e.g. daisybennett serving the 1890swallpaper vhost) and 404s on /product/<handle>.
+      // Gated (401) sites are fine — the page exists behind Steve's auth. So: safe when gated OR
+      // it actually has products.
+      const productful = (s.productCount > 0) || (Array.isArray(s.products) && s.products.length > 0);
+      const itemSafe = s.status === 401 || productful;
+      const setBoth = (k) => { map.set(k, url); if (itemSafe) item.set(k, url); };
+      if (s.vendor && !BANNED.test(s.vendor)) setBoth(slugify(s.vendor));
+      if (s.slug) setBoth(String(s.slug).toLowerCase());
     }
   } catch { /* crawl artifact not ready yet — viewers resolve after the first crawl lands */ }
   VENDOR_VIEWER = map;
+  VENDOR_ITEM = item;
 }
 
 function deriveRow(r) {
@@ -220,10 +231,10 @@ function deriveRow(r) {
     internal_url: adminUrl(r.shopify_id),
     line_viewer_url: r.vendor ? (VENDOR_VIEWER.get(slugify(r.vendor)) || null) : null,
     // This Item = the SAME internal microsite, deep-linked to THIS product's /product/<handle>
-    // page (one item, not the whole line). Resolves only when the line has a live microsite AND
-    // the row has a handle; otherwise the control dims.
+    // page (one item, not the whole line). Uses VENDOR_ITEM (broken/empty vhosts excluded) so the
+    // control dims rather than dead-ending on a 404 when a microsite is misconfigured or handle-less.
     internal_product_url: (function () {
-      const base = r.vendor ? VENDOR_VIEWER.get(slugify(r.vendor)) : null;
+      const base = r.vendor ? VENDOR_ITEM.get(slugify(r.vendor)) : null;
       return (base && r.handle) ? `${base}product/${encodeURIComponent(r.handle)}` : null;
     })(),
     stock: (sku && STOCK.get(String(sku).toUpperCase())) || null,

← 435af85 livestock: self-contained Browserbase backend (lib/romo-lib.  ·  back to All Designerwallcoverings  ·  This Item deep-link: capture full per-microsite handle set + 94d8f0a →