[object Object]

← back to Designer Wallcoverings

Read-only overnight Kravet price monitor: diff live vs authoritative MAP, classify BELOW_MAP/CORRUPTION_SUSPECT (no live writes)

e7a0a4b339c37f2c90e88c41178759eb2ade673d · 2026-06-11 19:04:54 -0700 · SteveStudio2

Files touched

Diff

commit e7a0a4b339c37f2c90e88c41178759eb2ade673d
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Thu Jun 11 19:04:54 2026 -0700

    Read-only overnight Kravet price monitor: diff live vs authoritative MAP, classify BELOW_MAP/CORRUPTION_SUSPECT (no live writes)
---
 shopify/scripts/cadence/kravet-price-monitor.js | 87 +++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/shopify/scripts/cadence/kravet-price-monitor.js b/shopify/scripts/cadence/kravet-price-monitor.js
new file mode 100644
index 00000000..a41486f3
--- /dev/null
+++ b/shopify/scripts/cadence/kravet-price-monitor.js
@@ -0,0 +1,87 @@
+#!/usr/bin/env node
+/**
+ * kravet-price-monitor.js — READ-ONLY overnight watchdog.
+ *
+ * Context (2026-06-11): kravet_master_price was found CORRUPT ($1014 for Entangle vs the
+ * authoritative GDrive master's $374), and a parallel agent (reprice-restore-kravet.js on
+ * Kamatera) pushed wrong prices ($1521) to LIVE Shopify. This monitor does NOT write to
+ * Shopify. It pulls live Kravet-family prices in rolling batches, diffs each against the
+ * isolated authoritative reference (kravet_map_authoritative, MAP = wholesale × 1.5), and
+ * logs every mismatch to kravet_price_mismatch so Steve has a corrective worklist by morning.
+ *
+ * Resumes across runs via a cursor row in kravet_monitor_state. Safe to run on a loop.
+ */
+const https = require('https');
+const fs = require('fs');
+const os = require('os');
+const { execFileSync } = require('child_process');
+
+const BATCH = parseInt((process.argv.find((a,i)=>process.argv[i-1]==='--batch')||'150'),10);
+const DEV_FLAG = 0.10; // flag if live price deviates >10% from authoritative MAP
+
+const psql = sql => execFileSync('psql', ['-d','dw_unified','-At','-F','\t','-c',sql],
+  { encoding:'utf8', maxBuffer:1<<28 }).trim();
+const sleep = ms => new Promise(r=>setTimeout(r,ms));
+const env = fs.readFileSync(os.homedir()+'/Projects/secrets-manager/.env','utf8');
+const TOKEN = (env.match(/^SHOPIFY_ADMIN_TOKEN=(.*)$/m)||[])[1].replace(/['"]/g,'').trim();
+const STORE='designer-laboratory-sandbox.myshopify.com', API='2024-10';
+function gql(q,v){return new Promise(res=>{const d=JSON.stringify({query:q,variables:v});
+  const r=https.request({host:STORE,path:`/admin/api/${API}/graphql.json`,method:'POST',
+    headers:{'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json','Content-Length':Buffer.byteLength(d)}},
+    x=>{let b='';x.on('data',c=>b+=c);x.on('end',()=>{try{res(JSON.parse(b))}catch{res({})}})});
+  r.on('error',()=>res({}));r.write(d);r.end();});}
+
+function ddl(){
+  psql(`CREATE TABLE IF NOT EXISTS kravet_price_mismatch(
+    mfr_sku text PRIMARY KEY, shopify_id text, variant_title text, live_price numeric,
+    authoritative_map numeric, deviation_pct numeric, note text, ts timestamptz DEFAULT now());
+  CREATE TABLE IF NOT EXISTS kravet_monitor_state(k text PRIMARY KEY, v text);`);
+}
+
+(async()=>{
+  ddl();
+  // rolling cursor over distinct Kravet-family wallcovering products that we have an authoritative MAP for
+  const cursor = psql(`SELECT v FROM kravet_monitor_state WHERE k='cursor'`) || '0';
+  const rows = psql(`
+    WITH cand AS (
+      SELECT DISTINCT s.shopify_id, s.mfr_sku, a.map_price
+        FROM shopify_products s
+        JOIN kravet_map_authoritative a ON upper(trim(a.mfr_sku))=upper(trim(s.mfr_sku))
+       WHERE s.vendor ~* 'kravet|lee ?jofa|groundworks|brunschwig|baker|mulberry|threads|clarke|cole|gp ?& ?j|colefax|nicolette'
+         AND s.product_type ~* 'wallcover' AND a.map_price>0)
+    SELECT shopify_id, mfr_sku, map_price FROM cand
+     WHERE shopify_id > '${cursor.replace(/'/g,"")}' ORDER BY shopify_id LIMIT ${BATCH}`).trim();
+  if(!rows){ psql(`INSERT INTO kravet_monitor_state(k,v) VALUES('cursor','0') ON CONFLICT(k) DO UPDATE SET v='0'`);
+    console.log('cursor wrapped to start; no rows this pass'); return; }
+  const list = rows.split('\n').map(l=>{const[shopify_id,mfr_sku,map]=l.split('\t');return{shopify_id,mfr_sku,map:parseFloat(map)};});
+  let checked=0, flagged=0, lastId=cursor;
+  for(const c of list){
+    const id = c.shopify_id.startsWith('gid://')?c.shopify_id:'gid://shopify/Product/'+c.shopify_id;
+    const r = await gql(`query($id:ID!){product(id:$id){variants(first:20){nodes{title sku price}}}}`,{id});
+    const p = r.data && r.data.product;
+    lastId = c.shopify_id;
+    if(!p){ continue; }
+    // the roll (non-sample) variant's live price
+    const roll = p.variants.nodes.find(v=>!/sample/i.test(v.sku||'') && !/^sample$/i.test(v.title||''));
+    if(!roll){ continue; }  // sample-only, nothing priced to check
+    checked++;
+    const live = parseFloat(roll.price);
+    const dev = (live - c.map) / c.map;   // signed: negative = below MAP
+    // MAP is a FLOOR — above MAP is legitimate retail. Only flag:
+    //   BELOW_MAP        : live < 95% of MAP   (MAP violation / underpriced, incl $4.25 rolls)
+    //   CORRUPTION_SUSPECT: live > 2× MAP      (e.g. the $1014/$1521 corruption)
+    let cls = null;
+    if (live < c.map * 0.95) cls = 'BELOW_MAP';
+    else if (live > c.map * 2.0) cls = 'CORRUPTION_SUSPECT';
+    if (cls){
+      flagged++;
+      psql(`INSERT INTO kravet_price_mismatch(mfr_sku,shopify_id,variant_title,live_price,authoritative_map,deviation_pct,note)
+        VALUES('${c.mfr_sku.replace(/'/g,"''")}','${c.shopify_id}','${(roll.title||'').replace(/'/g,"''")}',${live},${c.map},${(dev*100).toFixed(1)},'${cls}')
+        ON CONFLICT(mfr_sku) DO UPDATE SET live_price=${live}, authoritative_map=${c.map}, deviation_pct=${(dev*100).toFixed(1)}, note='${cls}', ts=now();`);
+    }
+    await sleep(220);
+  }
+  psql(`INSERT INTO kravet_monitor_state(k,v) VALUES('cursor','${lastId.replace(/'/g,"")}') ON CONFLICT(k) DO UPDATE SET v='${lastId.replace(/'/g,"")}'`);
+  const totalFlagged = psql(`SELECT count(*) FROM kravet_price_mismatch`);
+  console.log(`pass: checked ${checked} priced rolls, flagged ${flagged} new mismatches (cumulative ${totalFlagged}); cursor -> ${lastId}`);
+})();

← 828450a0 schu-cost-ingest: add --dry (exercise UPDATEs in a txn then  ·  back to Designer Wallcoverings  ·  Morning summary of overnight Kravet price audit (CNCP + noti 0de24336 →