← back to Tk10661 Product Seo

prove-one.mjs

30 lines

// TK-10661 PROVE-ON-ONE: reorder ONE product's variants (Sample -> last) and verify the
// storefront JSON-LD offer flips from $4.25 to the real price. Records rollback data first.
import {readFileSync, writeFileSync} from 'node:fs';
const txt=readFileSync(`${process.env.HOME}/Projects/secrets-manager/.env`,'utf8');
const env={}; for(const l of txt.split('\n')){const m=l.match(/^([A-Z0-9_]+)=(.*)$/); if(m) env[m[1]]=m[2].replace(/^["']|["']$/g,'');}
const STORE=env.SHOPIFY_STORE_DOMAIN, TOKEN=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:{'Content-Type':'application/json','X-Shopify-Access-Token':TOKEN},body:JSON.stringify({query:q,variables:v})});return await r.json();}
const HANDLE='feather-wallcovering-malibu-wallpaper-2';
// 1. read current variant order
const rd=await gql(`query($h:String!){productByHandle(handle:$h){id variants(first:50){nodes{id title position price}}}}`,{h:HANDLE});
const prod=rd.data.productByHandle; const vars=prod.variants.nodes;
console.log('BEFORE:', vars.map(v=>`${v.title}@${v.position}($${v.price})`).join(', '));
// record rollback (original id->position)
writeFileSync('data/rollback/'+prod.id.split('/').pop()+'.json', JSON.stringify({productId:prod.id,original:vars.map(v=>({id:v.id,position:v.position,title:v.title}))},null,2));
// 2. compute new order: non-Sample first (preserve relative order), Sample(s) last
const nonSample=vars.filter(v=>!/^sample$/i.test(v.title.trim()));
const sample=vars.filter(v=>/^sample$/i.test(v.title.trim()));
const ordered=[...nonSample,...sample];
const positions=ordered.map((v,i)=>({id:v.id,position:i+1}));
console.log('TARGET:', ordered.map((v,i)=>`${v.title}@${i+1}`).join(', '));
// 3. apply reorder
const mut=`mutation($pid:ID!,$pos:[ProductVariantPositionInput!]!){ productVariantsBulkReorder(productId:$pid,positions:$pos){ product{id} userErrors{field message} } }`;
const res=await gql(mut,{pid:prod.id,pos:positions});
const ue=res.data?.productVariantsBulkReorder?.userErrors||res.errors;
if(ue&&ue.length){ console.log('WRITE ERROR:', JSON.stringify(ue)); process.exit(1); }
console.log('REORDER APPLIED ok');
// 4. re-read admin to confirm
const rd2=await gql(`query($h:String!){productByHandle(handle:$h){variants(first:50){nodes{title position price}}}}`,{h:HANDLE});
console.log('AFTER(admin):', rd2.data.productByHandle.variants.nodes.map(v=>`${v.title}@${v.position}`).join(', '));