[object Object]

← back to Harlequin Pilot Publish

Harlequin pilot publish scaffold: locate 23 + idempotent Single Roll adder (dry-run verified)

63120723184ee89b0e5f85bb6188af6caac8f8ef · 2026-08-26 09:33:00 -0700 · Steve Abrams

Files touched

Diff

commit 63120723184ee89b0e5f85bb6188af6caac8f8ef
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Aug 26 09:33:00 2026 -0700

    Harlequin pilot publish scaffold: locate 23 + idempotent Single Roll adder (dry-run verified)
---
 .gitignore             |   5 +
 01-locate.mjs          |  49 +++++
 02-add-single-roll.mjs |  91 ++++++++++
 data/add-results.json  | 140 ++++++++++++++
 data/located.json      | 485 +++++++++++++++++++++++++++++++++++++++++++++++++
 data/pilot-23.json     |  25 +++
 lib.mjs                |  63 +++++++
 7 files changed, 858 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c88df7a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+node_modules/
+.env*
+*.log
+.DS_Store
+data/*.tmp
diff --git a/01-locate.mjs b/01-locate.mjs
new file mode 100644
index 0000000..168c13a
--- /dev/null
+++ b/01-locate.mjs
@@ -0,0 +1,49 @@
+// READ-ONLY: locate each of the 23 pilot products live + dump current variants.
+import fs from 'node:fs';
+import { findProductByVariantSku, getProductVariants } from './lib.mjs';
+
+const pilot = JSON.parse(fs.readFileSync(new URL('./data/pilot-23.json', import.meta.url)));
+const out = [];
+
+for (const p of pilot) {
+  // Search by the DW SKU exactly, and also try the -Sample variant.
+  let hits = await findProductByVariantSku(p.dw_sku);
+  let productGid = null, matchedBy = null;
+
+  // exact variant sku match (base)
+  let exact = hits.find(h => (h.sku || '').toUpperCase() === p.dw_sku.toUpperCase());
+  if (exact) { productGid = exact.product.id; matchedBy = 'base-sku'; }
+
+  if (!productGid) {
+    // try sample sku
+    const sampleHits = await findProductByVariantSku(p.dw_sku + '-Sample');
+    const ex = sampleHits.find(h => (h.sku || '').toUpperCase() === (p.dw_sku + '-SAMPLE').toUpperCase());
+    if (ex) { productGid = ex.product.id; matchedBy = 'sample-sku'; }
+  }
+
+  if (!productGid) {
+    // last resort: prefix match on any returned hit whose sku starts with dw_sku
+    const pre = hits.find(h => (h.sku || '').toUpperCase().startsWith(p.dw_sku.toUpperCase()));
+    if (pre) { productGid = pre.product.id; matchedBy = 'prefix-sku'; }
+  }
+
+  let prod = null;
+  if (productGid) prod = await getProductVariants(productGid);
+
+  out.push({
+    dw_sku: p.dw_sku, title: p.title, haw: p.haw, retail: p.retail,
+    productGid, matchedBy,
+    handle: prod?.handle || null,
+    liveTitle: prod?.title || null,
+    status: prod?.status || null,
+    variants: prod ? prod.variants.edges.map(e => ({
+      id: e.node.id, title: e.node.title, sku: e.node.sku, price: e.node.price,
+      invItemId: e.node.inventoryItem?.id, tracked: e.node.inventoryItem?.tracked,
+    })) : null,
+  });
+  process.stderr.write(`${p.dw_sku}\t${productGid ? matchedBy : 'NOT-FOUND'}\t${prod?.variants.edges.length ?? '-'} variants\t${prod?.status ?? ''}\n`);
+}
+
+fs.writeFileSync(new URL('./data/located.json', import.meta.url), JSON.stringify(out, null, 2));
+const found = out.filter(o => o.productGid).length;
+process.stderr.write(`\nLOCATED ${found}/23\n`);
diff --git a/02-add-single-roll.mjs b/02-add-single-roll.mjs
new file mode 100644
index 0000000..75595b5
--- /dev/null
+++ b/02-add-single-roll.mjs
@@ -0,0 +1,91 @@
+// Idempotent: add a real "Single Roll" variant at computed retail to each pilot product.
+// Sample variant already exists (verified) => left untouched.
+// Records a restore-map (created variant ids) BEFORE completion for reversibility.
+import fs from 'node:fs';
+import path from 'node:path';
+import { rest, getProductVariants } from './lib.mjs';
+
+const APPLY = process.argv.includes('--apply');
+const located = JSON.parse(fs.readFileSync(new URL('./data/located.json', import.meta.url)));
+
+const RESTORE_MAP_PATH = process.env.HOME + '/.claude/yolo-queue/executed-reversible/harlequin-pilot-restore-map.json';
+let restore = { ticket: 'TK-10876', agent: 'vp-dw-commerce', created_at: new Date().toISOString(),
+  action: 'harlequin-pilot: add Single Roll variant to 23 Diane Hill products', entries: [] };
+if (fs.existsSync(RESTORE_MAP_PATH)) {
+  try { restore = JSON.parse(fs.readFileSync(RESTORE_MAP_PATH)); } catch {}
+  if (!restore.entries) restore.entries = [];
+}
+
+function saveRestore() {
+  fs.mkdirSync(path.dirname(RESTORE_MAP_PATH), { recursive: true });
+  fs.writeFileSync(RESTORE_MAP_PATH, JSON.stringify(restore, null, 2));
+}
+
+const results = [];
+
+for (const p of located) {
+  if (!p.productGid) { results.push({ ...p, action: 'SKIP-NOT-FOUND' }); continue; }
+  const pidNum = p.productGid.split('/').pop();
+
+  // Re-read current variants FRESH (idempotency source of truth)
+  const prod = await getProductVariants(p.productGid);
+  const variants = prod.variants.edges.map(e => e.node);
+  const wantSku = p.dw_sku;                 // Single Roll base sku
+  const wantPrice = Number(p.retail).toFixed(2);
+
+  const existingRoll = variants.find(v =>
+    (v.sku || '').toUpperCase() === wantSku.toUpperCase() ||
+    (v.title || '').toLowerCase() === 'single roll');
+
+  if (existingRoll) {
+    const priceOk = Number(existingRoll.price).toFixed(2) === wantPrice;
+    results.push({ dw_sku: p.dw_sku, action: priceOk ? 'SKIP-EXISTS-OK' : 'EXISTS-PRICE-MISMATCH',
+      variant_id: existingRoll.id, price: existingRoll.price, want: wantPrice });
+    process.stderr.write(`${p.dw_sku}\t${priceOk ? 'SKIP-EXISTS-OK' : 'PRICE-MISMATCH ' + existingRoll.price + '->' + wantPrice}\n`);
+    continue;
+  }
+
+  if (!APPLY) {
+    results.push({ dw_sku: p.dw_sku, action: 'WOULD-ADD', price: wantPrice, option: 'Size=Single Roll' });
+    process.stderr.write(`${p.dw_sku}\tWOULD-ADD Single Roll @ $${wantPrice}\n`);
+    continue;
+  }
+
+  // ADD via REST — mirror the Sample variant's inventory settings (tracked + continue = always sellable)
+  const body = { variant: {
+    option1: 'Single Roll',
+    sku: wantSku,
+    price: wantPrice,
+    inventory_policy: 'continue',
+    inventory_management: 'shopify',
+    taxable: true,
+    requires_shipping: true,
+    weight: 3.0, weight_unit: 'lb',
+  }};
+  const r = await rest(`products/${pidNum}/variants.json`, 'POST', body);
+  if (r.status >= 200 && r.status < 300 && r.json.variant) {
+    const v = r.json.variant;
+    restore.entries.push({
+      dw_sku: p.dw_sku, product_id: pidNum, product_gid: p.productGid, handle: p.handle,
+      variant_id: v.id, variant_gid: `gid://shopify/ProductVariant/${v.id}`,
+      change: 'ADDED_VARIANT', title: v.title, sku: v.sku, price: v.price,
+      prior_value: null, undo: `DELETE /products/${pidNum}/variants/${v.id}.json`,
+      created_at: new Date().toISOString(),
+    });
+    saveRestore(); // persist after EACH add (crash-safe reversibility)
+    results.push({ dw_sku: p.dw_sku, action: 'ADDED', variant_id: v.id, price: v.price });
+    process.stderr.write(`${p.dw_sku}\tADDED Single Roll id=${v.id} @ $${v.price}\n`);
+  } else {
+    results.push({ dw_sku: p.dw_sku, action: 'ERROR', status: r.status, body: r.json });
+    process.stderr.write(`${p.dw_sku}\tERROR ${r.status} ${JSON.stringify(r.json).slice(0,200)}\n`);
+  }
+  // >=90s gap is for BULK pushes; single-variant REST adds are light. Pace lightly to be safe.
+  await new Promise(res => setTimeout(res, 600));
+}
+
+fs.writeFileSync(new URL('./data/add-results.json', import.meta.url), JSON.stringify(results, null, 2));
+saveRestore();
+const added = results.filter(r => r.action === 'ADDED').length;
+const skip = results.filter(r => r.action === 'SKIP-EXISTS-OK').length;
+const err = results.filter(r => r.action === 'ERROR' || r.action === 'EXISTS-PRICE-MISMATCH' || r.action === 'SKIP-NOT-FOUND').length;
+process.stderr.write(`\n${APPLY ? 'APPLY' : 'DRY-RUN'} DONE: added=${added} skip-ok=${skip} issues=${err}\nrestore-map: ${RESTORE_MAP_PATH}\n`);
diff --git a/data/add-results.json b/data/add-results.json
new file mode 100644
index 0000000..0b24fa2
--- /dev/null
+++ b/data/add-results.json
@@ -0,0 +1,140 @@
+[
+  {
+    "dw_sku": "DWHF-70127",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70128",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70129",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70132",
+    "action": "WOULD-ADD",
+    "price": "981.00",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70131",
+    "action": "WOULD-ADD",
+    "price": "981.00",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70130",
+    "action": "WOULD-ADD",
+    "price": "981.00",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70134",
+    "action": "WOULD-ADD",
+    "price": "208.14",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70135",
+    "action": "WOULD-ADD",
+    "price": "208.14",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70133",
+    "action": "WOULD-ADD",
+    "price": "208.14",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70138",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70137",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70136",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70139",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70140",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70141",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70143",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70142",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70144",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70145",
+    "action": "WOULD-ADD",
+    "price": "269.68",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70146",
+    "action": "WOULD-ADD",
+    "price": "924.89",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70147",
+    "action": "WOULD-ADD",
+    "price": "924.89",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70148",
+    "action": "WOULD-ADD",
+    "price": "334.84",
+    "option": "Size=Single Roll"
+  },
+  {
+    "dw_sku": "DWHF-70149",
+    "action": "WOULD-ADD",
+    "price": "334.84",
+    "option": "Size=Single Roll"
+  }
+]
\ No newline at end of file
diff --git a/data/located.json b/data/located.json
new file mode 100644
index 0000000..5d7c556
--- /dev/null
+++ b/data/located.json
@@ -0,0 +1,485 @@
+[
+  {
+    "dw_sku": "DWHF-70127",
+    "title": "Ella - Fig Blossom/Fig Leaf/ Nectarine",
+    "haw": "HAW0239-01",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962180423731",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70127-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Ella - Fig Blossom/Fig Leaf/ Nectarine Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438303584307",
+        "title": "Sample",
+        "sku": "DWHF-70127-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544521474099",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70128",
+    "title": "Ella - Powder/ Sage / Peach",
+    "haw": "HAW0239-02",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962180849715",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70128-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Ella - Powder/ Sage / Peach Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438304043059",
+        "title": "Sample",
+        "sku": "DWHF-70128-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544521932851",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70129",
+    "title": "Ella - Sky/Fig Leaf/ Nectarine",
+    "haw": "HAW0239-03",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962181374003",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70129-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Ella - Sky/Fig Leaf/ Nectarine Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438304567347",
+        "title": "Sample",
+        "sku": "DWHF-70129-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544522489907",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70132",
+    "title": "Florence - Fig Blossom/Apple/Peony",
+    "haw": "HAW0240-03",
+    "retail": 981,
+    "productGid": "gid://shopify/Product/6962182717491",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70132-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Florence - Fig Blossom/Apple/Peony Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438305910835",
+        "title": "Sample",
+        "sku": "DWHF-70132-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544523800627",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70131",
+    "title": "Florence - Powder/ China Blue",
+    "haw": "HAW0240-02",
+    "retail": 981,
+    "productGid": "gid://shopify/Product/6962182357043",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70131-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Florence - Powder/ China Blue Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438305550387",
+        "title": "Sample",
+        "sku": "DWHF-70131-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544523440179",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70130",
+    "title": "Florence - Sky/Meadow/Blossom",
+    "haw": "HAW0240-01",
+    "retail": 981,
+    "productGid": "gid://shopify/Product/6962181898291",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70130-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Florence - Sky/Meadow/Blossom Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438305091635",
+        "title": "Sample",
+        "sku": "DWHF-70130-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544522981427",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70134",
+    "title": "Isabella - Honey/Porcelain",
+    "haw": "HAW0241-02",
+    "retail": 208.14,
+    "productGid": "gid://shopify/Product/6962183667763",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70134-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Isabella - Honey/Porcelain Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438306861107",
+        "title": "Sample",
+        "sku": "DWHF-70134-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544524750899",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70135",
+    "title": "Isabella - Porcelain/Bamboo",
+    "haw": "HAW0241-03",
+    "retail": 208.14,
+    "productGid": "gid://shopify/Product/6962183995443",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70135-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Isabella - Porcelain/Bamboo Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438307188787",
+        "title": "Sample",
+        "sku": "DWHF-70135-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544525078579",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70133",
+    "title": "Isabella - Sky/Porcelain",
+    "haw": "HAW0241-01",
+    "retail": 208.14,
+    "productGid": "gid://shopify/Product/6962183209011",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70133-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Isabella - Sky/Porcelain Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438306402355",
+        "title": "Sample",
+        "sku": "DWHF-70133-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544524292147",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70138",
+    "title": "Lady Alford - Apple/Magenta",
+    "haw": "HAW0242-03",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962185535539",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70138-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Lady Alford - Apple/Magenta Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438308728883",
+        "title": "Sample",
+        "sku": "DWHF-70138-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544526618675",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70137",
+    "title": "Lady Alford - Fig Blossom/ Magenta",
+    "haw": "HAW0242-02",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962184978483",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70137-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Lady Alford - Fig Blossom/ Magenta Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438308171827",
+        "title": "Sample",
+        "sku": "DWHF-70137-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544526061619",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70136",
+    "title": "Lady Alford - Porcelain / China Blue",
+    "haw": "HAW0242-01",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962184388659",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70136-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Lady Alford - Porcelain / China Blue Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438307582003",
+        "title": "Sample",
+        "sku": "DWHF-70136-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544525504563",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70139",
+    "title": "Lady Alford - Sky/Magenta",
+    "haw": "HAW0242-04",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962185928755",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70139-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Lady Alford - Sky/Magenta Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438309154867",
+        "title": "Sample",
+        "sku": "DWHF-70139-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544527044659",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70140",
+    "title": "Marie - Fig Leaf/Honey/Blossom",
+    "haw": "HAW0243-01",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962186256435",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70140-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Marie - Fig Leaf/Honey/Blossom Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438309515315",
+        "title": "Sample",
+        "sku": "DWHF-70140-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544527405107",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70141",
+    "title": "Marie - Rose/ Lagoon",
+    "haw": "HAW0243-02",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962186616883",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70141-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Marie - Rose/ Lagoon Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438309908531",
+        "title": "Sample",
+        "sku": "DWHF-70141-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544527798323",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70143",
+    "title": "Marsha - Aqua/Peony/Magenta",
+    "haw": "HAW0244-02",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962187632691",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70143-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Marsha - Aqua/Peony/Magenta Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438310924339",
+        "title": "Sample",
+        "sku": "DWHF-70143-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544528814131",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70142",
+    "title": "Marsha - Powder/Peony/Magenta",
+    "haw": "HAW0244-01",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962187075635",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70142-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Marsha - Powder/Peony/Magenta Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438310334515",
+        "title": "Sample",
+        "sku": "DWHF-70142-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544528224307",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70144",
+    "title": "Nellie - Gilver/Meadow",
+    "haw": "HAW0245-01",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962188124211",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70144-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Nellie - Gilver/Meadow Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438311415859",
+        "title": "Sample",
+        "sku": "DWHF-70144-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544529305651",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70145",
+    "title": "Nellie - Honey/Meadow",
+    "haw": "HAW0245-02",
+    "retail": 269.68,
+    "productGid": "gid://shopify/Product/6962188550195",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70145-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Nellie - Honey/Meadow Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438311874611",
+        "title": "Sample",
+        "sku": "DWHF-70145-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544529764403",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70146",
+    "title": "Rosa - Blush Pearl/Peony/Meadow",
+    "haw": "HAW0246-01",
+    "retail": 924.89,
+    "productGid": "gid://shopify/Product/6962188976179",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70146-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Rosa - Blush Pearl/Peony/Meadow Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438312300595",
+        "title": "Sample",
+        "sku": "DWHF-70146-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544530190387",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70147",
+    "title": "Rosa - Feather Grey/ Paper Lantern/Oyster",
+    "haw": "HAW0246-02",
+    "retail": 924.89,
+    "productGid": "gid://shopify/Product/6962189434931",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70147-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Rosa - Feather Grey/ Paper Lantern/Oyster Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438312726579",
+        "title": "Sample",
+        "sku": "DWHF-70147-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544530616371",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70148",
+    "title": "Valentina - Blush/Blossom",
+    "haw": "HAW0247-01",
+    "retail": 334.84,
+    "productGid": "gid://shopify/Product/6962189828147",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70148-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Valentina - Blush/Blossom Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438313119795",
+        "title": "Sample",
+        "sku": "DWHF-70148-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544531009587",
+        "tracked": true
+      }
+    ]
+  },
+  {
+    "dw_sku": "DWHF-70149",
+    "title": "Valentina - Exhale /Ink",
+    "haw": "HAW0247-02",
+    "retail": 334.84,
+    "productGid": "gid://shopify/Product/6962190319667",
+    "matchedBy": "sample-sku",
+    "handle": "dwhf-70149-sample-designer-wallcoverings-los-angeles",
+    "liveTitle": "Valentina - Exhale /Ink Wallcovering | Harlequin",
+    "status": "ACTIVE",
+    "variants": [
+      {
+        "id": "gid://shopify/ProductVariant/41438313611315",
+        "title": "Sample",
+        "sku": "DWHF-70149-Sample",
+        "price": "4.25",
+        "invItemId": "gid://shopify/InventoryItem/43544531501107",
+        "tracked": true
+      }
+    ]
+  }
+]
\ No newline at end of file
diff --git a/data/pilot-23.json b/data/pilot-23.json
new file mode 100644
index 0000000..fc18255
--- /dev/null
+++ b/data/pilot-23.json
@@ -0,0 +1,25 @@
+[
+  {"dw_sku":"DWHF-70127","title":"Ella - Fig Blossom/Fig Leaf/ Nectarine","mfr_sku":"112906","haw":"HAW0239-01","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70128","title":"Ella - Powder/ Sage / Peach","mfr_sku":"112907","haw":"HAW0239-02","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70129","title":"Ella - Sky/Fig Leaf/ Nectarine","mfr_sku":"112908","haw":"HAW0239-03","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70132","title":"Florence - Fig Blossom/Apple/Peony","mfr_sku":"112891","haw":"HAW0240-03","trade":542,"retail":981.00,"width_in":26.97},
+  {"dw_sku":"DWHF-70131","title":"Florence - Powder/ China Blue","mfr_sku":"112890","haw":"HAW0240-02","trade":542,"retail":981.00,"width_in":26.97},
+  {"dw_sku":"DWHF-70130","title":"Florence - Sky/Meadow/Blossom","mfr_sku":"112889","haw":"HAW0240-01","trade":542,"retail":981.00,"width_in":26.97},
+  {"dw_sku":"DWHF-70134","title":"Isabella - Honey/Porcelain","mfr_sku":"112914","haw":"HAW0241-02","trade":115,"retail":208.14,"width_in":20.47},
+  {"dw_sku":"DWHF-70135","title":"Isabella - Porcelain/Bamboo","mfr_sku":"112915","haw":"HAW0241-03","trade":115,"retail":208.14,"width_in":20.47},
+  {"dw_sku":"DWHF-70133","title":"Isabella - Sky/Porcelain","mfr_sku":"112913","haw":"HAW0241-01","trade":115,"retail":208.14,"width_in":20.47},
+  {"dw_sku":"DWHF-70138","title":"Lady Alford - Apple/Magenta","mfr_sku":"112900","haw":"HAW0242-03","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70137","title":"Lady Alford - Fig Blossom/ Magenta","mfr_sku":"112899","haw":"HAW0242-02","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70136","title":"Lady Alford - Porcelain / China Blue","mfr_sku":"112898","haw":"HAW0242-01","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70139","title":"Lady Alford - Sky/Magenta","mfr_sku":"112901","haw":"HAW0242-04","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70140","title":"Marie - Fig Leaf/Honey/Blossom","mfr_sku":"112909","haw":"HAW0243-01","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70141","title":"Marie - Rose/ Lagoon","mfr_sku":"112910","haw":"HAW0243-02","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70143","title":"Marsha - Aqua/Peony/Magenta","mfr_sku":"112903","haw":"HAW0244-02","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70142","title":"Marsha - Powder/Peony/Magenta","mfr_sku":"112902","haw":"HAW0244-01","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70144","title":"Nellie - Gilver/Meadow","mfr_sku":"112904","haw":"HAW0245-01","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70145","title":"Nellie - Honey/Meadow","mfr_sku":"112905","haw":"HAW0245-02","trade":149,"retail":269.68,"width_in":27.01},
+  {"dw_sku":"DWHF-70146","title":"Rosa - Blush Pearl/Peony/Meadow","mfr_sku":"112887","haw":"HAW0246-01","trade":511,"retail":924.89,"width_in":26.97},
+  {"dw_sku":"DWHF-70147","title":"Rosa - Feather Grey/ Paper Lantern/Oyster","mfr_sku":"112888","haw":"HAW0246-02","trade":511,"retail":924.89,"width_in":26.97},
+  {"dw_sku":"DWHF-70148","title":"Valentina - Blush/Blossom","mfr_sku":"112911","haw":"HAW0247-01","trade":185,"retail":334.84,"width_in":27.01},
+  {"dw_sku":"DWHF-70149","title":"Valentina - Exhale /Ink","mfr_sku":"112912","haw":"HAW0247-02","trade":185,"retail":334.84,"width_in":27.01}
+]
diff --git a/lib.mjs b/lib.mjs
new file mode 100644
index 0000000..52c40b6
--- /dev/null
+++ b/lib.mjs
@@ -0,0 +1,63 @@
+import fs from 'node:fs';
+
+export const SHOP = 'designer-laboratory-sandbox.myshopify.com';
+export const API = '2024-10';
+
+export function token() {
+  const env = fs.readFileSync(process.env.HOME + '/Projects/secrets-manager/.env', 'utf8');
+  const m = env.match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m);
+  if (!m) throw new Error('SHOPIFY_ADMIN_TOKEN not found');
+  return m[1].trim().replace(/^["']|["']$/g, '');
+}
+
+const T = token();
+
+export async function gql(query, variables = {}) {
+  const r = await fetch(`https://${SHOP}/admin/api/${API}/graphql.json`, {
+    method: 'POST',
+    headers: { 'X-Shopify-Access-Token': T, 'Content-Type': 'application/json' },
+    body: JSON.stringify({ query, variables }),
+  });
+  const j = await r.json();
+  if (j.errors) throw new Error('GraphQL errors: ' + JSON.stringify(j.errors));
+  return j.data;
+}
+
+export async function rest(path, method = 'GET', body = null) {
+  const opts = { method, headers: { 'X-Shopify-Access-Token': T, 'Content-Type': 'application/json' } };
+  if (body) opts.body = JSON.stringify(body);
+  const r = await fetch(`https://${SHOP}/admin/api/${API}/${path}`, opts);
+  const txt = await r.text();
+  let j; try { j = JSON.parse(txt); } catch { j = { _raw: txt }; }
+  return { status: r.status, json: j };
+}
+
+// Find a product by an exact variant SKU. Returns product gid + full variant list.
+export async function findProductByVariantSku(sku) {
+  const q = `query($q:String!){
+    productVariants(first: 25, query: $q){
+      edges{ node{
+        id sku price
+        inventoryItem { id tracked }
+        product { id handle title status }
+      }}
+    }
+  }`;
+  const d = await gql(q, { q: `sku:${sku}` });
+  return d.productVariants.edges.map(e => e.node);
+}
+
+// Full product variant dump by product gid
+export async function getProductVariants(productGid) {
+  const q = `query($id:ID!){
+    product(id:$id){
+      id handle title status
+      variants(first: 50){ edges{ node{
+        id title price sku
+        inventoryItem { id tracked }
+      }}}
+    }
+  }`;
+  const d = await gql(q, { id: productGid });
+  return d.product;
+}

(oldest)  ·  back to Harlequin Pilot Publish  ·  Harlequin pilot LIVE published: 23/23 Single Roll variants a 606c457 →