← back to Designerwallcoverings
fix remove-194-collisions: metafieldDelete->REST delete by id (2024-10 has no metafieldDelete mutation); remove ALL matching namespaces (custom+global), not just first
b0f1d98adbb484cceceefd3d9034c2e3beb05d4e · 2026-09-03 10:04:06 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ddgxmase3XCnLRxVyaE1LD
Files touched
M scripts/pj-mfr-backfill/remove-194-collisions.mjs
Diff
commit b0f1d98adbb484cceceefd3d9034c2e3beb05d4e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Sep 3 10:04:06 2026 -0700
fix remove-194-collisions: metafieldDelete->REST delete by id (2024-10 has no metafieldDelete mutation); remove ALL matching namespaces (custom+global), not just first
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ddgxmase3XCnLRxVyaE1LD
---
scripts/pj-mfr-backfill/remove-194-collisions.mjs | 30 ++++++++++++++---------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/scripts/pj-mfr-backfill/remove-194-collisions.mjs b/scripts/pj-mfr-backfill/remove-194-collisions.mjs
index ff3a22e..3cdd600 100644
--- a/scripts/pj-mfr-backfill/remove-194-collisions.mjs
+++ b/scripts/pj-mfr-backfill/remove-194-collisions.mjs
@@ -51,13 +51,19 @@ async function gql(q, v) {
});
const j = await r.json(); if (j.errors) throw new Error(JSON.stringify(j.errors)); return j.data;
}
-async function liveMfr(pid) {
+async function liveMfrs(pid) {
const r = await fetch(`https://${STORE}/admin/api/${API}/products/${pid}/metafields.json`, { headers: { 'X-Shopify-Access-Token': TOKEN } });
const d = await r.json();
- const m = (d.metafields || []).find(x => x.key && x.key.toLowerCase() === 'manufacturer_sku' && (x.value || '').trim());
- return m ? { id: m.id, namespace: m.namespace, value: m.value } : null;
+ return (d.metafields || [])
+ .filter(x => x.key && x.key.toLowerCase() === 'manufacturer_sku' && (x.value || '').trim())
+ .map(m => ({ id: m.id, namespace: m.namespace, value: String(m.value) }));
+}
+// Shopify 2024-10 has no `metafieldDelete` mutation; delete by metafield id via REST.
+async function delMeta(pid, id) {
+ const r = await fetch(`https://${STORE}/admin/api/${API}/products/${pid}/metafields/${id}.json`,
+ { method: 'DELETE', headers: { 'X-Shopify-Access-Token': TOKEN } });
+ if (!r.ok) throw new Error(`DELETE metafield ${id} -> HTTP ${r.status} ${await r.text()}`);
}
-const DEL = `mutation($id:ID!){ metafieldDelete(input:{id:$id}){ deletedId userErrors{message} } }`;
async function main() {
const recs = parseCsv(fs.readFileSync(CSV, 'utf8'));
@@ -67,13 +73,15 @@ async function main() {
for (const r of recs.slice(b, b + BATCH)) {
i++;
const pid = r.product_numeric_id, expect = String(r.new_manufacturer_sku).trim();
- const cur = await liveMfr(pid);
- if (!cur) { skip_absent++; continue; }
- if (cur.value.trim() !== expect) { skip_mismatch++; console.log(` SKIP ${r.dw_sku}: live='${cur.value}' != expected '${expect}' (not ours)`); continue; }
- if (!APPLY) { if (i <= 5) console.log(` DRY delete ${r.dw_sku} (${pid}) ${cur.namespace}.manufacturer_sku='${cur.value}'`); removed++; continue; }
- const d = await gql(DEL, { id: cur.id });
- if (d.metafieldDelete.userErrors.length) throw new Error(JSON.stringify(d.metafieldDelete.userErrors));
- fs.appendFileSync(LEDGER, JSON.stringify({ ts: new Date().toISOString(), product_id: pid, dw_sku: r.dw_sku, removed_value: cur.value, namespace: cur.namespace }) + '\n');
+ const all = await liveMfrs(pid);
+ const ours = all.filter(m => m.value.trim() === expect); // only the value WE wrote — any namespace (custom AND global)
+ if (all.length === 0) { skip_absent++; continue; }
+ if (ours.length === 0) { skip_mismatch++; console.log(` SKIP ${r.dw_sku}: live=[${all.map(m => m.namespace + '=' + m.value).join(',')}] != '${expect}' (not ours)`); continue; }
+ if (!APPLY) { if (i <= 5) console.log(` DRY delete ${r.dw_sku} (${pid}) ${ours.map(m => m.namespace + '.manufacturer_sku=' + m.value).join(', ')}`); removed++; continue; }
+ for (const m of ours) {
+ await delMeta(pid, m.id);
+ fs.appendFileSync(LEDGER, JSON.stringify({ ts: new Date().toISOString(), product_id: pid, dw_sku: r.dw_sku, removed_value: m.value, namespace: m.namespace, metafield_id: m.id }) + '\n');
+ }
removed++;
}
console.log(` batch ${b / BATCH + 1}: removed=${removed} skip_mismatch=${skip_mismatch} skip_absent=${skip_absent}`);
← 18eb4cc TK-11131: PJ mfr# — 706/194 collision split + delete-194 cor
·
back to Designerwallcoverings
·
auto-data-snapshot: 2026-09-03T10:32:28 (16 data files) — sc 1fa3961 →