← back to Wallco Ai
mural categories never tile — helper + hard rule + fixed 12 misclassified rows (10 monterey-mural + 2 cactus-pine-scenic)
8c14be1da63f6151f523e29884a74da2a11925e7 · 2026-05-28 14:49:24 -0700 · Steve Abrams
Files touched
M CLAUDE.mdA lib/mural-categories.js
Diff
commit 8c14be1da63f6151f523e29884a74da2a11925e7
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu May 28 14:49:24 2026 -0700
mural categories never tile — helper + hard rule + fixed 12 misclassified rows (10 monterey-mural + 2 cactus-pine-scenic)
---
CLAUDE.md | 1 +
lib/mural-categories.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/CLAUDE.md b/CLAUDE.md
index 3a0e064..7faf8b4 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -57,6 +57,7 @@ Critical excludes (already in `.deploy.conf`) — these files ARE genuinely PROD
- **No "FLIEPAPER" word in any customer-facing surface.** Internal scaffold names (`src/fliepaper-bugs.js`) are exempt; rendered URLs / image filenames / category slugs go through redaction.
- **`/admin` routes are admin-gated.** `src/admin-gate.js` enforces basic-auth on every `/admin/*` and `/api/admin/*` route. Don't add a new admin route without the gate.
- **`data/designs.json` MUST NOT include `local_path`.** That column leaks `/Users/stevestudio2/…` via the public `/api/designs` endpoint. Use `localPathForDesign(d)` in server.js (filename-only basename) instead. See commit `6dbeb3b` reverting `a1dfbdd`.
+- **Mural categories are NEVER tileable.** Rows in `monterey-mural`, `cactus-pine-scenic`, `cactus-11ft-mural`, `cactus-accent-mural`, `tree-mural`, `mural-scenic` must have `kind='mural_panel'` (or `'mural'` for cactus-11ft-mural). Never `seamless_tile`. A misclassified row renders as a tiny repeating tile preview on /designs grid + PDP and looks broken. Canonical list + `assertMuralKind(kind, category)` helper live in `lib/mural-categories.js`. 2026-05-27 audit fixed 12 misclassified rows (10 monterey-mural + 2 cactus-pine-scenic).
## Generation backend
diff --git a/lib/mural-categories.js b/lib/mural-categories.js
new file mode 100644
index 0000000..0d56a10
--- /dev/null
+++ b/lib/mural-categories.js
@@ -0,0 +1,49 @@
+// mural-categories — canonical list of categories that are MURALS, not tiles.
+//
+// Hard rule (Steve directive 2026-05-27): rows in these categories MUST NEVER
+// have kind='seamless_tile'. They're scenic murals — single oversized images
+// meant to be viewed as one image, not tiled. Tile previews / room renders /
+// listing cards / PDP toggles all key off `kind`; a misclassified row shows up
+// as a small repeating tile preview and looks broken.
+//
+// Historical incident — 2026-05-27 audit found 12 misclassified rows
+// (10 monterey-mural + 2 cactus-pine-scenic) inserted as seamless_tile;
+// fixed in PG via UPDATE … SET kind='mural_panel'. Any generator that writes
+// into these categories MUST call assertMuralKind() at insert time or use
+// muralKindFor() to pick the right kind.
+//
+// Note: cactus-11ft-mural historically uses kind='mural' (not 'mural_panel').
+// Both are valid mural kinds and the PDP/listing renderers handle both. The
+// guard accepts either. Only 'seamless_tile' (and other tile kinds) is refused.
+
+const MURAL_CATEGORIES = new Set([
+ 'monterey-mural',
+ 'cactus-pine-scenic',
+ 'cactus-11ft-mural',
+ 'cactus-accent-mural',
+ 'tree-mural',
+ 'mural-scenic',
+]);
+
+const TILE_KINDS = new Set(['seamless_tile', 'tile', 'repeat_tile']);
+
+function isMuralCategory(category) {
+ return MURAL_CATEGORIES.has(String(category || '').toLowerCase().trim());
+}
+
+function assertMuralKind(kind, category) {
+ if (isMuralCategory(category) && TILE_KINDS.has(String(kind || '').toLowerCase().trim())) {
+ throw new Error(
+ `mural-categories: refusing to insert kind='${kind}' into category='${category}' — ` +
+ `mural categories are never tileable. Use kind='mural_panel' (or 'mural') instead. ` +
+ `See lib/mural-categories.js for the canonical list.`
+ );
+ }
+}
+
+function muralKindFor(category) {
+ if (!isMuralCategory(category)) return null;
+ return category === 'cactus-11ft-mural' ? 'mural' : 'mural_panel';
+}
+
+module.exports = { MURAL_CATEGORIES, TILE_KINDS, isMuralCategory, assertMuralKind, muralKindFor };
← 4ad23bc feat(design page): theme1/theme2 toggle, default theme2 onlo
·
back to Wallco Ai
·
rooms: add Mac2→prod auto-sync wrapper so room PNGs land on e4cb8b8 →