[object Object]

← back to Restorationwallpaper

rails: build from tags via shared rail-match helper (fix degenerate single-rail collapse)

00b8d92cd54212d50b8bc5146c746a5be1c084e6 · 2026-05-26 10:18:40 -0700 · Steve Abrams

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files touched

Diff

commit 00b8d92cd54212d50b8bc5146c746a5be1c084e6
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue May 26 10:18:40 2026 -0700

    rails: build from tags via shared rail-match helper (fix degenerate single-rail collapse)
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---
 server.js        | 24 ++++++++++++++++--------
 site.config.json | 10 +++++-----
 2 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/server.js b/server.js
index 43d39e4..3a50050 100644
--- a/server.js
+++ b/server.js
@@ -19,6 +19,7 @@ if (ADMIN_ENABLED) {
   try { catalog = require('../_shared/admin-catalog'); }
   catch (e) { console.error(`[${__SITE}] admin-catalog unavailable (${e.message}) — falling back to static JSON`); }
 }
+const { buildRails, railFacets } = require('../_shared/rail-match');
 const siteCfg = JSON.parse(fs.readFileSync(path.join(__dirname, 'site.config.json'), 'utf8'));
 const SITE_SLUG = siteCfg.slug || __SITE;
 const SITE_RAILS = Array.isArray(siteCfg.rails) ? siteCfg.rails : [];
@@ -188,12 +189,19 @@ app.get('/api/products', (req, res) => {
 });
 
 app.get('/api/sliders', (req, res) => {
-  const out = [];
-  for (const a of SITE_RAILS) {
-    const items = PRODUCTS.filter(p => p.aesthetic === a).slice(0, 12);
-    if (items.length >= 4) out.push({ aesthetic: a, items });
-  }
-  res.json({ rails: out });
+  const RAIL_LABELS = {
+    traditional: 'Traditional',
+    victorian:   'Victorian',
+    damask:      'Damask',
+    floral:      'Floral',
+    paper:       'Paper',
+    beige:       'Beige & Neutral',
+  };
+  const rails = buildRails(PRODUCTS, SITE_RAILS).map(r => ({
+    ...r,
+    label: RAIL_LABELS[r.key] || r.key,
+  }));
+  res.json({ rails });
 });
 
 app.get('/api/facets', (req, res) => {
@@ -208,9 +216,9 @@ app.get('/api/facets', (req, res) => {
     list = list.filter(p => (p.title || '').toLowerCase().includes(needle) || (p.tags || []).some(t => String(t).toLowerCase().includes(needle)));
   }
   if (aesthetic && aesthetic !== 'all') list = list.filter(p => p.aesthetic === aesthetic);
-  const aesthetics = {}; const vendors = {};
+  const aesthetics = railFacets(list, SITE_RAILS);
+  const vendors = {};
   for (const p of list) {
-    aesthetics[p.aesthetic] = (aesthetics[p.aesthetic] || 0) + 1;
     vendors[p.vendor] = (vendors[p.vendor] || 0) + 1;
   }
   res.json({ aesthetics, vendors, total: list.length });
diff --git a/site.config.json b/site.config.json
index b01ab24..c5baf1c 100644
--- a/site.config.json
+++ b/site.config.json
@@ -10,12 +10,12 @@
     "accent": "#8a6a4a"
   },
   "rails": [
+    "traditional",
     "victorian",
-    "federal",
-    "colonial",
-    "arts-crafts",
-    "art-nouveau",
-    "art-deco"
+    "damask",
+    "floral",
+    "paper",
+    "beige"
   ],
   "port": 9903
 }

← 30b8042 rails: editorial labels for firing aesthetic buckets  ·  back to Restorationwallpaper  ·  rails: editorial labels for new tag-derived rail keys (index e114401 →