[object Object]

← back to Ffepurchasing

graphic-loop pass 12: niche keyword filter (no off-niche products like 'solid' on patterned sites)

f8c4ed74c62c0ae86b9b57078c78d82cc75ff071 · 2026-05-07 13:19:42 -0700 · Steve

Files touched

Diff

commit f8c4ed74c62c0ae86b9b57078c78d82cc75ff071
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu May 7 13:19:42 2026 -0700

    graphic-loop pass 12: niche keyword filter (no off-niche products like 'solid' on patterned sites)
---
 server.js | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/server.js b/server.js
index cf63638..3c4accd 100644
--- a/server.js
+++ b/server.js
@@ -36,6 +36,22 @@ const PRODUCTS = DATA_RAW.filter(p => !isJunk(p));
 const DROPPED = DATA_RAW.length - PRODUCTS.length;
 console.log(`Loaded ${DATA_RAW.length}, kept ${PRODUCTS.length}, dropped ${DROPPED}`);
 
+// graphics-loop pass 12: niche keyword filter — only show products that fit this site's niche
+const NICHE_POS = ["hotel","restaurant","spa","class a","hospitality","luxury"];
+const NICHE_NEG = ["solid","blank","plain"];
+function nicheFit(p) {
+  const blob = ((p.title || '') + ' ' + (p.tags || []).join(' ')).toLowerCase();
+  if (NICHE_NEG.some(n => blob.includes(n.toLowerCase()))) return false;
+  return NICHE_POS.length === 0 || NICHE_POS.some(k => blob.includes(k.toLowerCase()));
+}
+const PRODUCTS_NICHE = PRODUCTS.filter(nicheFit);
+const NICHE_DROPPED = PRODUCTS.length - PRODUCTS_NICHE.length;
+console.log(`Niche filter: kept ${PRODUCTS_NICHE.length} of ${PRODUCTS.length}, dropped ${NICHE_DROPPED}`);
+// Replace PRODUCTS reference with the niche-filtered list for all downstream handlers.
+const PRODUCTS_ORIG = PRODUCTS;
+Object.defineProperty(global, '__products_niche_applied', { value: true });
+
+
 const app = express();
 // Security headers via helmet (added 2026-05-04 overnight YOLO loop)
 // DW STANDARD: sort by color/style/sku/title for any product-rendering site.
@@ -79,7 +95,7 @@ app.use(express.static(path.join(__dirname, 'public')));
 
 app.get('/api/products', (req, res) => {
   const { q, aesthetic, vendor, page = 1, limit = 24, sort = 'newest'} = req.query;
-  let list = PRODUCTS;
+  let list = PRODUCTS_NICHE;
   if (q) {
     const needle = q.toLowerCase();
     list = list.filter(p => (p.title || '').toLowerCase().includes(needle) || (p.tags || []).some(t => t.toLowerCase().includes(needle)));
@@ -99,7 +115,7 @@ app.get('/api/sliders', (req, res) => {
   const SLIDER_AESTHETICS = ["mural","luxury","botanical","chinoiserie","deco","natural"];
   const out = [];
   for (const a of SLIDER_AESTHETICS) {
-    const items = PRODUCTS.filter(p => p.aesthetic === a).slice(0, 12);
+    const items = PRODUCTS_NICHE.filter(p => p.aesthetic === a).slice(0, 12);
     if (items.length >= 4) out.push({ aesthetic: a, items });
   }
   res.json({ rails: out });
@@ -107,17 +123,17 @@ app.get('/api/sliders', (req, res) => {
 
 app.get('/api/facets', (req, res) => {
   const aesthetics = {}; const vendors = {};
-  for (const p of PRODUCTS) {
+  for (const p of PRODUCTS_NICHE) {
     aesthetics[p.aesthetic] = (aesthetics[p.aesthetic] || 0) + 1;
     vendors[p.vendor] = (vendors[p.vendor] || 0) + 1;
   }
   res.json({ aesthetics, vendors, total: PRODUCTS.length });
 });
 
-app.get('/api/health', (req, res) => res.json({ status: 'ok', count: PRODUCTS.length, dropped: DROPPED }));
+app.get('/api/health', (req, res) => res.json({ status: 'ok', count: PRODUCTS_NICHE.length, dropped: DROPPED }));
 
 app.get('/sample/:handle', (req, res) => {
-  const p = PRODUCTS.find(x => x.handle === req.params.handle || x.sku === req.params.handle);
+  const p = PRODUCTS_NICHE.find(x => x.handle === req.params.handle || x.sku === req.params.handle);
   if (!p) return res.status(404).send('Not found');
   res.redirect(302, p.product_url || `${DW_SHOPIFY}/products/${encodeURIComponent(p.handle)}#sample`);
 });

← 3e4a6bb graphic-loop pass 11: add Ideas rails (New this week + Curat  ·  back to Ffepurchasing  ·  graphic-loop pass 13: real footer brand + Facebook link + OG c969938 →