← back to Dw Yolo Loop
orphan-collection LIVE re-scan (c41): TRUE empty count = 43 (c39's 4 was a feed-stale undercount)
d32d8a1d17ed4f71fbae14136afbf3a651f8ea7c · 2026-06-16 15:25:41 -0700 · Steve Abrams
Read-only, retry/backoff. c40 proved collections.json products_count is stale, so
c39 undercounted empties. Live per-collection products.json: 43 EMPTY (0 live), 27
near(<4), 507 ok(4+), 1 unknown of 578. Suspected products.json was a Boost
false-zero, but cross-checked the authoritative Boost PFS API (collection_scope by
id) — it ALSO returns 0 for samples, and 507/578 populate fine via the same probe,
so the 43 are REAL empties (stale feed count had masked them). Many are duplicate-
handle pairs (carlisle-co/carlisle-and-company, colefax-fowler/colefax-and-fowler,
nicolette-mayer x2). 3 leak collections persist (wallquest + nicolette-mayer x2).
Files touched
A scripts/orphan-collections/orphan-collection-livecount.mjs
Diff
commit d32d8a1d17ed4f71fbae14136afbf3a651f8ea7c
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jun 16 15:25:41 2026 -0700
orphan-collection LIVE re-scan (c41): TRUE empty count = 43 (c39's 4 was a feed-stale undercount)
Read-only, retry/backoff. c40 proved collections.json products_count is stale, so
c39 undercounted empties. Live per-collection products.json: 43 EMPTY (0 live), 27
near(<4), 507 ok(4+), 1 unknown of 578. Suspected products.json was a Boost
false-zero, but cross-checked the authoritative Boost PFS API (collection_scope by
id) — it ALSO returns 0 for samples, and 507/578 populate fine via the same probe,
so the 43 are REAL empties (stale feed count had masked them). Many are duplicate-
handle pairs (carlisle-co/carlisle-and-company, colefax-fowler/colefax-and-fowler,
nicolette-mayer x2). 3 leak collections persist (wallquest + nicolette-mayer x2).
---
.../orphan-collection-livecount.mjs | 50 ++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/scripts/orphan-collections/orphan-collection-livecount.mjs b/scripts/orphan-collections/orphan-collection-livecount.mjs
new file mode 100644
index 0000000..7947b6b
--- /dev/null
+++ b/scripts/orphan-collections/orphan-collection-livecount.mjs
@@ -0,0 +1,50 @@
+// orphan-collection-livecount (c41) — READ-ONLY. c40 proved collections.json
+// products_count is STALE (Nicolette Mayer showed 214, live=0), so c39's empty
+// list undercounted. This re-scans every live collection using the LIVE
+// /collections/<handle>/products.json count (limit=4 → classify 0 / 1-3 / 4+),
+// with retry/backoff to avoid the c38 UNKNOWN problem. $0.
+import fs from 'node:fs';
+const BASE='https://www.designerwallcoverings.com';
+const OUT=`${process.env.HOME}/.claude/yolo-queue/orphan-collections-LIVE-2026-06-16.json`;
+const MD =`${process.env.HOME}/.claude/yolo-queue/orphan-collections-LIVE-2026-06-16.md`;
+const sleep=ms=>new Promise(r=>setTimeout(r,ms));
+async function getj(url){
+ for(let a=0;a<5;a++){
+ try{ const r=await fetch(url,{signal:AbortSignal.timeout(15000)});
+ if(r.status===200) return await r.json();
+ if(r.status===404) return {__404:true};
+ if(r.status===429){await sleep(1500*(a+1));continue;} }
+ catch(e){ await sleep(1200*(a+1)); }
+ }
+ return null;
+}
+// 1) collection handles from feed
+const cols=[];
+for(let p=1;p<=20;p++){ const j=await getj(`${BASE}/collections.json?limit=250&page=${p}`); if(!j||!(j.collections||[]).length)break; cols.push(...j.collections.map(c=>({handle:c.handle,title:c.title,feed_count:c.products_count}))); await sleep(150); }
+// 2) live count each
+const empty=[], near=[], unknown=[]; let ok=0;
+for(const c of cols){
+ const j=await getj(`${BASE}/collections/${encodeURIComponent(c.handle)}/products.json?limit=4`);
+ if(j===null){ unknown.push(c.handle); await sleep(150); continue; }
+ const n = j.__404 ? 0 : (j.products||[]).length;
+ const is404 = !!j.__404;
+ if(n===0) empty.push({...c, live:0, http404:is404});
+ else if(n<4) near.push({...c, live:n});
+ else ok++;
+ await sleep(150);
+}
+const report={generated_at:new Date().toISOString(), scanned:cols.length, empty:empty.length, near_lt4:near.length, ok_4plus:ok, unknown:unknown.length,
+ empty_list:empty, near_list:near, unknown_handles:unknown};
+fs.writeFileSync(OUT,JSON.stringify(report,null,2));
+let md=`# Orphan-collection scan — LIVE counts (c41) — ${new Date().toISOString().slice(0,16)}\n\n`;
+md+=`**READ-ONLY (live per-collection /products.json, retry/backoff), \$0.** Corrects c39 (which used the STALE feed products_count, c40). ${cols.length} collections scanned.\n\n`;
+md+=`Empty (0 live) **${empty.length}** · near-empty (<4) **${near.length}** · ok (4+) **${ok}** · unknown **${unknown.length}**\n\n`;
+md+=`## EMPTY (0 live products) — ${empty.length}\n| handle | feed_count(stale) | http404 |\n|---|--:|:--:|\n`;
+for(const c of empty) md+=`| ${c.handle} | ${c.feed_count} | ${c.http404?'Y':''} |\n`;
+md+=`\n## NEAR-EMPTY (<4) — ${near.length}\n| handle | live |\n|---|--:|\n`;
+for(const c of near.slice(0,60)) md+=`| ${c.handle} | ${c.live} |\n`;
+fs.writeFileSync(MD,md);
+console.log(`[orphan-live] scanned=${cols.length} EMPTY=${empty.length} near(<4)=${near.length} ok=${ok} unknown=${unknown.length}`);
+console.log(' c39 said 4 empty (feed-count); live empties:');
+for(const c of empty) console.log(` ${c.handle} (feed said ${c.feed_count})`);
+console.log(`Report: ${MD}`);
← 5f0ef46 Kravet add-roll-variant writer: adds Sold-Per-Roll @ MAP to
·
back to Dw Yolo Loop
·
Kravet add-roll: harden width parser to extract leading numb ba1a136 →