[object Object]

← back to Hollywood Import

scrub: emit ALL images (all_images array) + completeness gate, not just primary (Steve: all SKUs must have all images/data)

402ee5e8b78ea96ba004fb571270a87156e859da · 2026-06-10 07:00:24 -0700 · SteveStudio2

Files touched

Diff

commit 402ee5e8b78ea96ba004fb571270a87156e859da
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date:   Wed Jun 10 07:00:24 2026 -0700

    scrub: emit ALL images (all_images array) + completeness gate, not just primary (Steve: all SKUs must have all images/data)
---
 scrub-momentum.js | 22 ++++++++++++++++++----
 verify2.js        | 10 ++++++++++
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/scrub-momentum.js b/scrub-momentum.js
index 26f693a..aeee14d 100644
--- a/scrub-momentum.js
+++ b/scrub-momentum.js
@@ -36,22 +36,36 @@ function scrubMomentum(row) {
     pubSpecs[k] = (typeof v === 'string') ? scrubText(v) : v;
   }
   const tags = scrubText(specs.tags || '').split(',').map(t => t.trim()).filter(Boolean);
+  // ALL images, not just primary (Steve: "always pull all data and images" —
+  // every Hollywood/Momentum SKU must carry every image). Parse all_images
+  // (JSON array or comma/newline list), prepend primary, dedupe.
+  let imgs = [];
+  if (row.all_images) {
+    try { const a = JSON.parse(row.all_images); if (Array.isArray(a)) imgs = a; } catch { imgs = String(row.all_images).split(/[,\n]/); }
+  }
+  if (row.image_url) imgs.unshift(row.image_url);
+  const images = [...new Set(imgs.map(s => String(s || '').trim()).filter(Boolean))];
+  // completeness gate — importer MUST refuse rows that aren't fully crawled
+  // (need all images + core data). false → re-crawl the full page first.
+  const complete = images.length > 0 && !!row.pattern_name && !!row.mfr_sku && !!(specs && Object.keys(specs).length);
   return {
     vendor:     specs.pl_brand || 'Hollywood Wallcoverings',
     title:      scrubText(row.pattern_name) + (row.color_name ? ', ' + scrubText(row.color_name) : ''),
     collection: specs.pl_city_name ? scrubText(specs.pl_city_name) : (row.collection ? scrubText(row.collection) : null),
     sku:        row.dw_sku,
     mfr_sku:    row.mfr_sku,
-    imageSrc:   row.image_url,   // TRANSIENT push src only — Shopify rehosts; excluded from leak check
+    images,                       // ALL images — TRANSIENT push srcs, Shopify rehosts; excluded from leak check
+    imageCount: images.length,
+    complete,                     // false = NOT import-ready
     tags,
     specs:      pubSpecs,
   };
 }
 
-// Leak check: scan every customer-facing field EXCEPT imageSrc (its momentum URL
-// is the sanctioned transient source Shopify launders). Returns array of leaks.
+// Leak check: scan every customer-facing field EXCEPT the image URLs (their
+// momentum CDN host is the sanctioned transient source Shopify launders). Leaks.
 function leakCheck(pub) {
-  const { imageSrc, ...rest } = pub;
+  const { images, imageSrc, ...rest } = pub;
   const hay = JSON.stringify(rest);
   const hits = hay.match(/momentum|versa/gi) || [];
   return hits;
diff --git a/verify2.js b/verify2.js
new file mode 100644
index 0000000..7e0ce39
--- /dev/null
+++ b/verify2.js
@@ -0,0 +1,10 @@
+const { spawnSync } = require('child_process');
+const { scrubMomentum, leakCheck } = require('./scrub-momentum');
+const PSQL='/opt/homebrew/opt/postgresql@14/bin/psql';
+const sql=`SELECT json_agg(t) FROM (SELECT id,pattern_name,color_name,collection,dw_sku,mfr_sku,image_url,all_images,specs
+  FROM vendor_catalog WHERE vendor_code='hollywood'
+   AND (sync_status='new' OR (on_shopify IS NOT TRUE AND shopify_product_id IS NULL)) AND mfr_sku IS NOT NULL) t`;
+const rows=JSON.parse(spawnSync(PSQL,['-U','stevestudio2','-d','dw_unified','-tA','-c',sql],{encoding:'utf8',maxBuffer:1<<30}).stdout||'[]')||[];
+let leaks=0,complete=0,multiImg=0,oneImg=0;
+for(const r of rows){const p=scrubMomentum(r);if(leakCheck(p).length)leaks++;if(p.complete)complete++;if(p.imageCount>1)multiImg++;else oneImg++;}
+console.log('netnew rows:',rows.length,'| leaks:',leaks,'| complete:',complete,'| >1 image:',multiImg,'| exactly 1 image:',oneImg);

← 6e3a6a3 scrubMomentum(): Momentum→Hollywood private-label scrub + ve  ·  back to Hollywood Import  ·  Momentum (Hollywood) authed crawler + Group-1 price staging a13162a →