← back to Council 0809 Builds

kravet-map-gate/map-gate.js

116 lines

#!/usr/bin/env node
/**
 * Kravet MAP Activation Gate  (Council idea #2, 2026-08-09)
 * ---------------------------------------------------------
 * Kravet-umbrella brands sell at MAP = wholesale × 1.5 (Kravet enforces it).
 * A batch push that activates at the generic cost/0.65/0.85 formula instead of
 * MAP creates a live MAP-compliance breach. This gate answers ONE question
 * before any status flip to ACTIVE:  "is this price >= MAP?"
 *
 * Two modes:
 *   report        - print current exposure (active Kravet SKUs priced < MAP)
 *   check <json>   - gate a proposed activation batch; exit 1 if any would breach
 *
 * READ-ONLY against the local dw_unified mirror. It never writes a price and
 * never flips a status — it is a guard other scripts call, not an executor.
 *
 * MAP source priority (per CLAUDE.md kravet-lines-price-at-map):
 *   1. kravet_authoritative_pricing.new_map   (loaded from the Kravet list)
 *   2. new_whls * 1.5  (derived, when map is null but whls is known)
 */
const { execFileSync } = require('child_process');

const KRAVET_VENDOR_RE =
  'kravet|lee jofa|brunschwig|groundworks|cole & son|baker|clarke|mulberry|' +
  'threads|gp ?& ?j|colefax|nicolette|aerin|barclay|thom filicia|andrew martin';

function q(sql) {
  const out = execFileSync(
    'psql',
    ['-h', '/tmp', '-d', 'dw_unified', '-tAF', '\t', '-c', sql],
    { encoding: 'utf8', env: { ...process.env, PATH: '/opt/homebrew/bin:' + process.env.PATH } }
  );
  return out.trim().split('\n').filter(Boolean).map((l) => l.split('\t'));
}

// Effective MAP per mfr_sku: explicit map, else whls*1.5
const MAP_EXPR = `COALESCE(kap.new_map, kap.new_whls * 1.5)`;

function report() {
  const rows = q(`
    WITH k AS (
      SELECT sp.dw_sku, sp.vendor, sp.mfr_sku, sp.price::numeric AS price,
             ${MAP_EXPR} AS map
      FROM shopify_products sp
      JOIN kravet_authoritative_pricing kap
        ON upper(trim(sp.mfr_sku)) = upper(trim(kap.mfr_sku))
       AND coalesce(trim(sp.mfr_sku),'') <> ''
      WHERE sp.status = 'ACTIVE' AND sp.vendor ~* '${KRAVET_VENDOR_RE}')
    SELECT
      count(*),
      count(*) FILTER (WHERE price < map - 0.01),
      count(*) FILTER (WHERE abs(price - 4.25) < 0.01)
    FROM k;`)[0];
  const [matched, belowMap, sampleLeak] = rows.map(Number);
  console.log(`Kravet MAP exposure (active, mfr_sku-matched):`);
  console.log(`  matched to authoritative pricing : ${matched}`);
  console.log(`  priced BELOW MAP (breach risk)   : ${belowMap}`);
  console.log(`  $4.25 sample leaking as sell price: ${sampleLeak}`);
  // worst offenders
  const worst = q(`
    WITH k AS (
      SELECT sp.dw_sku, sp.vendor, sp.price::numeric AS price, ${MAP_EXPR} AS map
      FROM shopify_products sp
      JOIN kravet_authoritative_pricing kap
        ON upper(trim(sp.mfr_sku)) = upper(trim(kap.mfr_sku))
       AND coalesce(trim(sp.mfr_sku),'') <> ''
      WHERE sp.status='ACTIVE' AND sp.vendor ~* '${KRAVET_VENDOR_RE}')
    SELECT dw_sku, vendor, price, round(map,2), round((map-price),2) AS short
    FROM k WHERE price < map - 0.01 ORDER BY (map-price) DESC LIMIT 10;`);
  if (worst.length) {
    console.log(`\n  Top 10 below-MAP (dw_sku | vendor | price | MAP | short-by):`);
    worst.forEach((r) => console.log('   ', r.join(' | ')));
  }
  return { matched, belowMap, sampleLeak };
}

/**
 * Gate a proposed activation batch.
 * batch = [{ mfr_sku, price }]  (the values a push is about to make ACTIVE)
 * Returns { ok, breaches: [{mfr_sku, price, map}] }.
 */
function check(batch) {
  if (!Array.isArray(batch) || !batch.length) return { ok: true, breaches: [] };
  const values = batch
    .map((b) => `('${String(b.mfr_sku).replace(/'/g, "''")}', ${Number(b.price)})`)
    .join(',');
  const rows = q(`
    WITH proposed(mfr_sku, price) AS (VALUES ${values})
    SELECT p.mfr_sku, p.price, round(${MAP_EXPR},2) AS map
    FROM proposed p
    JOIN kravet_authoritative_pricing kap
      ON upper(trim(p.mfr_sku)) = upper(trim(kap.mfr_sku))
    WHERE p.price < ${MAP_EXPR} - 0.01;`);
  const breaches = rows.map(([mfr_sku, price, map]) => ({ mfr_sku, price: +price, map: +map }));
  return { ok: breaches.length === 0, breaches };
}

if (require.main === module) {
  const [, , mode, arg] = process.argv;
  if (mode === 'check') {
    const batch = JSON.parse(arg || '[]');
    const res = check(batch);
    if (!res.ok) {
      console.error(`BLOCKED: ${res.breaches.length} SKU(s) would activate below MAP:`);
      res.breaches.forEach((b) =>
        console.error(`  ${b.mfr_sku}  price ${b.price} < MAP ${b.map}`));
      process.exit(1);
    }
    console.log(`OK: all ${batch.length} proposed activations are >= MAP.`);
  } else {
    report();
  }
}

module.exports = { check, report };