← back to Designerwallcoverings
WM reprice: add one-command revert.mjs (restores old prices from restore-map, TK-11814)
c7cb7c832477e6686578a47acffc481d7ea34be9 · 2026-09-16 08:55:17 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DsSmHLJqGWrvjf65UNVQx
Files touched
A scripts/wm-reprice/revert.mjs
Diff
commit c7cb7c832477e6686578a47acffc481d7ea34be9
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 16 08:55:17 2026 -0700
WM reprice: add one-command revert.mjs (restores old prices from restore-map, TK-11814)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DsSmHLJqGWrvjf65UNVQx
---
scripts/wm-reprice/revert.mjs | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/scripts/wm-reprice/revert.mjs b/scripts/wm-reprice/revert.mjs
new file mode 100644
index 0000000..dff88e7
--- /dev/null
+++ b/scripts/wm-reprice/revert.mjs
@@ -0,0 +1,34 @@
+/* TK-11814 — REVERT the William Morris live reprice.
+ Reads scripts/wm-reprice/restore-map.csv (variant_gid,sku,old_price,new_price) and writes
+ every variant's OLD price back via productVariantsBulkUpdate. DRY by default; APPLY=1 writes.
+ This is the one-command undo referenced in the executed-reversible ledger. */
+import fs from 'node:fs';
+import { gql } from '../lib/shopify.mjs';
+
+const APPLY = process.env.APPLY === '1';
+const DIR = new URL('.', import.meta.url).pathname;
+const rows = fs.readFileSync(DIR + 'restore-map.csv', 'utf8').trim().split('\n').slice(1).map(l => {
+ const [vgid, sku, oldp, newp] = l.split(',');
+ return { vgid, sku, oldp: +oldp, newp: +newp };
+});
+const MUT = `mutation($pid:ID!,$variants:[ProductVariantsBulkInput!]!){ productVariantsBulkUpdate(productId:$pid,variants:$variants){ productVariants{ id price } userErrors{ field message } } }`;
+
+(async () => {
+ console.log(`MODE: ${APPLY ? 'APPLY (reverting live)' : 'DRY (no writes — set APPLY=1)'} | variants: ${rows.length}\n`);
+ const byPid = {};
+ for (const r of rows) {
+ const d = await gql(`{ productVariant(id:"${r.vgid}"){ price product{ id } } }`);
+ const pid = d?.productVariant?.product?.id;
+ if (!pid) { console.error(` skip ${r.sku}: not found`); continue; }
+ (byPid[pid] ||= []).push(r);
+ }
+ if (!APPLY) { console.log(`DRY: would restore ${rows.length} variants to their old prices. Re-run APPLY=1.`); return; }
+ let wrote = 0, err = 0;
+ for (const [pid, vs] of Object.entries(byPid)) {
+ const r = await gql(MUT, { pid, variants: vs.map(v => ({ id: v.vgid, price: String(v.oldp) })) });
+ const ue = r?.productVariantsBulkUpdate?.userErrors || [];
+ if (ue.length) { err += vs.length; console.error(` ERR ${pid}: ${JSON.stringify(ue)}`); continue; }
+ wrote += (r.productVariantsBulkUpdate.productVariants || []).length;
+ }
+ console.log(`\n=== REVERTED === wrote:${wrote} err:${err}`);
+})();
← 41d4d1e WM reprice: 375 William Morris products to cost/0.65/0.85 (+
·
back to Designerwallcoverings
·
auto-data-snapshot: 2026-09-16T09:33:20 (1 data files) — dat 6eab755 →