← back to Wallco Ai

lib/mural-categories.js

50 lines

// 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 };