← back to Dw Unbuyable Recovery Pilot

tk10978-scalamandre/patch-buyable.mjs

31 lines

#!/usr/bin/env node
// TK-10978 — patch the pilot roll variants to be BUYABLE.
// The pilot created "Sold Per Roll" variants with inventory_policy='deny' +
// mgmt='shopify' + qty=0, which is UNBUYABLE (tracked, deny, zero stock). Fix:
// set inventory_policy='continue' so a made-to-order roll is always purchasable
// (matches the live Elitis "Sold Per Roll" buyable config). Reads prestate.jsonl.
// Usage: node patch-buyable.mjs [--live]   default = dry-run.
import { readFileSync } from 'node:fs';
import { execSync } from 'child_process';
const LIVE = process.argv.includes('--live');
const T = execSync(`grep -E '^SHOPIFY_ADMIN_TOKEN=' ${process.env.HOME}/Projects/secrets-manager/.env|cut -d= -f2-`).toString().trim();
const DOMAIN = 'designer-laboratory-sandbox.myshopify.com', API = '2024-10';
const hdr = { 'X-Shopify-Access-Token': T, 'Content-Type': 'application/json' };
const REST = `https://${DOMAIN}/admin/api/${API}`;
const lines = readFileSync(new URL('./data/prestate.jsonl', import.meta.url).pathname, 'utf8').trim().split('\n').map(JSON.parse);
const sleep = ms => new Promise(r => setTimeout(r, ms));
async function api(path, opts) { const r = await fetch(`${REST}${path}`, { headers: hdr, ...opts }); return { status: r.status, json: await r.json().catch(() => ({})) }; }
let n = 0, skip = 0;
for (const l of lines) {
  const { json } = await api(`/products/${l.pid}.json`, {});
  const vs = json.product?.variants || [];
  const roll = vs.find(v => (v.sku || '').toLowerCase() === l.rollSku.toLowerCase() && (v.option1 || '') === 'Sold Per Roll');
  if (!roll) { console.log('SKIP', l.pid, 'no roll variant'); skip++; continue; }
  if (roll.inventory_policy === 'continue') { console.log('SKIP', l.pid, l.rollSku, 'already continue'); skip++; continue; }
  if (!LIVE) { console.log('WOULD PATCH', l.pid, l.rollSku, `policy ${roll.inventory_policy}->continue`); continue; }
  const put = await api(`/variants/${roll.id}.json`, { method: 'PUT', body: JSON.stringify({ variant: { id: roll.id, inventory_policy: 'continue' } }) });
  if (put.status !== 200) { console.log('ERR', l.pid, put.status); continue; }
  n++; console.log('PATCHED', l.pid, l.rollSku, '-> continue (buyable)'); await sleep(500);
}
console.log(LIVE ? `patched ${n}, skipped ${skip}` : 'dry-run complete');