[object Object]

← back to Silkwallcoverings

silkwallcoverings: add silk niche filter — drop non-silk fibres (abaca/linen/grasscloth leaked; no nicheFit before)

a1732f2803f963edf7d1f213ae045b97d96ffc85 · 2026-08-12 10:01:48 -0700 · steve

Files touched

Diff

commit a1732f2803f963edf7d1f213ae045b97d96ffc85
Author: steve <steve@designerwallcoverings.com>
Date:   Wed Aug 12 10:01:48 2026 -0700

    silkwallcoverings: add silk niche filter — drop non-silk fibres (abaca/linen/grasscloth leaked; no nicheFit before)
---
 server.js | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/server.js b/server.js
index 975113e..6280b5f 100644
--- a/server.js
+++ b/server.js
@@ -35,6 +35,18 @@ function isJunk(p) {
   return false;
 }
 
+// SILK niche filter (added 2026-08-12 — Steve fleet fix "it is not {niche}"). This site
+// (unlike the older sister-sites) had NO niche scoping and showed its whole assigned
+// catalog, so non-silk fibres (abaca, natural linen, grasscloth) leaked onto a SILK site.
+// Mirror silkwallpaper's rule: keep a silk signal, drop competing primary fibres.
+const NICHE_POS = ["silk","luxe","sheen","jacquard","satin"];
+const NICHE_NEG = ["solid","blank","plain","grasscloth","grass cloth","sisal","seagrass","jute","raffia","cork","linen","flax","mica","mylar","suede","leather","hemp","abaca"];
+function nicheFit(p) {
+  const blob = ((p.title || '') + ' ' + (p.tags || []).join(' ')).toLowerCase();
+  if (NICHE_NEG.some(n => blob.includes(n))) return false;
+  return NICHE_POS.some(k => blob.includes(k));
+}
+
 // Catalog now lives in dw_unified.microsite_products — populated async at
 // startup (see bottom of file). Falls back to data/products.json if PG is down.
 let PRODUCTS = [];
@@ -278,9 +290,9 @@ if (catalog) catalog.mount(app, { siteSlug: SITE_SLUG, rails: SITE_RAILS });
   if (catalog) {
     try {
       const rows = await catalog.getProducts(SITE_SLUG);
-      PRODUCTS = rows.filter(p => !isJunk(p));
+      PRODUCTS = rows.filter(p => !isJunk(p) && nicheFit(p));
       DROPPED = rows.length - PRODUCTS.length;
-      console.log(`[${__SITE}] loaded ${rows.length} from dw_unified, kept ${PRODUCTS.length}, dropped ${DROPPED}`);
+      console.log(`[${__SITE}] loaded ${rows.length} from dw_unified, kept ${PRODUCTS.length} (silk niche), dropped ${DROPPED}`);
       loaded = true;
     } catch (e) {
       console.error(`[${__SITE}] PG catalog load failed (${e.message}) — falling back to data/products.json`);
@@ -289,8 +301,8 @@ if (catalog) catalog.mount(app, { siteSlug: SITE_SLUG, rails: SITE_RAILS });
   if (!loaded) {
     try {
       const raw = JSON.parse(fs.readFileSync(path.join(__dirname, 'data', 'products.json'), 'utf8'));
-      PRODUCTS = (Array.isArray(raw) ? raw : []).filter(p => !isJunk(p));
-      console.log(`[${__SITE}] loaded ${PRODUCTS.length} from data/products.json (static mode)`);
+      PRODUCTS = (Array.isArray(raw) ? raw : []).filter(p => !isJunk(p) && nicheFit(p));
+      console.log(`[${__SITE}] loaded ${PRODUCTS.length} from data/products.json (static mode, silk niche)`);
     } catch (_) { PRODUCTS = []; }
   }
   buildSampleDisplayMap(); // Step 2: redacted->raw /sample resolver keys

← 6abaf0f viewer standard: add per-field on/off menu (Fields ▾) to pro  ·  back to Silkwallcoverings  ·  silkwallcoverings: title-required silk filter — drop tag-onl d7c473c →