← back to Customdigitalmurals
stage2: wire customdigitalmurals onto shared catalog (hand-tailored)
8e87abfb272661d72f8ec6e40ab7fa7f3bcdcb17 · 2026-05-19 11:07:56 -0700 · Steve Abrams
Files touched
M package.jsonM server.jsA site.config.json
Diff
commit 8e87abfb272661d72f8ec6e40ab7fa7f3bcdcb17
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue May 19 11:07:56 2026 -0700
stage2: wire customdigitalmurals onto shared catalog (hand-tailored)
---
package.json | 4 +++-
server.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
site.config.json | 15 +++++++++++++++
3 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index 64db1ea..915d9a2 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,8 @@
"start": "node server.js"
},
"dependencies": {
- "express": "^4.18.2"
+ "dotenv": "^16.4.5",
+ "express": "^4.18.2",
+ "pg": "^8.11.5"
}
}
diff --git a/server.js b/server.js
index 8dfec26..fcd00c0 100644
--- a/server.js
+++ b/server.js
@@ -6,13 +6,28 @@
* density slider, Cloudflare-aware, pm2 + systemd.
*/
'use strict';
+try { require('dotenv').config({ path: require('path').join(__dirname, '.env') }); } catch (e) {}
const express = require('express');
const path = require('path');
const fs = require('fs');
const PORT = process.env.PORT || 9896;
const DATA_FILE = path.join(__dirname, 'data', 'products.json');
-const ALL = JSON.parse(fs.readFileSync(DATA_FILE, 'utf8'));
+
+// Shared catalog module — read-path from dw_unified.microsite_products + admin CRUD.
+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 : [];
+
+// Static JSON snapshot — keeps the rich fields (images[], price, body_html) the
+// migration into microsite_products didn't carry over, and is the PG-down fallback.
+const STATIC = JSON.parse(fs.readFileSync(DATA_FILE, 'utf8'));
+const STATIC_BY_HANDLE = new Map(STATIC.map(p => [p.handle, p]));
+
+// ALL is populated async at startup (see bottom). Seed with the static snapshot
+// so the very first requests before PG resolves still have data.
+let ALL = STATIC;
const DW_BASE = 'https://designerwallcoverings.com';
const GA4_ID = process.env.GA4_MEASUREMENT_ID || '';
@@ -95,7 +110,40 @@ app.get('/sitemap.xml', (_req, res) => {
res.send(`<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls}\n</urlset>`);
});
-app.listen(PORT, () => console.log(`customdigitalmurals.com :${PORT}`));
+// Admin catalog CRUD — /admin/catalog (basic-auth) + /api/admin/* REST.
+catalog.mount(app, { siteSlug: SITE_SLUG, rails: SITE_RAILS });
+
+// Merge a PG microsite_products row with the rich static snapshot (by handle),
+// so the storefront still has images[], price and body_html the migration dropped.
+function enrich(row) {
+ const s = STATIC_BY_HANDLE.get(row.handle) || {};
+ return {
+ id: s.id,
+ title: row.title || s.title,
+ handle: row.handle,
+ vendor: row.vendor || s.vendor,
+ product_type: row.product_type || s.product_type,
+ tags: (Array.isArray(row.tags) && row.tags.length) ? row.tags : (s.tags || []),
+ body_html: s.body_html || '',
+ images: s.images || (row.image_url ? [row.image_url] : []),
+ price: row.max_price != null ? String(row.max_price) : (s.price || '0'),
+ dw_url: row.product_url || s.dw_url,
+ };
+}
+
+// Load the catalog from dw_unified, then start listening. PG down → JSON snapshot.
+(async () => {
+ try {
+ const rows = await catalog.getProducts(SITE_SLUG);
+ if (!rows.length) throw new Error('microsite_products returned 0 rows');
+ ALL = rows.map(enrich);
+ console.log(`[${SITE_SLUG}] loaded ${ALL.length} products from dw_unified`);
+ } catch (e) {
+ console.error(`[${SITE_SLUG}] PG catalog load failed (${e.message}) — using data/products.json`);
+ ALL = STATIC;
+ }
+ app.listen(PORT, () => console.log(`customdigitalmurals.com :${PORT} (${ALL.length} products)`));
+})();
// ── Templates ──────────────────────────────────────────────────────────────
diff --git a/site.config.json b/site.config.json
new file mode 100644
index 0000000..faa7d89
--- /dev/null
+++ b/site.config.json
@@ -0,0 +1,15 @@
+{
+ "slug": "customdigitalmurals",
+ "siteName": "Customdigitalmurals",
+ "domain": "customdigitalmurals.com",
+ "heroHeadline": "CUSTOMDIGITALMURALS",
+ "rails": [
+ "green",
+ "botanical",
+ "commercial",
+ "blue",
+ "architectural",
+ "white"
+ ],
+ "_generated": true
+}
← 31a4c17 initial scaffold: customdigitalmurals.com Off-White storefro
·
back to Customdigitalmurals
·
Phase 2: mobile-ready + tap-to-reveal 917bb01 →