← back to Tk10895 GroupB

erica/audit-tranche-c.mjs

46 lines

import fs from 'node:fs';
const TOK=fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8')
  .split('\n').find(l=>l.startsWith('SHOPIFY_ADMIN_TOKEN='))?.split('=').slice(1).join('=').trim();
const SHOP='designer-laboratory-sandbox.myshopify.com',API='2024-10';
const retail=c=>(Math.round((c/0.65/0.85)*100)/100).toFixed(2);
const cand=JSON.parse(fs.readFileSync('tranche-c-candidates.json','utf8'));
const entries=Object.entries(cand);
const q=`query($ids:[ID!]!){ nodes(ids:$ids){ ... on Product { legacyResourceId title status handle
  variants(first:25){ edges{ node{ id title price position sku } } } } } }`;
const byPid={};
for(let i=0;i<entries.length;i+=50){
  const chunk=entries.slice(i,i+50);
  const r=await fetch(`https://${SHOP}/admin/api/${API}/graphql.json`,{method:'POST',
    headers:{'X-Shopify-Access-Token':TOK,'Content-Type':'application/json'},
    body:JSON.stringify({query:q,variables:{ids:chunk.map(([,v])=>`gid://shopify/Product/${v.pid}`)}})});
  const j=await r.json();
  if(j.errors){console.error(JSON.stringify(j.errors));process.exit(1);}
  for(const n of j.data.nodes) if(n) byPid[n.legacyResourceId]=n;
  await new Promise(s=>setTimeout(s,400));
}
const buckets={sample_only:[],live_correct:[],live_wrong:[],no_product:[],draft:[]};
for(const [mfr,v] of entries){
  const n=byPid[v.pid];
  if(!n){buckets.no_product.push({mfr,...v});continue;}
  const vs=n.variants.edges.map(e=>e.node).sort((a,b)=>a.position-b.position);
  const sell=vs.find(x=>parseFloat(x.price)>10);
  const want=retail(v.cost);
  const rec={mfr,...v,pid:n.legacyResourceId,handle:n.handle,status:n.status,title:n.title,
             want,live:sell?sell.price:null,variant_id:sell?sell.id:null,
             nvariants:vs.length,pos1:vs[0]?.title,pos1price:vs[0]?.price};
  if(!sell) (n.status==='DRAFT'?buckets.draft:buckets.sample_only).push(rec);
  else if(sell.price===want) buckets.live_correct.push(rec);
  else buckets.live_wrong.push(rec);
}
for(const [k,v] of Object.entries(buckets)) console.log(`${k.padEnd(14)} ${v.length}`);
console.log('\n--- live_wrong (repriceable) ---');
for(const r of buckets.live_wrong.slice(0,25))
  console.log(`  ${r.mfr.padEnd(12)} ${r.cohort.padEnd(19)} ${r.status.padEnd(7)} live=$${r.live} want=$${r.want}  ${r.pattern.slice(0,26)}`);
console.log('\n--- sample_only ACTIVE (need sellable variant created) ---');
const cs={}; for(const r of buckets.sample_only) cs[r.cohort]=(cs[r.cohort]||0)+1;
console.log('  by cohort:',cs);
for(const r of buckets.sample_only.slice(0,10))
  console.log(`  ${r.mfr.padEnd(12)} ${r.status.padEnd(7)} want=$${r.want} w=${r.width}  ${r.pattern.slice(0,30)}`);
fs.writeFileSync('tranche-c-live.json',JSON.stringify(buckets,null,1));
console.log('\nwrote tranche-c-live.json');