← back to Dw Add Sellable Variant Tk10902
tk10825-rollback.mjs
35 lines
#!/usr/bin/env node
// TK-10825 ROLLBACK — re-publish every product this ticket unpublished, from the ledger record.
// Reads tk10825-run-log.jsonl for action=='unpublished' rows and PUTs published=true back.
// Usage: node tk10825-rollback.mjs [--live] (default DRY-RUN)
import fs from 'fs';
import { execSync } from 'child_process';
const DOMAIN = 'designer-laboratory-sandbox.myshopify.com';
const API = '2024-10';
const TOKEN = execSync(`grep -E '^SHOPIFY_ADMIN_TOKEN=' ${process.env.HOME}/Projects/secrets-manager/.env | cut -d= -f2-`).toString().trim();
const LIVE = process.argv.includes('--live');
const RUNLOG = `${process.cwd()}/tk10825-run-log.jsonl`;
const base = `https://${DOMAIN}/admin/api/${API}`;
const hdr = { 'X-Shopify-Access-Token': TOKEN, 'Content-Type': 'application/json' };
const sleep = ms => new Promise(r => setTimeout(r, ms));
const rows = fs.readFileSync(RUNLOG, 'utf8').split('\n').filter(Boolean)
.map(JSON.parse).filter(r => r.action === 'unpublished');
console.log(`\n=== ${LIVE ? 'LIVE RE-PUBLISH' : 'DRY-RUN'} — ${rows.length} products to restore ===\n`);
let done = 0;
for (const r of rows) {
if (!LIVE) { console.log(`WOULD RE-PUBLISH ${r.pid} "${r.title}"`); done++; continue; }
for (let a = 0; a < 5; a++) {
const res = await fetch(`${base}/products/${r.pid}.json`, { method: 'PUT', headers: hdr, body: JSON.stringify({ product: { id: Number(r.pid), published: true } }) });
if (res.status === 429) { await sleep(2500); continue; }
console.log(`${res.status === 200 ? 'RE-PUBLISHED' : 'FAILED_' + res.status} ${r.pid} "${r.title}"`);
if (res.status === 200) done++;
break;
}
await sleep(600);
}
console.log(`\n=== DONE: restored=${done}/${rows.length} ===`);