[object Object]

← back to Designer Wallcoverings

Carl Robinson: DW-less sequential SKU series (GRS-001, PWV-001, CORK-001…), map from live DWCR- for one-shot Shopify update

e6d41099a352ceda379d400e2c3bd86a42adaf3f · 2026-07-06 12:05:29 -0700 · steve@designerwallcoverings.com

Files touched

Diff

commit e6d41099a352ceda379d400e2c3bd86a42adaf3f
Author: steve@designerwallcoverings.com <steve@designerwallcoverings.com>
Date:   Mon Jul 6 12:05:29 2026 -0700

    Carl Robinson: DW-less sequential SKU series (GRS-001, PWV-001, CORK-001…), map from live DWCR- for one-shot Shopify update
---
 .../wallquest-refresh/remap-skus-carl-robinson.cjs | 45 +++++++++++++---------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/scripts/wallquest-refresh/remap-skus-carl-robinson.cjs b/scripts/wallquest-refresh/remap-skus-carl-robinson.cjs
index 056f30ba..cfe390c8 100644
--- a/scripts/wallquest-refresh/remap-skus-carl-robinson.cjs
+++ b/scripts/wallquest-refresh/remap-skus-carl-robinson.cjs
@@ -1,8 +1,9 @@
-// Re-assign Carl Robinson dw_sku with MATERIAL-BASED prefixes (Steve's directive 2026-07-06),
-// matching the Daisy Bennett scheme (grasscloth→DWGRS, paperweave→DWPWV, cork→DWCORK, mica→DWMIC…).
-// Beach-city DISPLAY names are unchanged — only the DW SKU code changes. Numeric tail = mfr CL number.
-// Updates: enriched+normalized JSON (in place), carl_robinson_catalog.dw_sku, and writes an
-// old→new map (+ shopify_product_id) for the gated Shopify variant-SKU update.
+// Re-assign Carl Robinson dw_sku: material-series prefix WITHOUT the "DW" (Steve 2026-07-06),
+// numbered SEQUENTIALLY within each series (GRS-001..GRS-014, PWV-001..PWV-019, CORK-001..).
+// Beach-city DISPLAY names unchanged — only the SKU code changes. Sequence order = mfr CL number.
+// Updates enriched+normalized JSON + carl_robinson_catalog.dw_sku, and writes an old→new map
+// where OLD = the SKU currently live on Shopify/registry (DWCR-<mfr>) so the gated Shopify
+// variant-SKU update jumps straight to the final scheme.
 const fs = require('fs');
 const { Client } = require('pg');
 const CONN = process.env.DATABASE_URL || 'postgresql://dw_admin@127.0.0.1:5432/dw_unified';
@@ -13,30 +14,36 @@ const MAPOUT = '/tmp/cr-sku-remap.json';
 const CODE = { Grasscloth:'GRS', Paperweave:'PWV', Raffia:'RAF', Sisal:'SIS', Cork:'CORK', Mica:'MIC',
   Netting:'NET', Bamboo:'BAM', Fiber:'FIB', Jute:'JUT', Nonwoven:'NWV', Silk:'SLK', 'Wood Veneer':'WDV' };
 const materialOf = p => (p || '').replace(/^white naturals\s*/i, '').trim() || 'Naturals';
