← back to Gmc 425 Supplemental Feed

spike-primary-feed.mjs

32 lines

#!/usr/bin/env node
/** spike-primary-feed.mjs — READ-ONLY diagnosis of SUPP_CANT_HELP products (Roll absent from feed).
 * For each, pull live Shopify variant order/availability to find WHY Google submitted only the Sample. */
import fs from 'node:fs';
const HOME=process.env.HOME, SHOP='designer-laboratory-sandbox';
const API=`https://${SHOP}.myshopify.com/admin/api/2024-10/graphql.json`;
const T=(fs.readFileSync(HOME+'/Projects/secrets-manager/.env','utf8').match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m)||[])[1].replace(/['"]/g,'').trim();
async function gql(q,v){const r=await fetch(API,{method:'POST',headers:{'X-Shopify-Access-Token':T,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v||{}})});return r.json();}
const rows=JSON.parse(fs.readFileSync(new URL('./out/sample-classification.json',import.meta.url),'utf8')).rows.filter(r=>r.classification==='SUPP_CANT_HELP');
const Q=`query($id:ID!){product(id:$id){title
  variants(first:20){nodes{id title position price availableForSale inventoryQuantity barcode}}}}`;
let samplePos1=0, rollUnavail=0, rollNoInv=0, sampleHasBarcode=0, rollHasBarcode=0, n=0;
const detail=[];
for(const r of rows){
  const j=await gql(Q,{id:`gid://shopify/Product/${r.pid}`}); const p=j.data?.product; if(!p)continue; n++;
  const vs=p.variants.nodes.map(v=>({...v,vid:v.id.split('/').pop(),pr:parseFloat(v.price)}));
  const sample=vs.find(v=>v.vid===r.sampleVid)||vs.find(v=>v.pr<=4.25);
  const roll=vs.find(v=>v.vid===r.rollVid)||vs.reduce((a,b)=>b.pr>a.pr?b:a,vs[0]);
  if(sample?.position===1) samplePos1++;
  if(roll && !roll.availableForSale) rollUnavail++;
  if(roll && (roll.inventoryQuantity||0)<=0) rollNoInv++;
  if(sample?.barcode) sampleHasBarcode++;
  if(roll?.barcode) rollHasBarcode++;
  if(detail.length<8) detail.push({title:p.title.slice(0,34),samplePos:sample?.position,rollPos:roll?.position,rollAvail:roll?.availableForSale,rollInv:roll?.inventoryQuantity,sampleBC:!!sample?.barcode,rollBC:!!roll?.barcode});
}
console.log(`SUPP_CANT_HELP analyzed: ${n}`);
console.log(`  sample is variant position 1 (default/first): ${samplePos1}/${n}  (${(100*samplePos1/n).toFixed(0)}%)`);
console.log(`  roll NOT availableForSale:                     ${rollUnavail}/${n}`);
console.log(`  roll inventoryQuantity <= 0:                   ${rollNoInv}/${n}`);
console.log(`  sample has barcode/GTIN: ${sampleHasBarcode}/${n} · roll has barcode/GTIN: ${rollHasBarcode}/${n}`);
console.log(`\nsample detail:`); detail.forEach(d=>console.log('  ',JSON.stringify(d)));