← back to Carmelwallpapers
stage2: wire carmelwallpapers onto shared catalog (hand-tailored)
ccc83e1c476162e63c81ab0fcc51c83eb4e6cffa · 2026-05-19 11:07:18 -0700 · Steve Abrams
Files touched
Diff
commit ccc83e1c476162e63c81ab0fcc51c83eb4e6cffa
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue May 19 11:07:18 2026 -0700
stage2: wire carmelwallpapers onto shared catalog (hand-tailored)
---
server.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 58 insertions(+), 14 deletions(-)
diff --git a/server.js b/server.js
index b04006d..cd30afc 100644
--- a/server.js
+++ b/server.js
@@ -6,6 +6,27 @@ const path = require('path');
const PORT = process.env.PORT || 9832;
const DATA_PATH = path.join(__dirname, 'data', 'products.json');
+// ── Shared catalog: products live in dw_unified.microsite_products ───────────
+const catalog = require('../_shared/admin-catalog');
+const siteCfg = JSON.parse(fs.readFileSync(path.join(__dirname, 'site.config.json'), 'utf8'));
+const SITE_SLUG = siteCfg.slug || path.basename(__dirname);
+const SITE_RAILS = Array.isArray(siteCfg.rails) ? siteCfg.rails : [];
+
+// The PG read-path returns the canonical microsite_products columns. The Carmel
+// templates also expect `sample_url` + `images` (legacy products.json fields),
+// so derive them: sample = product page anchored to #sample; images = [image_url].
+function shapeForSite(p) {
+ const productUrl = p.product_url
+ || (p.handle ? `https://designerwallcoverings.com/products/${p.handle}` : '#');
+ return {
+ ...p,
+ product_url: productUrl,
+ sample_url: p.sample_url || `${productUrl}#sample`,
+ images: Array.isArray(p.images) && p.images.length ? p.images
+ : (p.image_url ? [p.image_url] : []),
+ };
+}
+
// ── Junk filter ──────────────────────────────────────────────────────────────
const JUNK_TITLE = /(lamp|rug|pillow|throw|tripod|frame|mirror|vase|candle|sculpture|figurine|stool|table|chair|sofa|curtain|bedding|towel|plate|bowl|mug)/i;
function isJunk(p) {
@@ -99,23 +120,39 @@ let PRODUCTS = [];
let DROPPED = 0;
let AESTHETICS = {};
-function loadData() {
+function applyProducts(raw) {
+ const clean = raw.map(shapeForSite).filter(p => !isJunk(p));
+ DROPPED = raw.length - clean.length;
+ PRODUCTS = clean;
+ AESTHETICS = {};
+ for (const p of PRODUCTS) {
+ AESTHETICS[p.aesthetic] = (AESTHETICS[p.aesthetic] || 0) + 1;
+ }
+}
+
+function loadFromJson() {
+ const raw = JSON.parse(fs.readFileSync(DATA_PATH, 'utf8'));
+ applyProducts(Array.isArray(raw) ? raw : []);
+}
+
+// PG-first load: read the curated catalog from dw_unified.microsite_products.
+// On any PG failure, fall back to the static data/products.json snapshot.
+async function loadData() {
try {
- const raw = JSON.parse(fs.readFileSync(DATA_PATH, 'utf8'));
- const clean = raw.filter(p => !isJunk(p));
- DROPPED = raw.length - clean.length;
- PRODUCTS = clean;
- AESTHETICS = {};
- for (const p of PRODUCTS) {
- AESTHETICS[p.aesthetic] = (AESTHETICS[p.aesthetic] || 0) + 1;
+ const rows = await catalog.getProducts(SITE_SLUG);
+ applyProducts(rows);
+ console.log(`Loaded ${PRODUCTS.length} products from dw_unified (dropped ${DROPPED} junk)`);
+ } catch (e) {
+ console.error(`PG catalog load failed (${e.message}) — falling back to data/products.json`);
+ try {
+ loadFromJson();
+ console.log(`Loaded ${PRODUCTS.length} products from JSON fallback (dropped ${DROPPED} junk)`);
+ } catch (e2) {
+ console.error('Failed to load products.json:', e2.message);
+ PRODUCTS = [];
}
- console.log(`Loaded ${PRODUCTS.length} products (dropped ${DROPPED} junk)`);
- } catch(e) {
- console.error('Failed to load products.json:', e.message);
- PRODUCTS = [];
}
}
-loadData();
const app = express();
app.set('trust proxy', 1);
@@ -530,4 +567,11 @@ ${THEME_TOGGLE_SCRIPT}
</body></html>`);
});
-app.listen(PORT, () => console.log(`carmelwallpapers listening on :${PORT}`));
+// ── Admin catalog CRUD — /admin/catalog (basic-auth) + /api/admin/* REST ─────
+catalog.mount(app, { siteSlug: SITE_SLUG, rails: SITE_RAILS });
+
+// ── Startup: load catalog from PG, then listen ───────────────────────────────
+(async () => {
+ await loadData();
+ app.listen(PORT, () => console.log(`carmelwallpapers listening on :${PORT}`));
+})();
← 5958e2e fix: wire vendor sort handler, add SKU option, drop dead Pri
·
back to Carmelwallpapers
·
Phase 2: mobile-ready + tap-to-reveal 76119fc →