← back to Dw Yolo Loop
TK-10210: fix false no_roll_variant_price exclusion in dw-yolo-loop feed-eligibility
86f28e838751e6026b0f225c0e0a29f09a63750a · 2026-08-05 04:06:08 -0700 · steve@designerwallcoverings.com
Port the TK-10209 fix from designerwallcoverings to dw-yolo-loop:
1. isSample now uses price-beats-label logic: a variant priced >$5 is a
real roll even if labeled "Sample" — fixes the Osborne W7351-01 class
where the sole roll variant was mislabeled "Size: Sample" @ $76.02,
causing rollPrice=null -> false no_roll_variant_price exclusion.
2. Wrap /tmp/cost_map.tsv readFileSync in try/catch: the file is GC-prone
and the script is designed to flag kravet_map_unverified_no_cost when
cost is missing — a hard crash here defeated that intent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Files touched
M scripts/google-feed/feed-eligibility.mjs
Diff
commit 86f28e838751e6026b0f225c0e0a29f09a63750a
Author: steve@designerwallcoverings.com <steve@designerwallcoverings.com>
Date: Wed Aug 5 04:06:08 2026 -0700
TK-10210: fix false no_roll_variant_price exclusion in dw-yolo-loop feed-eligibility
Port the TK-10209 fix from designerwallcoverings to dw-yolo-loop:
1. isSample now uses price-beats-label logic: a variant priced >$5 is a
real roll even if labeled "Sample" — fixes the Osborne W7351-01 class
where the sole roll variant was mislabeled "Size: Sample" @ $76.02,
causing rollPrice=null -> false no_roll_variant_price exclusion.
2. Wrap /tmp/cost_map.tsv readFileSync in try/catch: the file is GC-prone
and the script is designed to flag kravet_map_unverified_no_cost when
cost is missing — a hard crash here defeated that intent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---
scripts/google-feed/feed-eligibility.mjs | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/scripts/google-feed/feed-eligibility.mjs b/scripts/google-feed/feed-eligibility.mjs
index c86a7a9..22cc9be 100644
--- a/scripts/google-feed/feed-eligibility.mjs
+++ b/scripts/google-feed/feed-eligibility.mjs
@@ -39,10 +39,18 @@ const URL = `https://${SHOP}/admin/api/${VER}/graphql.json`;
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
// ---- cost map for Kravet MAP floor (from mirror; sparse is OK -> flagged unverified) ----
+// Tolerate an absent cost map: the file lives in /tmp and is GC-prone, and the
+// script is DESIGNED to flag `kravet_map_unverified_no_cost` per-product when cost
+// is missing. A hard readFileSync crash here defeats that intent (TK-10209).
const COST = new Map();
-for (const line of fs.readFileSync('/tmp/cost_map.tsv', 'utf8').trim().split('\n')) {
- const [gid, cost] = line.split('\t');
- if (gid) COST.set(gid, parseFloat(cost) || 0);
+try {
+ for (const line of fs.readFileSync('/tmp/cost_map.tsv', 'utf8').trim().split('\n')) {
+ const [gid, cost] = line.split('\t');
+ if (gid) COST.set(gid, parseFloat(cost) || 0);
+ }
+} catch (e) {
+ if (e.code !== 'ENOENT') throw e;
+ console.error('[warn] /tmp/cost_map.tsv absent -> Kravet MAP floor unverified for all (per-product flagged)');
}
// ---- rule constants ----
@@ -56,7 +64,16 @@ const PRIVATE_LABEL_LEAK = ['command54','command 54','wallquest','chesapeake','n
'seabrook','brewster','desima','carlsten','nicolette mayer'];
const norm = s => String(s == null ? '' : s).toLowerCase();
-const isSample = v => /(sample|memo|swatch)/i.test([v.title, v.sku].join(' ')) || /-sample$/i.test(v.sku || '');
+// A variant priced above this is a REAL sellable roll no matter what its option
+// label says. Fixes the false `no_roll_variant_price` on products whose single
+// full-roll-priced variant is mislabeled option "Size: Sample" (e.g. Osborne &
+// Little W7351-01 @ $76.02). Genuine $4.25 memo/swatch samples stay < this and are
+// still correctly treated as samples (TK-10209).
+const ROLL_PRICE_MIN = 5;
+const looksSample = v => /(sample|memo|swatch)/i.test([v.title, v.sku].join(' ')) || /-sample$/i.test(v.sku || '');
+// Classify as sample only when it LOOKS like a sample AND isn't priced like a real
+// roll. Price beats the label: a >$5 variant is a roll even if labeled "Sample".
+const isSample = v => looksSample(v) && !(parseFloat(v.price) > ROLL_PRICE_MIN);
async function gql(query, variables) {
for (let attempt = 0; attempt < 8; attempt++) {
← 5df288c Romo close: batch ledger + price-correction ledger + audit a
·
back to Dw Yolo Loop
·
gmc-feed-exclude: add --orphans-only (Bucket A / live-verifi 5795600 →