-const newSku = (r) => { const mat = materialOf(r.pattern); const code = CODE[mat] || 'NAT';
-  const tail = (String(r.mfr_sku).match(/\d+/) || String(r.dw_sku).match(/\d+/) || ['0'])[0]; return { code, sku: `DW${code}-${tail}` }; };
+const numOf = r => parseInt((String(r.mfr_sku).match(/\d+/) || ['0'])[0], 10);
 
 (async () => {
   const enr = JSON.parse(fs.readFileSync(ENR, 'utf8'));
-  const map = [];       // {old, new, mfr}
+  // sequential per material, ordered by mfr number
+  const byMat = {};
+  for (const r of enr) (byMat[materialOf(r.pattern)] = byMat[materialOf(r.pattern)] || []).push(r);
+  const seqBySku = {};   // mfr_sku -> new sku
   const dist = {};
-  for (const r of enr) {
-    const old = r.dw_sku; const { code, sku } = newSku(r);
-    if (old !== sku) map.push({ old, new: sku, mfr: r.mfr_sku });
-    r.dw_sku = sku; dist[code] = (dist[code] || 0) + 1;
+  for (const [mat, rows] of Object.entries(byMat)) {
+    const code = CODE[mat] || 'NAT';
+    rows.sort((a, b) => numOf(a) - numOf(b));
+    rows.forEach((r, i) => { seqBySku[r.mfr_sku] = `${code}-${String(i + 1).padStart(3, '0')}`; });
+    dist[code] = rows.length;
   }
+  for (const r of enr) r.dw_sku = seqBySku[r.mfr_sku];
   fs.writeFileSync(ENR, JSON.stringify(enr, null, 2));
-  if (fs.existsSync(NORM)) { const n = JSON.parse(fs.readFileSync(NORM, 'utf8')); for (const r of n) r.dw_sku = newSku(r).sku; fs.writeFileSync(NORM, JSON.stringify(n, null, 2)); }
+  if (fs.existsSync(NORM)) { const n = JSON.parse(fs.readFileSync(NORM, 'utf8')); for (const r of n) if (seqBySku[r.mfr_sku]) r.dw_sku = seqBySku[r.mfr_sku]; fs.writeFileSync(NORM, JSON.stringify(n, null, 2)); }
 
-  // DB: update catalog dw_sku (keyed on mfr_sku) + pull shopify_product_id for the map
   const db = new Client({ connectionString: CONN }); await db.connect();
+  // update catalog dw_sku (keyed on mfr_sku)
   for (const r of enr) await db.query('UPDATE carl_robinson_catalog SET dw_sku=$1, updated_at=now() WHERE mfr_sku=$2', [r.dw_sku, r.mfr_sku]);
-  for (const m of map) { const q = await db.query('SELECT shopify_product_id FROM dw_sku_registry WHERE dw_sku=$1', [m.old]); m.shopify_product_id = q.rows[0]?.shopify_product_id || null; }
+  // build old→new map: OLD = current registry SKU (live on Shopify), matched by mfr_sku
+  const reg = await db.query("SELECT dw_sku, mfr_sku, shopify_product_id FROM dw_sku_registry WHERE mfr_sku = ANY($1)", [enr.map(r => r.mfr_sku)]);
+  const map = reg.rows.map(row => ({ old: row.dw_sku, new: seqBySku[row.mfr_sku], mfr: row.mfr_sku, shopify_product_id: row.shopify_product_id }))
+    .filter(m => m.new && m.old !== m.new);
   await db.end();
   fs.writeFileSync(MAPOUT, JSON.stringify(map, null, 2));
 
-  console.log('material-based SKU distribution:');
-  Object.entries(dist).sort((a, b) => b[1] - a[1]).forEach(([c, v]) => console.log(`  DW${c}-  ×${v}`));
-  console.log(`total=${Object.values(dist).reduce((a, b) => a + b, 0)} | remapped=${map.length} | with shopify id=${map.filter(m => m.shopify_product_id).length}`);
-  console.log(`map → ${MAPOUT}`);
+  console.log('sequential DW-less SKU series:');
+  Object.entries(dist).sort((a, b) => b[1] - a[1]).forEach(([c, v]) => console.log(`  ${c}-001 … ${c}-${String(v).padStart(3, '0')}  (${v})`));
+  console.log(`total=${Object.values(dist).reduce((a, b) => a + b, 0)} | map entries=${map.length} | with shopify id=${map.filter(m => m.shopify_product_id).length}`);
 })().catch(e => { console.error('ERROR', e.message); process.exit(1); });

← 83f25e3d Daisy Bennett: adjudicate flagged families — Diamond Back We  ·  back to Designer Wallcoverings  ·  Carl Robinson: 6-digit sequential SKU numbers (GRS-000001…) cf7d3da2 →