[object Object]

← back to Designerwallcoverings

Sanderson importer: repair X&Y pattern/color split for color: facet (TK-11070)

572262d2cc3f96b1e0c7368bcabe9d08d41923f3 · 2026-09-01 10:53:10 -0700 · Steve Abrams

Completes the color-tag root-cause fix. The scraper split 'X & Y ...' pattern
names at the first space (e.g. pattern_name='Bamboo & Birds', color_name='& Birds
China Blue /Lotus Pink'). cleanColorName() strips the leading '& <token>' prefix
iff pattern_name ends with that same '& <token>', normalizes slash spacing, and
returns '' (→ no color: facet emitted) when unresolvable — never a malformed one.
Preserves genuine '&' colorways (e.g. 'Rhubarb & Custard'). Matches the deterministic
repair used by the Wave-2 batch remediation (tk11070-remediate.mjs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 572262d2cc3f96b1e0c7368bcabe9d08d41923f3
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Sep 1 10:53:10 2026 -0700

    Sanderson importer: repair X&Y pattern/color split for color: facet (TK-11070)
    
    Completes the color-tag root-cause fix. The scraper split 'X & Y ...' pattern
    names at the first space (e.g. pattern_name='Bamboo & Birds', color_name='& Birds
    China Blue /Lotus Pink'). cleanColorName() strips the leading '& <token>' prefix
    iff pattern_name ends with that same '& <token>', normalizes slash spacing, and
    returns '' (→ no color: facet emitted) when unresolvable — never a malformed one.
    Preserves genuine '&' colorways (e.g. 'Rhubarb & Custard'). Matches the deterministic
    repair used by the Wave-2 batch remediation (tk11070-remediate.mjs).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 scripts/sanderson-onboard/build-payloads.mjs | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/scripts/sanderson-onboard/build-payloads.mjs b/scripts/sanderson-onboard/build-payloads.mjs
index 087e92d..386eb6b 100644
--- a/scripts/sanderson-onboard/build-payloads.mjs
+++ b/scripts/sanderson-onboard/build-payloads.mjs
@@ -42,6 +42,27 @@ const clean = s => String(s == null ? '' : s).replace(/wall\s*paper/ig, 'Wallcov
 // mixed case like "Rose/Cream", "101 Dalmatians", "V&A" (lowercasing-first would damage these).
 const titleCase = s => clean(s).replace(/\b\w/g, c => c.toUpperCase()).trim();
 const esc = s => String(s == null ? '' : s).replace(/[&<>"]/g, c => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;' }[c]));
+const decodeEnt = s => String(s == null ? '' : s).replace(/&amp;/g, '&').replace(/&#39;/g, "'").replace(/&quot;/g, '"');
+
+// Repair the scraper's "X & Y" pattern/color split (TK-11070). Patterns like "Bamboo & Birds" get
+// split at the first space → pattern_name="Bamboo & Birds", color_name="& Birds <colorway>". Strict
+// deterministic repair: iff color_name starts with "& <token>" AND pattern_name ends with "& <token>"
+// (same token), strip that prefix; normalize "A /B" → "A/B". Returns '' when unresolvable so the caller
+// emits NO color: facet (never a wrong one), matching the batch remediation logic.
+function cleanColorName(colorName, patternName) {
+  let c = decodeEnt(colorName).trim();
+  const pat = decodeEnt(patternName).trim();
+  if (!c) return '';
+  const mC = c.match(/^&\s+(\S+)\s+(.+)$/);
+  if (mC) {
+    const mP = pat.match(/&\s+(\S+)\s*$/);
+    if (mP && mP[1].toLowerCase() === mC[1].toLowerCase()) c = mC[2].trim();
+    else return '';
+  }
+  c = c.replace(/\s*\/\s*/g, '/').replace(/\s+/g, ' ').trim();
+  if (!c || /^&/.test(c) || c.length > 40) return '';
+  return c;
+}
 
 function rows() {
   const cols = `id, mfr_sku, dw_sku, pattern_name, color_name, collection, width, roll_length,
@@ -70,8 +91,10 @@ function tags(r) {
   if (!bad(r.collection)) t.add(titleCase(r.collection));
   if (!bad(r.material)) t.add(titleCase(r.material));
   // color: facet MUST come from the REAL scraped colorway (color_name), NOT AI vision guess (TK-11070).
-  // Falls back gracefully to nothing (never emits a wrong color:) if the real colorway is missing.
-  if (!bad(r.color_name)) t.add('color:' + titleCase(r.color_name));
+  // cleanColorName repairs the "X & Y" pattern/color split and returns '' when unresolvable, so we
+  // emit NO color: facet rather than a wrong/malformed one.
+  const cw = cleanColorName(r.color_name, r.pattern_name);
+  if (cw) t.add('color:' + titleCase(cw));
   // NOTE (TK-11070): ai_colors palette names below (Alabaster/Sky/Duck Egg …) are DEMOTED — they were
   // producing stray-colorway pollution tags. They are no longer added as bare tags; the color: facet is
   // now the single authoritative colorway. Palette hues remain available via custom.color_details metafield.

← 349d204 Sanderson importer: fix color-tag source + selective image d  ·  back to Designerwallcoverings  ·  Sanderson TK-11070 batch-remediation + rollback scripts d3e1577 →