← back to Dw Yolo Loop

scripts/price-render-audit/price-render-audit.mjs

87 lines

// price-render-audit — READ-ONLY, $0. Cycle 67 (DTD-picked A, unanimous).
// Price is the most direct revenue/trust defect on a storefront. Per the c66 lesson,
// measure at the RENDERED/EFFECTIVE layer — NOT the dw_unified mirror (price ~30% synced,
// unreliable). Sources: products.json variant prices (effective sellable prices) +
// the PDP JSON-LD offer price (what Google/shoppers see rendered).
// Classify each live product:
//   HEALTHY      — has a real sellable variant price (> sample floor)
//   BROKEN-ZERO  — ALL variants $0.00/null → genuinely unpriced/un-buyable (the defect)
//   SAMPLE-ONLY  — single variant == $4.25 → legitimate showroom-line (NOT broken; per
//                  showroom-lines-category) — classified out, not flagged
//   LD-RENDER-GAP— variants have a real price but the rendered JSON-LD offer price is 0/absent
// NEGATIVE CONTROL: print real prices the detector read (proves it parses prices) +
// confirm it flags a genuinely $0 product AND does NOT flag a legit $4.25 single-variant.
// EXCLUDES Phillip Jeffries.
const WWW='https://www.designerwallcoverings.com';
const UA='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36';
const sleep=ms=>new Promise(r=>setTimeout(r,ms));
async function get(u){for(let a=0;a<4;a++){try{const r=await fetch(u,{headers:{'User-Agent':UA}});if(r.status===429){await sleep(1500*(a+1));continue;}return {status:r.status,text:await r.text()};}catch(e){await sleep(800*(a+1));}}return {status:0,text:''};}
const PJ=/phillip[- ]?jeffries|phillip-jeffries/i;
function ldPrice(html){
  const blocks=[...html.matchAll(/<script type="application\/ld\+json">([\s\S]*?)<\/script>/g)].map(m=>m[1]);
  for(const b of blocks){ let j; try{j=JSON.parse(b);}catch{continue;}
    const cands=j['@graph']?j['@graph']:[j];
    for(const c of cands){ if(c['@type']==='Product'){ const o=Array.isArray(c.offers)?c.offers[0]:c.offers; if(o){ if(o.price!=null) return parseFloat(o.price); if(o.lowPrice!=null) return parseFloat(o.lowPrice); } } } }
  return null;
}

