[object Object]

← back to Wolfgordon Crawl

Add unmatched-legacy analysis (174 weak-data, 614 discontinued, 1 recoverable)

5bbaafe5c6c27a3289ef1a2c12973e6bc799a919 · 2026-06-19 09:40:01 -0700 · Steve

Files touched

Diff

commit 5bbaafe5c6c27a3289ef1a2c12973e6bc799a919
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Jun 19 09:40:01 2026 -0700

    Add unmatched-legacy analysis (174 weak-data, 614 discontinued, 1 recoverable)
---
 unmatched-analysis.js | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/unmatched-analysis.js b/unmatched-analysis.js
new file mode 100644
index 0000000..3b27432
--- /dev/null
+++ b/unmatched-analysis.js
@@ -0,0 +1,58 @@
+#!/usr/bin/env node
+// Drill into the 789 unmatched legacy WG products (read-only).
+// Goal: distinguish genuine discontinues from recoverable patterns.
+const { pool } = require('./scraper-utils');
+
+function norm(s){return s?String(s).toLowerCase().replace(/[®™©]/g,'').replace(/&amp;/g,'&').replace(/[^a-z0-9]+/g,' ').replace(/\s+/g,' ').trim():'';}
+function nsku(s){return s?String(s).toLowerCase().replace(/_8$/,'').replace(/[^a-z0-9]+/g,''):'';}
+
+async function main(){
+  const cat = (await pool.query(`SELECT mfr_sku,pattern_name,color_name FROM wolf_gordon_catalog`)).rows;
+  const catNsku = new Set(cat.map(r=>nsku(r.mfr_sku)));
+  const catPat  = new Set(cat.map(r=>norm(r.pattern_name)));   // pattern-only catalog set
+  const catPC = new Set(cat.map(r=>`${norm(r.pattern_name)}|${norm(r.color_name)}`));
+
+  const leg = (await pool.query(`SELECT sku,mfr_sku,pattern_name,title,status FROM shopify_products WHERE vendor='Wolf Gordon'`)).rows;
+
+  const unmatched=[];
+  for(const r of leg){
+    const head=(r.title||'').split('|')[0].trim();
+    const ci=head.indexOf(' - ');
+    const color=ci===-1?null:head.slice(ci+3).trim();
+    if(catNsku.has(nsku(r.mfr_sku))) continue;
+    const pc=`${norm(r.pattern_name)}|${norm(color)}`;
+    if(color && catPC.has(pc)) continue;
+    unmatched.push({...r, color});
+  }
+
+  // Bucket the unmatched.
+  let patternStillExists=0, patternGone=0, patternIsSku=0;
+  const goneSamples=[], patStillSamples=[];
+  for(const u of unmatched){
+    const p=norm(u.pattern_name);
+    // pattern_name that is literally the SKU (weak legacy data)
+    if(nsku(u.pattern_name)===nsku(u.mfr_sku)){ patternIsSku++; continue; }
+    if(catPat.has(p)){ patternStillExists++; if(patStillSamples.length<12) patStillSamples.push(u); }
+    else { patternGone++; if(goneSamples.length<12) goneSamples.push(u); }
+  }
+
+  const byStatus={};
+  for(const u of unmatched) byStatus[u.status]=(byStatus[u.status]||0)+1;
+
+  console.log('UNMATCHED LEGACY ANALYSIS  (total '+unmatched.length+')');
+  console.log('='.repeat(64));
+  console.log('By Shopify status:');
+  for(const k of Object.keys(byStatus)) console.log('  '+k.padEnd(22)+byStatus[k]);
+  console.log('-'.repeat(64));
+  console.log('pattern_name is just the SKU (weak data):        '+patternIsSku);
+  console.log('pattern STILL EXISTS in catalog (color drifted): '+patternStillExists+'  <- likely recolored/renamed, recoverable');
+  console.log('pattern GONE from catalog entirely:              '+patternGone+'  <- genuine discontinue');
+  console.log('='.repeat(64));
+  console.log('\nSAMPLE — pattern still exists but exact color/sku drifted:');
+  for(const u of patStillSamples) console.log('  '+u.sku.padEnd(16)+(u.pattern_name+' / '+(u.color||'')).padEnd(34)+'status='+u.status);
+  console.log('\nSAMPLE — pattern gone (genuine discontinue):');
+  for(const u of goneSamples) console.log('  '+u.sku.padEnd(16)+(u.pattern_name+' / '+(u.color||'')).padEnd(34)+'status='+u.status);
+
+  await pool.end();
+}
+main().catch(e=>{console.error(e);process.exit(1);});

← 8c28e07 Assign sequential DW SKUs to 106 NULL WG catalog rows (DWWG-  ·  back to Wolfgordon Crawl  ·  Add reconciliation dry-run report + pricing-status finding 48267d6 →