← back to Sample Followup Sweep

lib/slug-aliases.cjs

43 lines

'use strict';
// SINGLE SOURCE OF TRUTH for vendor slug derivation + deliberate routing aliases.
//
// Why this file exists (TK-11255): this table lived in TWO places —
// scripts/build-fleet.js (grouping) and scripts/scheduled-run.mjs (the vid->contact
// bridge) — and had ALREADY diverged: only the bridge knew that bare vid '1838' is
// the same vendor as '1838 Wallcoverings'. Two hand-maintained copies of one routing
// table is exactly the failure mode that produced SAND->'Sandberg', which sent
// Sanderson memo chases to Gimmersta, an unrelated company. One copy, or it drifts.
//
// A slug is normally DERIVED from the vid. The entries below intentionally route a
// vid to ANOTHER vendor's slug because that vendor's desk fulfils their samples.
// Adding a line is a deliberate routing decision; build-fleet.js FAILS THE BUILD on
// any undeclared duplicate slug.
const SLUG_ALIASES = {
  'ANNA FRENCH': 'thib',                // Anna French is distributed by Thibaut
  'ANNA': 'thib',                       // same vendor, short vid variant
  'ARTE': 'arte-international',         // Arte @ Egg & Dart
  'AS CREATION': 'san',                 // Sancar (AS Creation)
  'BM': 'green',                        // Greenland / bmwallpaper
  '1838': '1838-wallcoverings',         // bare vid + '1838 Wallcoverings' = one vendor (Scott Myer)
  '1838 WALLCOVERINGS': '1838-wallcoverings', // long vid spelling of the same vendor (declared to satisfy the dup-slug guard)
  'SCHUMACHER': 'sch',                  // long vid spelling = same vendor as 'SCH' (F. Schumacher). TK-11524:
                                        // this merge previously lived ONLY in build-fleet.js's local VID_ALIAS,
                                        // so scheduled-run.mjs's runtime contact bridge mapped raw vid
                                        // 'SCHUMACHER' -> slug 'schumacher' (no contact) -> ‹CONFIRM SAMPLE EMAIL›
                                        // skip-gap. 'sch' carries la-samples@schumacher.com + a no-chase disposition.
};

// FileMaker vid values carry stray CR/whitespace — a Kravet record's vid is literally
// "kra\r". Normalise before ANY keying or the lookup silently misses and that vendor's
// overdue sample is never chased.
function normVid(vid) {
  return String(vid == null ? '' : vid).replace(/[\r\n]/g, '').trim().toUpperCase();
}

function slugForVid(vid) {
  const v = normVid(vid);
  return SLUG_ALIASES[v] || v.toLowerCase().replace(/[^a-z0-9]+/g, '-');
}

module.exports = { SLUG_ALIASES, normVid, slugForVid };