[object Object]

← back to Dw Unbuyable Recovery Pilot

TK-10978 RebelWalls: one-command archive rollback (restore prior status from prestate)

fe0b011fb4b0ba699824d7992c3b3a230ccfe4be · 2026-09-02 12:18:11 -0700 · steve

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit fe0b011fb4b0ba699824d7992c3b3a230ccfe4be
Author: steve <steve@designerwallcoverings.com>
Date:   Wed Sep 2 12:18:11 2026 -0700

    TK-10978 RebelWalls: one-command archive rollback (restore prior status from prestate)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 tk10978-rebelwalls/archive-rollback.mjs | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/tk10978-rebelwalls/archive-rollback.mjs b/tk10978-rebelwalls/archive-rollback.mjs
new file mode 100644
index 0000000..28e3608
--- /dev/null
+++ b/tk10978-rebelwalls/archive-rollback.mjs
@@ -0,0 +1,26 @@
+#!/usr/bin/env node
+// TK-10978 — REVERSE the Rebel Walls RS-orphan archive. For each product in
+// data/archive-prestate.jsonl, restore its prior status (active). Idempotent:
+// skips any product already back at its prior status.
+// Usage: node archive-rollback.mjs [--live]   default = dry-run (lists what it would restore).
+import { readFileSync } from 'node:fs';
+import { execSync } from 'child_process';
+const LIVE = process.argv.includes('--live');
+const TOKEN = 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 REST = `https://${DOMAIN}/admin/api/${API}`;
+const hdr = { 'X-Shopify-Access-Token': TOKEN, 'Content-Type': 'application/json' };
+const lines = readFileSync(new URL('./data/archive-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={}) { for(let a=0;a<6;a++){const r=await fetch(`${REST}${path}`,{headers:hdr,...opts}); if(r.status===429){await sleep(2500);continue;} return {status:r.status,json:await r.json().catch(()=>({}))};} return {status:429,json:{}}; }
+let n=0, skip=0;
+for (const l of lines) {
+  const g = await api(`/products/${l.pid}.json`);
+  const cur = g.json.product?.status;
+  if (cur === l.prior_status) { console.log('skip', l.pid, `already ${cur}`); skip++; continue; }
+  if (!LIVE) { console.log('WOULD RESTORE', l.pid, `${cur} -> ${l.prior_status}`, l.title); continue; }
+  const up = await api(`/products/${l.pid}.json`, { method:'PUT', body: JSON.stringify({ product:{ id:Number(l.pid), status:l.prior_status } }) });
+  if (up.status===200){ n++; console.log('restored', l.pid, `-> ${l.prior_status}`, l.title); } else { console.log('ERR', l.pid, up.status); }
+  await sleep(500);
+}
+console.log(LIVE ? `\nrestored ${n}, skipped ${skip} (of ${lines.length})` : `\ndry-run complete (${lines.length} in prestate)`);

← cdd5b64 auto-data-snapshot: 2026-09-02T12:07:47 (8 data files) — tk1  ·  back to Dw Unbuyable Recovery Pilot  ·  auto-data-snapshot: 2026-09-02T12:46:36 (1 data files) — tk1 1af16b4 →