← back to Dw Unbuyable Recovery Pilot

tk11252-hollywood/reverify-8.mjs

98 lines

#!/usr/bin/env node
// TK-11252 fork-1 — READ-ONLY re-verify of the 8 genuine dead-ends before the DRAFT write.
// For each of the 8: live Shopify status/handle/tags/variants + live PDP quoteCTA check.
// Writes prestate snapshot for clean re-activate undo. NO WRITES to Shopify here.
import { readFileSync, writeFileSync } from 'node:fs';
const TOKEN = readFileSync(new URL('/Users/macstudio3/Projects/secrets-manager/.env', 'file://'),'utf8')
  .split('\n').find(l=>l.startsWith('SHOPIFY_ADMIN_TOKEN=')).split('=').slice(1).join('=').trim();
const SHOP = 'designer-laboratory-sandbox.myshopify.com';
const API = '2024-10';

// The 8 genuine dead-ends (SKU -> numeric product id), from unbuyable-live.json @ 2026-09-14.
const TARGETS = [
  { sku:'A166-189', id:'7800001003571', handle:'aura-canvas-wallcovering' },
  { sku:'A166-322', id:'7800001036339', handle:'aura-lagoon-wallcovering' },
  { sku:'A166-421', id:'7800001101875', handle:'aura-sunset-wallcovering' },
  { sku:'A166-503', id:'7800001134643', handle:'aura-fresco-wallcovering' },
  { sku:'A166-545', id:'7800001167411', handle:'aura-desert-gem-wallcovering' },
  { sku:'A166-814', id:'7800001200179', handle:'aura-cirrus-wallcovering' },
  { sku:'A166-895', id:'7800001232947', handle:'aura-silverado-wallcovering' },
  { sku:'A125-356-261', id:'7799848108083', handle:'kibesillah-gulch-pewter-type-ii-vinyl-wallcovering' },
];

async function gql(query, variables){
  const r = await fetch(`https://${SHOP}/admin/api/${API}/graphql.json`, {
    method:'POST',
    headers:{'Content-Type':'application/json','X-Shopify-Access-Token':TOKEN},
    body: JSON.stringify({ query, variables }),
  });
  const j = await r.json();
  if (j.errors) throw new Error('GraphQL: '+JSON.stringify(j.errors));
  return j.data;
}

const Q = `query($id:ID!){
  product(id:$id){
    id legacyResourceId title handle status tags onlineStoreUrl
    variants(first:20){ nodes{ id sku title price } }
  }
}`;

async function checkPdp(handle){
  // follow redirects; a quote CTA renders the "Request a Quote" text
  try {
    const url = `https://designerwallcoverings.com/products/${handle}`;
    const r = await fetch(url, { redirect:'follow', headers:{'User-Agent':'Mozilla/5.0 tk11252-reverify'} });
    const html = await r.text();
    const finalUrl = r.url;
    const quoteCTA = /request a quote/i.test(html) ? 1 : 0;
    const addToCart = /add to cart|name="add"/i.test(html) ? 1 : 0;
    return { httpStatus:r.status, finalUrl, size:html.length, quoteCTA, addToCart };
  } catch(e){ return { error:String(e) }; }
}

const results = [];
for (const t of TARGETS){
  const gid = `gid://shopify/Product/${t.id}`;
  const d = await gql(Q, { id: gid });
  const p = d.product;
  const pdp = await checkPdp(p.handle);
  const nonSampleVariants = p.variants.nodes.filter(v => !/-sample$/i.test(v.sku||'') && !/^sample$/i.test(v.title||''));
  results.push({
    expectSku:t.sku, gid, legacyId:p.legacyResourceId, title:p.title, handle:p.handle,
    status:p.status, tags:p.tags,
    hasQuoteTag: p.tags.map(x=>x.toLowerCase()).includes('quotes'),
    variantCount:p.variants.nodes.length,
    variants:p.variants.nodes.map(v=>({sku:v.sku,title:v.title,price:v.price})),
    nonSampleVariantCount: nonSampleVariants.length,
    pdp,
  });
  await new Promise(r=>setTimeout(r,350));
}

// Determine which are still genuine dead-ends: ACTIVE + no quote tag + no quote CTA + sole variant = Sample
for (const r of results){
  r.stillDeadEnd = (r.status==='ACTIVE') && !r.hasQuoteTag &&
    (r.pdp && r.pdp.quoteCTA===0) && (r.nonSampleVariantCount===0) && (r.variantCount===1);
}

const out = { measured_at:new Date().toISOString(), n:results.length, results };
writeFileSync(new URL('./reverify-8-result.json','file://'+process.cwd()+'/'), JSON.stringify(out,null,2));

console.log('SKU            STATUS   qTag qCTA http  nonSampleV  soleVar  DEADEND');
for (const r of results){
  console.log(
    (r.expectSku).padEnd(14),
    (r.status||'?').padEnd(8),
    String(r.hasQuoteTag?'Y':'n').padEnd(4),
    String(r.pdp?.quoteCTA ?? '?').padEnd(4),
    String(r.pdp?.httpStatus ?? r.pdp?.error ?? '?').padEnd(5),
    String(r.nonSampleVariantCount).padEnd(11),
    String(r.variantCount===1?'Y':'n').padEnd(8),
    r.stillDeadEnd ? 'YES' : 'NO(skip)'
  );
}
const still = results.filter(r=>r.stillDeadEnd).length;
console.log(`\nSTILL-DEAD-END: ${still}/8  |  SKIP: ${8-still}/8`);
writeFileSync('/tmp/tk11252-still.txt', String(still));