[object Object]

← back to Dw Width Fix

Fix 5 broken custom.width metafields (vendor-derived); flag 25 no-source; restore-map + rollback

511462ee783e6a5c3a9fd70df96a684099450579 · 2026-08-20 08:19:31 -0700 · steve

Files touched

Diff

commit 511462ee783e6a5c3a9fd70df96a684099450579
Author: steve <steve@designerwallcoverings.com>
Date:   Thu Aug 20 08:19:31 2026 -0700

    Fix 5 broken custom.width metafields (vendor-derived); flag 25 no-source; restore-map + rollback
---
 .gitignore       |   5 +
 apply.mjs        |  34 +++++++
 broken-live.json | 272 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 restore-map.json |  45 +++++++++
 rollback.mjs     |  12 +++
 scan.mjs         |  84 +++++++++++++++++
 to-flag.json     | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++
 to-write.json    |  57 ++++++++++++
 verify.mjs       |  12 +++
 9 files changed, 773 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ff2422c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+node_modules/
+.env*
+tmp/
+*.log
+.DS_Store
diff --git a/apply.mjs b/apply.mjs
new file mode 100644
index 0000000..d2ad51b
--- /dev/null
+++ b/apply.mjs
@@ -0,0 +1,34 @@
+import fs from 'fs';
+const env = Object.fromEntries(fs.readFileSync('.env','utf8').split('\n').filter(l=>l.includes('=')&&!l.startsWith('#')).map(l=>{const i=l.indexOf('=');return [l.slice(0,i).trim(), l.slice(i+1).trim()];}));
+const TOKEN = env.SHOPIFY_ADMIN_TOKEN;
+const DOMAIN='designer-laboratory-sandbox.myshopify.com';
+const API=`https://${DOMAIN}/admin/api/2024-10/graphql.json`;
+const LIMIT = parseInt(process.argv[2]||'0',10); // 0 = all; else canary N
+const DRY = process.env.DRY==='1';
+
+async function gql(query,variables={}){
+  const r=await fetch(API,{method:'POST',headers:{'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json'},body:JSON.stringify({query,variables})});
+  const j=await r.json(); if(j.errors){console.error(JSON.stringify(j.errors));throw new Error('gql');} return j.data;
+}
+const items = JSON.parse(fs.readFileSync('to-write.json','utf8'));
+const batch = LIMIT>0 ? items.slice(0,LIMIT) : items;
+
+// Restore map: capture LIVE current value fresh (re-read, don't trust file) before writing
+const restore = fs.existsSync('restore-map.json') ? JSON.parse(fs.readFileSync('restore-map.json','utf8')) : {};
+const M_READ=`query($id:ID!){product(id:$id){id handle metafield(namespace:"custom",key:"width"){id value}}}`;
+const M_SET=`mutation($mf:[MetafieldsSetInput!]!){metafieldsSet(metafields:$mf){metafields{id key value} userErrors{field message}}}`;
+
+for(const it of batch){
+  const cur = await gql(M_READ,{id:it.id});
+  const live = cur.product.metafield ? cur.product.metafield.value : null;
+  restore[it.id] = {handle:it.handle, oldValue:live, mfId:cur.product.metafield?cur.product.metafield.id:null, newValue:it.newWidth, source:it.source, ts:new Date().toISOString()};
+  if(DRY){ console.log(`DRY  ${it.handle}  live=${JSON.stringify(live)} -> ${JSON.stringify(it.newWidth)}`); continue; }
+  const res = await gql(M_SET,{mf:[{ownerId:it.id, namespace:'custom', key:'width', type:'single_line_text_field', value:it.newWidth}]});
+  const err = res.metafieldsSet.userErrors;
+  if(err && err.length){ console.error(`ERR ${it.handle}`, JSON.stringify(err)); }
+  else { console.log(`SET  ${it.handle}  ${JSON.stringify(live)} -> ${JSON.stringify(res.metafieldsSet.metafields[0].value)}`); }
+  fs.writeFileSync('restore-map.json', JSON.stringify(restore,null,2)); // persist after each
+  await new Promise(r=>setTimeout(r,400));
+}
+fs.writeFileSync('restore-map.json', JSON.stringify(restore,null,2));
+console.log(`\n${DRY?'DRY':'APPLIED'} ${batch.length} items. restore-map.json written (${Object.keys(restore).length} entries).`);
diff --git a/broken-live.json b/broken-live.json
new file mode 100644
index 0000000..b1f3cdc
--- /dev/null
+++ b/broken-live.json
@@ -0,0 +1,272 @@
+[
+  {
+    "id": "gid://shopify/Product/1495267803248",
+    "title": "Vaughn Trees",
+    "vendor": "LA Walls",
+    "handle": "vaughn-trees-tre-23000",
+    "mfId": "gid://shopify/Metafield/34797755695155",
+    "value": "Call to Verify",
+    "reason": "placeholder-call"
+  },
+  {
+    "id": "gid://shopify/Product/1495267901552",
+    "title": "Vaughn Trees",
+    "vendor": "LA Walls",
+    "handle": "vaughn-trees-tre-23001",
+    "mfId": "gid://shopify/Metafield/36116011417651",
+    "value": "Call to Verify",
+    "reason": "placeholder-call"
+  },
+  {
+    "id": "gid://shopify/Product/1495268262000",
+    "title": "Vaughn Trees",
+    "vendor": "LA Walls",
+    "handle": "vaughn-trees-tre-23003",
+    "mfId": "gid://shopify/Metafield/34796429115443",
+    "value": "Call to Verify",
+    "reason": "placeholder-call"
+  },
+  {
+    "id": "gid://shopify/Product/1495268491376",
+    "title": "Vaughn Trees",
+    "vendor": "LA Walls",
+    "handle": "vaughn-trees-tre-23004",
+    "mfId": "gid://shopify/Metafield/34797632978995",
+    "value": "Call to Verify",
+    "reason": "placeholder-call"
+  },
+  {
+    "id": "gid://shopify/Product/1495268720752",
+    "title": "Vaughn Trees",
+    "vendor": "LA Walls",
+    "handle": "vaughn-trees-tre-23005",
+    "mfId": "gid://shopify/Metafield/34799290744883",
+    "value": "Call to Verify",
+    "reason": "placeholder-call"
+  },
+  {
+    "id": "gid://shopify/Product/1496337842288",
+    "title": "Museum Gallery Wallcovering",
+    "vendor": "Designer Wallcoverings",
+    "handle": "museum-gallery-wallpaper-ama-52523",
+    "mfId": "gid://shopify/Metafield/34782701355059",
+    "value": "TBD",
+    "reason": "placeholder-tbd"
+  },
+  {
+    "id": "gid://shopify/Product/1496338038896",
+    "title": "Old Luggage Wallcovering",
+    "vendor": "Designer Wallcoverings",
+    "handle": "old-luggage-wallpaper-ama-52524",
+    "mfId": "gid://shopify/Metafield/34782701453363",
+    "value": "TBD",
+    "reason": "placeholder-tbd"
+  },
+  {
+    "id": "gid://shopify/Product/1496338301040",
+    "title": "Rockefeller Wallcovering",
+    "vendor": "Designer Wallcoverings",
+    "handle": "rockefeller-wallpaper-ama-52526",
+    "mfId": "gid://shopify/Metafield/34791841824819",
+    "value": "TBD",
+    "reason": "placeholder-tbd"
+  },
+  {
+    "id": "gid://shopify/Product/1496338563184",
+    "title": "Rockefeller Wallcovering",
+    "vendor": "Designer Wallcoverings",
+    "handle": "rockefeller-wallpaper-ama-52527",
+    "mfId": "gid://shopify/Metafield/34782701617203",
+    "value": "TBD",
+    "reason": "placeholder-tbd"
+  },
+  {
+    "id": "gid://shopify/Product/1497734250608",
+    "title": "Butterflies Fabric - Ice Blue",
+    "vendor": "British Walls",
+    "handle": "butterflies-blue-bga-47948",
+    "mfId": "gid://shopify/Metafield/34402830286899",
+    "value": "Per yard ",
+    "reason": "no-digit-nonlegit"
+  },
+  {
+    "id": "gid://shopify/Product/1501562339440",
+    "title": "Phillipe Romano - Renaissance Metal Leaf",
+    "vendor": "Phillipe Romano",
+    "handle": "phillipe-romano-renaissance-metal-leaf-rml-33052",
+    "mfId": "gid://shopify/Metafield/34421789917235",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/1501562896496",
+    "title": "Phillipe Romano - Renaissance Metal Leaf",
+    "vendor": "Phillipe Romano",
+    "handle": "phillipe-romano-renaissance-metal-leaf-rml-33054",
+    "mfId": "gid://shopify/Metafield/34421790539827",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/1501563355248",
+    "title": "Phillipe Romano - Renaissance Metal Leaf",
+    "vendor": "Phillipe Romano",
+    "handle": "phillipe-romano-renaissance-metal-leaf-rml-33056",
+    "mfId": "gid://shopify/Metafield/34421791227955",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/1501667983472",
+    "title": "Flattering Flamingo Midnight Blue | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-midnight-blue-whm-78001",
+    "mfId": "gid://shopify/Metafield/34421937963059",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/1501668278384",
+    "title": "Flattering Flamingo Grey | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-grey-whm-78002",
+    "mfId": "gid://shopify/Metafield/34421938880563",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/1501668802672",
+    "title": "Vintage Story Time | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "vintage-story-time-wallpaper-whm-78005",
+    "mfId": "gid://shopify/Metafield/34421940715571",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/1501668999280",
+    "title": "Flattering Flamingo Midnight Blue | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-midnight-blue-whm-78001-room",
+    "mfId": "gid://shopify/Metafield/34421938257971",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/1501669392496",
+    "title": "Vintage Story Time | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "vintage-story-time-wallpaper-whm-78005-room",
+    "mfId": "gid://shopify/Metafield/34421941076019",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/1501669523568",
+    "title": "Flattering Flamingo Midnight Blue | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-midnight-blue-whm-78001-zoom",
+    "mfId": "gid://shopify/Metafield/34421937668147",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/1501669654640",
+    "title": "Flattering Flamingo Grey | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-grey-whm-78002-zoom",
+    "mfId": "gid://shopify/Metafield/34421938552883",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/1501669884016",
+    "title": "Flattering Flamingo Light Blue | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-light-blue-whm-78003-zoom",
+    "mfId": "gid://shopify/Metafield/34421939175475",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/3928407179329",
+    "title": "Lafayette's Ballroom Flocked Velvet",
+    "vendor": "Phillipe Romano",
+    "handle": "lafayettes-ballroom-flocked-velvet-prnc-26701",
+    "mfId": "gid://shopify/Metafield/34394124091443",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm"
+  },
+  {
+    "id": "gid://shopify/Product/7422307663923",
+    "title": "Monte Carlo Bul - Cadet/G Blue By Lee Jofa | Trim Bullion",
+    "vendor": "Lee Jofa",
+    "handle": "dwkk-g45e3d7cc",
+    "mfId": "gid://shopify/Metafield/34783491719219",
+    "value": "0",
+    "reason": "literal-zero"
+  },
+  {
+    "id": "gid://shopify/Product/7422324604979",
+    "title": "Timothy - Sky Blue By Lee Jofa | Barbara Barry Collection |  Trim Fringe",
+    "vendor": "Lee Jofa",
+    "handle": "dwkk-g12a34adc",
+    "mfId": "gid://shopify/Metafield/34783457968179",
+    "value": "0",
+    "reason": "literal-zero"
+  },
+  {
+    "id": "gid://shopify/Product/7422324637747",
+    "title": "Timothy - Blue  By Lee Jofa | Barbara Barry Collection |  Trim Fringe",
+    "vendor": "Lee Jofa",
+    "handle": "dwkk-g39ddb0be",
+    "mfId": "gid://shopify/Metafield/34783457902643",
+    "value": "0",
+    "reason": "literal-zero"
+  },
+  {
+    "id": "gid://shopify/Product/7506088820787",
+    "title": "Acanthus Embossed Natural Paintable Sidewall | Lincrusta",
+    "vendor": "Lincrusta",
+    "handle": "lin-980014-rd1960fr-acanthus-lincrusta",
+    "mfId": "gid://shopify/Metafield/34484412776499",
+    "value": ":",
+    "reason": "colon-only"
+  },
+  {
+    "id": "gid://shopify/Product/7506268946483",
+    "title": "Adhesive Adhesive Accessory | Lincrusta",
+    "vendor": "Lincrusta",
+    "handle": "lin-980044-rdadh50-adhesive-lincrusta",
+    "mfId": "gid://shopify/Metafield/36116324745267",
+    "value": "Roll Length",
+    "reason": "label-only"
+  },
+  {
+    "id": "gid://shopify/Product/7506269110323",
+    "title": "Bonding Bonding Accessory | Lincrusta",
+    "vendor": "Lincrusta",
+    "handle": "lin-980046-rdprm10-bonding-lincrusta",
+    "mfId": "gid://shopify/Metafield/36116325171251",
+    "value": "Roll Length",
+    "reason": "label-only"
+  },
+  {
+    "id": "gid://shopify/Product/7506269208627",
+    "title": "Bonding Bonding Accessory | Lincrusta",
+    "vendor": "Lincrusta",
+    "handle": "lin-980047-rdprm25-bonding-lincrusta",
+    "mfId": "gid://shopify/Metafield/36116325236787",
+    "value": "Roll Length",
+    "reason": "label-only"
+  },
+  {
+    "id": "gid://shopify/Product/7786558947379",
+    "title": "Abaca La Perle Rare | Elitis",
+    "vendor": "Elitis",
+    "handle": "abaca-la-perle-rare-elitis",
+    "mfId": "gid://shopify/Metafield/34404064329779",
+    "value": "plant effect wallpaper.",
+    "reason": "desc-leaked"
+  }
+]
\ No newline at end of file
diff --git a/restore-map.json b/restore-map.json
new file mode 100644
index 0000000..8fe9bdb
--- /dev/null
+++ b/restore-map.json
@@ -0,0 +1,45 @@
+{
+  "gid://shopify/Product/1501562339440": {
+    "handle": "phillipe-romano-renaissance-metal-leaf-rml-33052",
+    "oldValue": "0 cm (0.00\")",
+    "mfId": "gid://shopify/Metafield/34421789917235",
+    "newValue": "54\"",
+    "source": "phillipe_romano_catalog Renaissance Metal Leaf uniform 54\"",
+    "ts": "2026-08-20T15:19:03.989Z",
+    "note": "oldValue corrected to true pre-fix value from live scan"
+  },
+  "gid://shopify/Product/1501562896496": {
+    "handle": "phillipe-romano-renaissance-metal-leaf-rml-33054",
+    "oldValue": "0 cm (0.00\")",
+    "mfId": "gid://shopify/Metafield/34421790539827",
+    "newValue": "54\"",
+    "source": "phillipe_romano_catalog Renaissance Metal Leaf uniform 54\"",
+    "ts": "2026-08-20T15:19:04.796Z",
+    "note": "oldValue corrected to true pre-fix value from live scan"
+  },
+  "gid://shopify/Product/1501563355248": {
+    "handle": "phillipe-romano-renaissance-metal-leaf-rml-33056",
+    "oldValue": "0 cm (0.00\")",
+    "mfId": "gid://shopify/Metafield/34421791227955",
+    "newValue": "54\"",
+    "source": "phillipe_romano_catalog Renaissance Metal Leaf uniform 54\"",
+    "ts": "2026-08-20T15:19:05.603Z",
+    "note": "oldValue corrected to true pre-fix value from live scan"
+  },
+  "gid://shopify/Product/7506088820787": {
+    "handle": "lin-980014-rd1960fr-acanthus-lincrusta",
+    "oldValue": ":",
+    "mfId": "gid://shopify/Metafield/34484412776499",
+    "newValue": "20 9/16 inches",
+    "source": "lincrusta_catalog RD1960FR width text",
+    "ts": "2026-08-20T15:19:06.379Z"
+  },
+  "gid://shopify/Product/7786558947379": {
+    "handle": "abaca-la-perle-rare-elitis",
+    "oldValue": "plant effect wallpaper.",
+    "mfId": "gid://shopify/Metafield/34404064329779",
+    "newValue": "39\"",
+    "source": "elitis_catalog Abaca line uniform 39\"",
+    "ts": "2026-08-20T15:19:07.196Z"
+  }
+}
\ No newline at end of file
diff --git a/rollback.mjs b/rollback.mjs
new file mode 100644
index 0000000..0f5679c
--- /dev/null
+++ b/rollback.mjs
@@ -0,0 +1,12 @@
+import fs from 'fs';
+const env=Object.fromEntries(fs.readFileSync('.env','utf8').split('\n').filter(l=>l.includes('=')&&!l.startsWith('#')).map(l=>{const i=l.indexOf('=');return [l.slice(0,i).trim(),l.slice(i+1).trim()];}));
+const TOKEN=env.SHOPIFY_ADMIN_TOKEN;const API='https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json';
+async function gql(q,v={}){const r=await fetch(API,{method:'POST',headers:{'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v})});return (await r.json()).data;}
+const rm=JSON.parse(fs.readFileSync('restore-map.json','utf8'));
+const M=`mutation($mf:[MetafieldsSetInput!]!){metafieldsSet(metafields:$mf){metafields{value} userErrors{message}}}`;
+for(const [id,e] of Object.entries(rm)){
+  if(e.oldValue==null){ console.log('SKIP (was null)',e.handle); continue; }
+  const res=await gql(M,{mf:[{ownerId:id,namespace:'custom',key:'width',type:'single_line_text_field',value:e.oldValue}]});
+  console.log('RESTORED',e.handle,'->',JSON.stringify(e.oldValue), res.metafieldsSet.userErrors);
+  await new Promise(r=>setTimeout(r,400));
+}
diff --git a/scan.mjs b/scan.mjs
new file mode 100644
index 0000000..0aeb85c
--- /dev/null
+++ b/scan.mjs
@@ -0,0 +1,84 @@
+import fs from 'fs';
+const env = Object.fromEntries(fs.readFileSync('.env','utf8').split('\n').filter(l=>l.includes('=')&&!l.startsWith('#')).map(l=>{const i=l.indexOf('=');return [l.slice(0,i).trim(), l.slice(i+1).trim()];}));
+const TOKEN = env.SHOPIFY_ADMIN_TOKEN;
+const DOMAIN = 'designer-laboratory-sandbox.myshopify.com';
+const API = `https://${DOMAIN}/admin/api/2024-10/graphql.json`;
+
+async function gql(query, variables={}) {
+  const r = await fetch(API, {
+    method:'POST',
+    headers:{'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json'},
+    body:JSON.stringify({query, variables})
+  });
+  const j = await r.json();
+  if (j.errors) { console.error(JSON.stringify(j.errors)); throw new Error('gql'); }
+  return j.data;
+}
+
+// broken classifier per memo
+function classify(v) {
+  if (v == null) return {broken:false, reason:'null'};
+  const s = String(v).trim();
+  if (s === '') return {broken:true, reason:'empty'};
+  const low = s.toLowerCase();
+  // NOT broken (verified legit non-numeric)
+  if (low === 'hide') return {broken:false, reason:'leather-hide'};
+  if (/untrimmed/.test(low)) return {broken:false, reason:'maya-untrimmed'};
+  if (/sold per yard/.test(low)) return {broken:false, reason:'per-yard'};
+  if (/pillow|cushion/.test(low)) return {broken:false, reason:'pillow'};
+  // Elitis european decimal like "0,7m (27\")" -> has a real inch width in parens
+  if (/^0[.,]\d+\s*m/.test(low) && /\d+\s*("|in)/.test(low)) return {broken:false, reason:'euro-decimal-with-inches'};
+  // BROKEN classes
+  if (s === '0') return {broken:true, reason:'literal-zero'};
+  if (/^0\s*cm\s*\(0\.00/.test(low)) return {broken:true, reason:'zero-cm'};
+  if (low === 'tbd') return {broken:true, reason:'placeholder-tbd'};
+  if (/call to verify/.test(low)) return {broken:true, reason:'placeholder-call'};
+  if (low === '(ft)') return {broken:true, reason:'unit-only-ft'};
+  if (low === 'roll length') return {broken:true, reason:'label-only'};
+  if (s === ':') return {broken:true, reason:'colon-only'};
+  if (/wallpaper\.?$/.test(low) && !/\d/.test(s)) return {broken:true, reason:'desc-leaked'};
+  // general: no digit at all AND not a known-legit non-numeric => suspicious (report, not auto)
+  if (!/\d/.test(s)) return {broken:true, reason:'no-digit-nonlegit'};
+  // has a digit but is it a real zero width? "0 cm" variants, or purely "0..."
+  if (/^0(\.0+)?\s*(cm|in|"|mm|m)?$/.test(low)) return {broken:true, reason:'zero-width'};
+  return {broken:false, reason:'ok'};
+}
+
+const out = [];
+let cursor = null, page=0;
+const q = `query($cursor:String){
+  products(first:200, after:$cursor, query:"status:active") {
+    pageInfo{hasNextPage endCursor}
+    nodes{ id title status vendor handle
+      metafield(namespace:"custom", key:"width"){ id value }
+    }
+  }
+}`;
+let total=0, withWidth=0;
+while(true){
+  const d = await gql(q,{cursor});
+  const conn = d.products;
+  for(const n of conn.nodes){
+    total++;
+    if(!n.metafield) continue;
+    withWidth++;
+    const c = classify(n.metafield.value);
+    if(c.broken){
+      out.push({id:n.id, title:n.title, vendor:n.vendor, handle:n.handle,
+        mfId:n.metafield.id, value:n.metafield.value, reason:c.reason});
+    }
+  }
+  page++;
+  process.stderr.write(`page ${page} scanned=${total} withWidth=${withWidth} broken=${out.length}\r`);
+  if(!conn.pageInfo.hasNextPage) break;
+  cursor = conn.pageInfo.endCursor;
+}
+process.stderr.write('\n');
+fs.writeFileSync('broken-live.json', JSON.stringify(out,null,2));
+console.log(`\nTOTAL active scanned: ${total}`);
+console.log(`with custom.width: ${withWidth}`);
+console.log(`BROKEN now: ${out.length}`);
+const byReason={}, byVendor={};
+for(const o of out){ byReason[o.reason]=(byReason[o.reason]||0)+1; byVendor[o.vendor]=(byVendor[o.vendor]||0)+1; }
+console.log('by reason:', JSON.stringify(byReason,null,2));
+console.log('by vendor:', JSON.stringify(byVendor,null,2));
diff --git a/to-flag.json b/to-flag.json
new file mode 100644
index 0000000..28e142d
--- /dev/null
+++ b/to-flag.json
@@ -0,0 +1,252 @@
+[
+  {
+    "id": "gid://shopify/Product/1495267803248",
+    "title": "Vaughn Trees",
+    "vendor": "LA Walls",
+    "handle": "vaughn-trees-tre-23000",
+    "mfId": "gid://shopify/Metafield/34797755695155",
+    "value": "Call to Verify",
+    "reason": "placeholder-call",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1495267901552",
+    "title": "Vaughn Trees",
+    "vendor": "LA Walls",
+    "handle": "vaughn-trees-tre-23001",
+    "mfId": "gid://shopify/Metafield/36116011417651",
+    "value": "Call to Verify",
+    "reason": "placeholder-call",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1495268262000",
+    "title": "Vaughn Trees",
+    "vendor": "LA Walls",
+    "handle": "vaughn-trees-tre-23003",
+    "mfId": "gid://shopify/Metafield/34796429115443",
+    "value": "Call to Verify",
+    "reason": "placeholder-call",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1495268491376",
+    "title": "Vaughn Trees",
+    "vendor": "LA Walls",
+    "handle": "vaughn-trees-tre-23004",
+    "mfId": "gid://shopify/Metafield/34797632978995",
+    "value": "Call to Verify",
+    "reason": "placeholder-call",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1495268720752",
+    "title": "Vaughn Trees",
+    "vendor": "LA Walls",
+    "handle": "vaughn-trees-tre-23005",
+    "mfId": "gid://shopify/Metafield/34799290744883",
+    "value": "Call to Verify",
+    "reason": "placeholder-call",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1496337842288",
+    "title": "Museum Gallery Wallcovering",
+    "vendor": "Designer Wallcoverings",
+    "handle": "museum-gallery-wallpaper-ama-52523",
+    "mfId": "gid://shopify/Metafield/34782701355059",
+    "value": "TBD",
+    "reason": "placeholder-tbd",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1496338038896",
+    "title": "Old Luggage Wallcovering",
+    "vendor": "Designer Wallcoverings",
+    "handle": "old-luggage-wallpaper-ama-52524",
+    "mfId": "gid://shopify/Metafield/34782701453363",
+    "value": "TBD",
+    "reason": "placeholder-tbd",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1496338301040",
+    "title": "Rockefeller Wallcovering",
+    "vendor": "Designer Wallcoverings",
+    "handle": "rockefeller-wallpaper-ama-52526",
+    "mfId": "gid://shopify/Metafield/34791841824819",
+    "value": "TBD",
+    "reason": "placeholder-tbd",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1496338563184",
+    "title": "Rockefeller Wallcovering",
+    "vendor": "Designer Wallcoverings",
+    "handle": "rockefeller-wallpaper-ama-52527",
+    "mfId": "gid://shopify/Metafield/34782701617203",
+    "value": "TBD",
+    "reason": "placeholder-tbd",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1497734250608",
+    "title": "Butterflies Fabric - Ice Blue",
+    "vendor": "British Walls",
+    "handle": "butterflies-blue-bga-47948",
+    "mfId": "gid://shopify/Metafield/34402830286899",
+    "value": "Per yard ",
+    "reason": "no-digit-nonlegit",
+    "flagReason": "valid selling-unit descriptor Per yard - NOT broken, exclude"
+  },
+  {
+    "id": "gid://shopify/Product/1501667983472",
+    "title": "Flattering Flamingo Midnight Blue | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-midnight-blue-whm-78001",
+    "mfId": "gid://shopify/Metafield/34421937963059",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1501668278384",
+    "title": "Flattering Flamingo Grey | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-grey-whm-78002",
+    "mfId": "gid://shopify/Metafield/34421938880563",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1501668802672",
+    "title": "Vintage Story Time | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "vintage-story-time-wallpaper-whm-78005",
+    "mfId": "gid://shopify/Metafield/34421940715571",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1501668999280",
+    "title": "Flattering Flamingo Midnight Blue | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-midnight-blue-whm-78001-room",
+    "mfId": "gid://shopify/Metafield/34421938257971",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1501669392496",
+    "title": "Vintage Story Time | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "vintage-story-time-wallpaper-whm-78005-room",
+    "mfId": "gid://shopify/Metafield/34421941076019",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1501669523568",
+    "title": "Flattering Flamingo Midnight Blue | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-midnight-blue-whm-78001-zoom",
+    "mfId": "gid://shopify/Metafield/34421937668147",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1501669654640",
+    "title": "Flattering Flamingo Grey | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-grey-whm-78002-zoom",
+    "mfId": "gid://shopify/Metafield/34421938552883",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/1501669884016",
+    "title": "Flattering Flamingo Light Blue | Traditional Whimsy",
+    "vendor": "Traditional Whimsy",
+    "handle": "flattering-flamingo-wallpaper-light-blue-whm-78003-zoom",
+    "mfId": "gid://shopify/Metafield/34421939175475",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/3928407179329",
+    "title": "Lafayette's Ballroom Flocked Velvet",
+    "vendor": "Phillipe Romano",
+    "handle": "lafayettes-ballroom-flocked-velvet-prnc-26701",
+    "mfId": "gid://shopify/Metafield/34394124091443",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/7422307663923",
+    "title": "Monte Carlo Bul - Cadet/G Blue By Lee Jofa | Trim Bullion",
+    "vendor": "Lee Jofa",
+    "handle": "dwkk-g45e3d7cc",
+    "mfId": "gid://shopify/Metafield/34783491719219",
+    "value": "0",
+    "reason": "literal-zero",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/7422324604979",
+    "title": "Timothy - Sky Blue By Lee Jofa | Barbara Barry Collection |  Trim Fringe",
+    "vendor": "Lee Jofa",
+    "handle": "dwkk-g12a34adc",
+    "mfId": "gid://shopify/Metafield/34783457968179",
+    "value": "0",
+    "reason": "literal-zero",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/7422324637747",
+    "title": "Timothy - Blue  By Lee Jofa | Barbara Barry Collection |  Trim Fringe",
+    "vendor": "Lee Jofa",
+    "handle": "dwkk-g39ddb0be",
+    "mfId": "gid://shopify/Metafield/34783457902643",
+    "value": "0",
+    "reason": "literal-zero",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/7506268946483",
+    "title": "Adhesive Adhesive Accessory | Lincrusta",
+    "vendor": "Lincrusta",
+    "handle": "lin-980044-rdadh50-adhesive-lincrusta",
+    "mfId": "gid://shopify/Metafield/36116324745267",
+    "value": "Roll Length",
+    "reason": "label-only",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/7506269110323",
+    "title": "Bonding Bonding Accessory | Lincrusta",
+    "vendor": "Lincrusta",
+    "handle": "lin-980046-rdprm10-bonding-lincrusta",
+    "mfId": "gid://shopify/Metafield/36116325171251",
+    "value": "Roll Length",
+    "reason": "label-only",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  },
+  {
+    "id": "gid://shopify/Product/7506269208627",
+    "title": "Bonding Bonding Accessory | Lincrusta",
+    "vendor": "Lincrusta",
+    "handle": "lin-980047-rdprm25-bonding-lincrusta",
+    "mfId": "gid://shopify/Metafield/36116325236787",
+    "value": "Roll Length",
+    "reason": "label-only",
+    "flagReason": "no vendor-catalog width source; do not invent"
+  }
+]
\ No newline at end of file
diff --git a/to-write.json b/to-write.json
new file mode 100644
index 0000000..c163105
--- /dev/null
+++ b/to-write.json
@@ -0,0 +1,57 @@
+[
+  {
+    "id": "gid://shopify/Product/1501562339440",
+    "title": "Phillipe Romano - Renaissance Metal Leaf",
+    "vendor": "Phillipe Romano",
+    "handle": "phillipe-romano-renaissance-metal-leaf-rml-33052",
+    "mfId": "gid://shopify/Metafield/34421789917235",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "newWidth": "54\"",
+    "source": "phillipe_romano_catalog Renaissance Metal Leaf uniform 54\""
+  },
+  {
+    "id": "gid://shopify/Product/1501562896496",
+    "title": "Phillipe Romano - Renaissance Metal Leaf",
+    "vendor": "Phillipe Romano",
+    "handle": "phillipe-romano-renaissance-metal-leaf-rml-33054",
+    "mfId": "gid://shopify/Metafield/34421790539827",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "newWidth": "54\"",
+    "source": "phillipe_romano_catalog Renaissance Metal Leaf uniform 54\""
+  },
+  {
+    "id": "gid://shopify/Product/1501563355248",
+    "title": "Phillipe Romano - Renaissance Metal Leaf",
+    "vendor": "Phillipe Romano",
+    "handle": "phillipe-romano-renaissance-metal-leaf-rml-33056",
+    "mfId": "gid://shopify/Metafield/34421791227955",
+    "value": "0 cm (0.00\")",
+    "reason": "zero-cm",
+    "newWidth": "54\"",
+    "source": "phillipe_romano_catalog Renaissance Metal Leaf uniform 54\""
+  },
+  {
+    "id": "gid://shopify/Product/7506088820787",
+    "title": "Acanthus Embossed Natural Paintable Sidewall | Lincrusta",
+    "vendor": "Lincrusta",
+    "handle": "lin-980014-rd1960fr-acanthus-lincrusta",
+    "mfId": "gid://shopify/Metafield/34484412776499",
+    "value": ":",
+    "reason": "colon-only",
+    "newWidth": "20 9/16 inches",
+    "source": "lincrusta_catalog RD1960FR width text"
+  },
+  {
+    "id": "gid://shopify/Product/7786558947379",
+    "title": "Abaca La Perle Rare | Elitis",
+    "vendor": "Elitis",
+    "handle": "abaca-la-perle-rare-elitis",
+    "mfId": "gid://shopify/Metafield/34404064329779",
+    "value": "plant effect wallpaper.",
+    "reason": "desc-leaked",
+    "newWidth": "39\"",
+    "source": "elitis_catalog Abaca line uniform 39\""
+  }
+]
\ No newline at end of file
diff --git a/verify.mjs b/verify.mjs
new file mode 100644
index 0000000..639b5e8
--- /dev/null
+++ b/verify.mjs
@@ -0,0 +1,12 @@
+import fs from 'fs';
+const env = Object.fromEntries(fs.readFileSync('.env','utf8').split('\n').filter(l=>l.includes('=')&&!l.startsWith('#')).map(l=>{const i=l.indexOf('=');return [l.slice(0,i).trim(), l.slice(i+1).trim()];}));
+const TOKEN=env.SHOPIFY_ADMIN_TOKEN;const API='https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json';
+async function gql(q,v={}){const r=await fetch(API,{method:'POST',headers:{'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v})});return (await r.json()).data;}
+const items=JSON.parse(fs.readFileSync('to-write.json','utf8'));
+const handles=process.argv[2]==='canary'?items.slice(0,3):items;
+for(const it of handles){
+  const d=await gql(`query($id:ID!){product(id:$id){handle metafield(namespace:"custom",key:"width"){value}}}`,{id:it.id});
+  const v=d.product.metafield?.value;
+  const ok = v===it.newWidth;
+  console.log(`${ok?'✓':'✗'} ${it.handle}  live="${v}"  expected="${it.newWidth}"`);
+}

(oldest)  ·  back to Dw Width Fix  ·  (newest)