[object Object]

← back to Japan Enrich

japan viewer: per-distributor microsite host-scoping — <slug>.designerwallcoverings.com serves only that distributor's Sangetsu line (internal, read-only)

0b387d1bfb0ddb1ac07f645b45fcf9a7444425c0 · 2026-07-06 16:10:18 -0700 · Steve

Files touched

Diff

commit 0b387d1bfb0ddb1ac07f645b45fcf9a7444425c0
Author: Steve <steve@designerwallcoverings.com>
Date:   Mon Jul 6 16:10:18 2026 -0700

    japan viewer: per-distributor microsite host-scoping — <slug>.designerwallcoverings.com serves only that distributor's Sangetsu line (internal, read-only)
---
 viewer-local/server.js | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/viewer-local/server.js b/viewer-local/server.js
index 627b8f1..587a70b 100644
--- a/viewer-local/server.js
+++ b/viewer-local/server.js
@@ -82,6 +82,15 @@ const SANG_BRANDS_FILE = path.join(DIR, 'sangetsu-brands.json');
 let SANG_BRANDS = {};
 const loadSangBrands = () => { try { SANG_BRANDS = JSON.parse(fs.readFileSync(SANG_BRANDS_FILE, 'utf8')); } catch { SANG_BRANDS = {}; } };
 loadSangBrands();
+// distributor → subdomain slug map, so <slug>.designerwallcoverings.com is a per-distributor
+// microsite (e.g. koroseal. / eijffinger. / j-josephson.). Built from the scraped brand map.
+let DIST_SLUGS = {};
+const buildDistSlugs = () => {
+  const m = { lilycolor: 'Lilycolor (direct)' };
+  for (const v of Object.values(SANG_BRANDS)) if (v && v.slug && v.distributor) m[v.slug] = v.distributor;
+  DIST_SLUGS = m;
+};
+buildDistSlugs();
 const ENRICH_FILES = [
   process.env.ENRICH_FILE,                                          // explicit override
   path.join(DIR, 'lilycolor-enriched.jsonl'),                       // post-deploy: beside staging
@@ -300,7 +309,7 @@ function buildRows() {
 }
 
 let ROWS = buildRows();
-const reload = () => { loadGreenSwatches(); loadSangSwatches(); loadSangBrands(); ENRICH = loadEnrich(); ROWS = buildRows(); };
+const reload = () => { loadGreenSwatches(); loadSangSwatches(); loadSangBrands(); buildDistSlugs(); ENRICH = loadEnrich(); ROWS = buildRows(); };
 try { if (fs.existsSync(SANG_BRANDS_FILE)) fs.watchFile(SANG_BRANDS_FILE, { interval: 5000 }, reload); } catch {}
 fs.watchFile(SANG, { interval: 4000 }, reload);   // pick up Sangetsu staging as it grows
 fs.watchFile(LILY, { interval: 8000 }, reload);
@@ -379,12 +388,23 @@ function hostScope(req) {
     return { id: 'china', label: 'China — Greenland', sub: 'Greenland vendor · staged offline · read-only preview',
       sources: ['greenland'], tabs: [{ src: 'greenland', label: 'Greenland' }] };
   }
+  // per-distributor microsite: <slug>.designerwallcoverings.com → only that distributor's rows
+  const sub = host.split('.')[0];
+  if (DIST_SLUGS[sub] && !['japan', 'china', 'www', 'localhost'].includes(sub)) {
+    const label = DIST_SLUGS[sub];
+    return { id: 'dist-' + sub, label, sub: `${label} · Sangetsu distribution · internal · read-only`,
+      sources: ['lilycolor', 'sangetsu'], distributor: label,
+      tabs: [{ src: 'sangetsu', label: 'Sangetsu' }] };
+  }
   // japan + local dev + anything else: the existing Japanese catalog, greenland excluded
   return { id: 'japan', label: 'Sangetsu + Lilycolor', sub: 'staged offline · read-only preview',
     sources: ['lilycolor', 'sangetsu'], tabs: [{ src: 'lilycolor', label: 'Lilycolor' }, { src: 'sangetsu', label: 'Sangetsu' }] };
 }
-// rows visible for this host (the pool every count + filter runs against)
-const scopedRows = (scope) => ROWS.filter((r) => scope.sources.includes(r.source));
+// rows visible for this host (the pool every count + filter runs against);
+// a distributor microsite pre-filters to that distributor's rows.
+const scopedRows = (scope) => (scope.distributor
+  ? ROWS.filter((r) => scope.sources.includes(r.source) && r.distributor === scope.distributor)
+  : ROWS.filter((r) => scope.sources.includes(r.source)));
 
 // gzip JSON responses when the client accepts it (the light /api/products list is
 // ~15.9k rows — gzip takes it from ~7MB to ~1MB; internal-line-viewer spec).

← efb2116 japan: close distributor gap — scrape 40 more patterns, live  ·  back to Japan Enrich  ·  japan: autonomous local-model onboarding pipeline (manifest 51b7196 →