const idx=await get(`${WWW}/sitemap.xml`);
const prodMaps=[...idx.text.matchAll(/<loc>([^<]+sitemap_products_\d+\.xml[^<]*)<\/loc>/g)].map(m=>m[1].replace(/&amp;/g,'&')).filter(u=>!/\/en-(ca|gb)\//.test(u));
let handles=[];
for(const sm of prodMaps){ const x=await get(sm); const hs=[...x.text.matchAll(/<loc>[^<]*\/products\/([^<\/?]+)/g)].map(m=>m[1]); const step=Math.max(1,Math.floor(hs.length/8)); for(let i=0;i<hs.length&&handles.length<360;i+=step) handles.push(hs[i]); }
handles=[...new Set(handles)].filter(h=>!PJ.test(h)).slice(0,300);
console.log(`=== price-render-audit (READ-ONLY, $0) ===\nsampling ${handles.length} live products at the EFFECTIVE/RENDERED layer (PJ excluded)\n`);

let evald=0, healthy=0, brokenZero=0, sampleOnly=0, ldRenderGap=0, pjSkip=0, err=0;
const brokenSamples=[], healthySamples=[], gapSamples=[], problems=[];
let done=0, ldChecks=0;
for(const h of handles){
  const r=await get(`${WWW}/products/${h}.json`);
  let prod; try{ prod=JSON.parse(r.text).product; }catch{ err++; done++; continue; }
  if(!prod){ err++; done++; continue; }
  if(PJ.test(prod.vendor||'')||PJ.test(h)){ pjSkip++; done++; continue; }
  const vp=(prod.variants||[]).map(v=>({price:parseFloat(v.price),sku:v.sku,title:v.title})).filter(v=>!isNaN(v.price));
  if(vp.length===0){ err++; done++; continue; }
  evald++;
  const prices=vp.map(v=>v.price); const maxV=Math.max(...prices); const minV=Math.min(...prices);
  const nVar=vp.length;
  if(maxV===0){ brokenZero++; if(brokenSamples.length<10) brokenSamples.push({h,vendor:prod.vendor,prices}); problems.push({h,issue:'ALL-VARIANTS-$0',vendor:prod.vendor}); }
  else if(nVar===1 && maxV>0 && maxV<=4.25){ sampleOnly++; }
  else {
    healthy++;
    if(healthySamples.length<6) healthySamples.push({h,minV,maxV});
    // rendered-layer cross-check: does JSON-LD show a price for a product that HAS a real variant price?
    if(done%4===0){ // sample 1-in-4 for the (heavier) PDP fetch to bound cost/time
      const pdp=await get(`${WWW}/products/${h}`); ldChecks++;
      const ld=pdp.status===200?ldPrice(pdp.text):null;
      if(ld===0 || ld===null){ ldRenderGap++; if(gapSamples.length<8) gapSamples.push({h,ld,maxV}); problems.push({h,issue:`JSON-LD price ${ld===null?'ABSENT':'$0'} but variants up to $${maxV}`,vendor:prod.vendor}); }
      await sleep(80);
    }
  }
  done++;
  if(done%50===0) console.log(`  ${done}/${handles.length} (healthy=${healthy} broken-$0=${brokenZero} sample-only=${sampleOnly} ld-gap=${ldRenderGap}/${ldChecks})`);
  await sleep(70);
}

console.log(`\n=== RESULTS ===`);
console.log(`products evaluated: ${evald} | PJ-skip: ${pjSkip} | err: ${err}`);
console.log(`  HEALTHY (real sellable price): ${healthy}  (${evald?(100*healthy/evald).toFixed(1):0}%)`);
console.log(`  SAMPLE-ONLY (single variant $<=4.25, legit showroom-line — NOT broken): ${sampleOnly}`);
console.log(`  *** BROKEN-ZERO (all variants $0.00 — unpriced/un-buyable): ${brokenZero} ***`);
console.log(`\n-- rendered-layer cross-check (JSON-LD price on ${ldChecks} healthy PDPs) --`);
console.log(`  LD-RENDER-GAP (JSON-LD price \$0/absent while variants priced): ${ldRenderGap}/${ldChecks}`);
if(evald>0){
  const bad=brokenZero, p=bad/evald, se=Math.sqrt(p*(1-p)/evald), lo=Math.max(0,p-1.96*se)*100, hi=Math.min(1,p+1.96*se)*100;
  console.log(`\n*** BROKEN-ZERO price rate: ${bad}/${evald} = ${(100*p).toFixed(2)}%  (95% CI ${lo.toFixed(2)}–${hi.toFixed(2)}%, n=${evald}) ***`);
}
console.log(`\n-- NEGATIVE CONTROL (detector reads real prices) --`);
console.log(`  healthy price samples (detector parsed a real price):`); healthySamples.forEach(s=>console.log(`    ${s.h.slice(0,40)} → $${s.minV}–$${s.maxV}`));
console.log(`  broken-$0 detected: ${brokenZero>0?'yes ('+brokenSamples.length+' samples)':'NONE in sample'}`);
if(brokenSamples.length) brokenSamples.forEach(s=>console.log(`    $0: ${s.h.slice(0,42)} [${s.vendor}] prices=${JSON.stringify(s.prices)}`));
console.log(`  classifier correctly separates legit single-variant $4.25 showroom-lines: ${sampleOnly} excluded from broken`);
if(gapSamples.length){ console.log('\nLD-render-gap samples:'); gapSamples.forEach(s=>console.log(`    ${s.h.slice(0,40)} ld=${s.ld} maxVariant=$${s.maxV}`)); }

import fs from 'fs';
fs.writeFileSync('/tmp/price-render-audit.json',JSON.stringify({ts:new Date().toISOString(),sampled:handles.length,evald,healthy,sampleOnly,brokenZero,ldChecks,ldRenderGap,pjSkip,err,brokenSamples,healthySamples,gapSamples,problems},null,2));
console.log('\nwrote /tmp/price-render-audit.json');