← back to Dw Signup Fulfillment

verification/tk10836/verify-nonsample-scope.js

46 lines

#!/usr/bin/env node
// TK-11366 SCOPE TEST: is the checkout default-flip sample-specific, or store-wide?
// Same proxy that worked: abandoned checkouts record what the shopper was HANDED.
// Here: NON-sample (full-price) carts, before vs after 2026-08-18.
const fs=require('fs'),os=require('os');
for (const line of fs.readFileSync(os.homedir()+'/Projects/secrets-manager/.env','utf8').split('\n')) {
  const m=line.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*)$/); if(!m) continue;
  let v=m[2].trim().replace(/^['"]|['"]$/g,''); if(!process.env[m[1]]) process.env[m[1]]=v;
}
const STORE=process.env.SHOPIFY_STORE_DOMAIN, TOKEN=process.env.SHOPIFY_FULL_ACCESS_TOKEN, API='2024-10';
async function gql(q,v={}){const r=await fetch(`https://${STORE}/admin/api/${API}/graphql.json`,{method:'POST',
  headers:{'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v})});
  const j=await r.json(); if(j.errors)console.error('ERR',JSON.stringify(j.errors).slice(0,300)); return j.data;}
const Q=`query($c:String){ abandonedCheckouts(first:40, after:$c, query:"created_at:>2026-06-01", sortKey:CREATED_AT){
  pageInfo{hasNextPage endCursor}
  nodes{ createdAt subtotalPriceSet{shopMoney{amount}} totalPriceSet{shopMoney{amount}} totalTaxSet{shopMoney{amount}}
    shippingAddress{countryCodeV2}
    lineItems(first:20){ nodes{ title quantity variant{ sku } } } } } }`;
(async()=>{
  let c=null, samp=[], full=[];
  do{ const d=await gql(Q,{c}); if(!d) break;
    for(const a of d.abandonedCheckouts.nodes){
      const lis=a.lineItems.nodes; if(!lis.length) continue;
      if(a.shippingAddress?.countryCodeV2!=='US') continue;
      const isSample=li=>/(^|-)sample/i.test(li.variant?.sku||'')||/sample|memo|swatch/i.test(li.title||'');
      const allSample=lis.every(isSample), noSample=lis.every(li=>!isSample(li));
      const items=Number(a.subtotalPriceSet?.shopMoney?.amount||0);
      const total=Number(a.totalPriceSet?.shopMoney?.amount||0);
      const tax=Number(a.totalTaxSet?.shopMoney?.amount||0);
      const rec={date:a.createdAt.slice(0,10), items, ship:+(total-items-tax).toFixed(2)};
      if(allSample) samp.push(rec); else if(noSample) full.push(rec);
    } c=d.abandonedCheckouts.pageInfo.hasNextPage?d.abandonedCheckouts.pageInfo.endCursor:null; }while(c);
  const tab=(rows,lab)=>{
    console.log(`\n### ${lab} (US abandoned checkouts) ###`);
    for(const [w,lo,hi] of [['Jun 1 - Aug 17','2026-06-01','2026-08-17'],['Aug 18 - Sep 10','2026-08-18','2026-09-30']]){
      const s=rows.filter(r=>r.date>=lo&&r.date<=hi);
      const z=s.filter(r=>r.ship<=0.001).length;
      console.log(`  ${w}: n=${String(s.length).padStart(3)}  ship\$0.00=${String(z).padStart(3)} (${s.length?(100*z/s.length).toFixed(0):'-'}%)  medianShip=$${s.length?[...s.map(r=>r.ship)].sort((a,b)=>a-b)[Math.floor(s.length/2)].toFixed(2):'-'}`);
    }
  };
  tab(samp,'SAMPLE-ONLY carts  (control - known affected)');
  tab(full,'NON-SAMPLE / full-price carts  (the scope question)');
  console.log('\nNOTE: full-price carts legitimately pay shipping, so a low $0.00 rate is EXPECTED there.');
  console.log('The signal is whether the BEFORE/AFTER ratio shifts the way the sample cohort did.');
})();