← back to Dw Validator Debug TK11314
feat: add --below-cost mode to knoll-reprice.js (TK-10302 follow-up)
23966f88c6f2cd08f0ca7ec26091966e13d9edcf · 2026-08-09 04:12:10 -0700 · steve@designerwallcoverings.com
15 Knoll rolls (DWKN-250156-170: Drift/Drizzle/Elixir) are priced below cost
($29.50-$59 vs $53-$107 cost). The original at-cost mode skips them. New
--below-cost flag targets rolls where cur < cost and reprices to cost/0.65/0.85.
Steve-approved to add; `--commit` execution stays gated.
Files touched
M shopify/scripts/knoll-reprice.js
Diff
commit 23966f88c6f2cd08f0ca7ec26091966e13d9edcf
Author: steve@designerwallcoverings.com <steve@designerwallcoverings.com>
Date: Sun Aug 9 04:12:10 2026 -0700
feat: add --below-cost mode to knoll-reprice.js (TK-10302 follow-up)
15 Knoll rolls (DWKN-250156-170: Drift/Drizzle/Elixir) are priced below cost
($29.50-$59 vs $53-$107 cost). The original at-cost mode skips them. New
--below-cost flag targets rolls where cur < cost and reprices to cost/0.65/0.85.
Steve-approved to add; `--commit` execution stays gated.
---
shopify/scripts/knoll-reprice.js | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/shopify/scripts/knoll-reprice.js b/shopify/scripts/knoll-reprice.js
index 302c5954..0f0c65d3 100644
--- a/shopify/scripts/knoll-reprice.js
+++ b/shopify/scripts/knoll-reprice.js
@@ -7,16 +7,19 @@
* price ≈ its knoll_catalog cost (the bug signature). Any roll already priced != cost is
* SKIPPED (never touched). Never touches the Sample variant. Target is always > current.
*
- * node knoll-reprice.js # DRY (all)
- * node knoll-reprice.js 3 # DRY, first 3 (canary preview)
- * node knoll-reprice.js 3 --commit # CANARY: commit 3
- * node knoll-reprice.js --commit # commit all fixable
+ * node knoll-reprice.js # DRY (at-cost mode, all)
+ * node knoll-reprice.js 3 # DRY, first 3 canary preview
+ * node knoll-reprice.js 3 --commit # CANARY: commit 3
+ * node knoll-reprice.js --commit # commit all at-cost fixable
+ * node knoll-reprice.js --below-cost # DRY: show rolls priced BELOW cost
+ * node knoll-reprice.js --below-cost --commit # commit below-cost reprices (gated, Steve-approved)
*/
const https = require('https'); const fs = require('fs'); const os = require('os');
const { execFileSync } = require('child_process');
const argN = process.argv.find(a => /^\d+$/.test(a));
const N = argN ? parseInt(argN, 10) : Infinity;
const COMMIT = process.argv.includes('--commit');
+const BELOW_COST_MODE = process.argv.includes('--below-cost');
const SAMPLE = 4.25;
const COST_TOL = 0.02; // current price must be within 2¢ of cost to qualify
const TOKEN = (fs.readFileSync(os.homedir() + '/Projects/secrets-manager/.env', 'utf8').match(/^SHOPIFY_ADMIN_TOKEN=(.*)$/m) || [])[1].replace(/['"]/g, '').trim();
@@ -53,13 +56,21 @@ for (const line of psql("SELECT dw_sku, price_retail FROM knoll_catalog WHERE pr
if (!cost) { nocost.push(roll.sku); continue; }
const cur = parseFloat(roll.price);
const target = Math.round((cost / 0.65 / 0.85) * 100) / 100;
- if (Math.abs(cur - cost) <= COST_TOL && target > cur) fixable.push({ pid: n.id, roll, cost, cur, target, title: n.title });
- else skip_priced.push({ sku: roll.sku, cur, cost }); // already != cost → leave alone
+ if (BELOW_COST_MODE) {
+ // below-cost mode: catch rolls where current price < cost (selling at a loss)
+ if (cur < cost - COST_TOL && target > cur) fixable.push({ pid: n.id, roll, cost, cur, target, title: n.title });
+ else skip_priced.push({ sku: roll.sku, cur, cost });
+ } else {
+ // default mode: catch rolls priced AT cost (importer bug)
+ if (Math.abs(cur - cost) <= COST_TOL && target > cur) fixable.push({ pid: n.id, roll, cost, cur, target, title: n.title });
+ else skip_priced.push({ sku: roll.sku, cur, cost });
+ }
}
const list = Number.isFinite(N) ? fixable.slice(0, N) : fixable;
- console.log(`fixable (roll priced at cost) ${fixable.length} | skip already-repriced/other ${skip_priced.length} | no-cost ${nocost.length}`);
- list.slice(0, 6).forEach(t => console.log(` ${t.roll.sku} $${t.cur} (cost) → $${t.target} ${t.title.slice(0,38)}`));
- if (skip_priced.length) console.log(` e.g. skipped: ${skip_priced.slice(0,4).map(s=>s.sku+'@$'+s.cur).join(', ')}`);
+ const modeLabel = BELOW_COST_MODE ? 'roll priced BELOW cost' : 'roll priced at cost';
+ console.log(`fixable (${modeLabel}) ${fixable.length} | skip ${skip_priced.length} | no-cost ${nocost.length}`);
+ list.slice(0, 6).forEach(t => console.log(` ${t.roll.sku} $${t.cur} (cur, cost $${t.cost}) → $${t.target} ${t.title.slice(0,38)}`));
+ if (skip_priced.length && !BELOW_COST_MODE) console.log(` e.g. skipped: ${skip_priced.slice(0,4).map(s=>s.sku+'@$'+s.cur).join(', ')}`);
if (!COMMIT) { console.log(`\nDRY — --commit will reprice ${list.length} roll variants (Sample untouched).`); return; }
const M = `mutation($pid:ID!,$variants:[ProductVariantsBulkInput!]!){productVariantsBulkUpdate(productId:$pid,variants:$variants){userErrors{field message}}}`;
← 3d75135e auto-data-snapshot: 2026-08-09T03:04:53 (3 data files) — DW-
·
back to Dw Validator Debug TK11314
·
auto-data-snapshot: 2026-08-09T06:41:43 (1 data files) — sho 590c1c47 →