← back to Designer Wallcoverings
add Carnegie Seafoam manufacturer images
05a1d9a277a24ef262018ccb70bd1fac354e6cd3 · 2026-09-01 13:24:54 -0700 · Steve
Files touched
A data/carnegie-seafoam-images-RESTORE-2026-09-01T20-24-37-589Z.jsonA scripts/add-carnegie-seafoam-images.mjsA verification/TK-11047-seafoam-images-e2e.json
Diff
commit 05a1d9a277a24ef262018ccb70bd1fac354e6cd3
Author: Steve <steve@designerwallcoverings.com>
Date: Tue Sep 1 13:24:54 2026 -0700
add Carnegie Seafoam manufacturer images
---
...am-images-RESTORE-2026-09-01T20-24-37-589Z.json | 23 +++++++++
scripts/add-carnegie-seafoam-images.mjs | 15 ++++++
verification/TK-11047-seafoam-images-e2e.json | 59 ++++++++++++++++++++++
3 files changed, 97 insertions(+)
diff --git a/data/carnegie-seafoam-images-RESTORE-2026-09-01T20-24-37-589Z.json b/data/carnegie-seafoam-images-RESTORE-2026-09-01T20-24-37-589Z.json
new file mode 100644
index 00000000..9df6c2f5
--- /dev/null
+++ b/data/carnegie-seafoam-images-RESTORE-2026-09-01T20-24-37-589Z.json
@@ -0,0 +1,23 @@
+{
+ "ticket": "TK-11047",
+ "timestamp": "2026-09-01T20:24:37.875Z",
+ "product": {
+ "id": 7923378487347,
+ "title": "Carnegie Xorel Seafoam 1 Wallcovering",
+ "images": [
+ {
+ "id": 37910362325043,
+ "alt": null,
+ "position": 1,
+ "product_id": 7923378487347,
+ "created_at": "2026-08-18T18:10:50-07:00",
+ "updated_at": "2026-08-20T09:22:10-07:00",
+ "admin_graphql_api_id": "gid://shopify/MediaImage/28749817282611",
+ "width": 1370,
+ "height": 1370,
+ "src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/63831_square-swatch.jpg?v=1787101850",
+ "variant_ids": []
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/scripts/add-carnegie-seafoam-images.mjs b/scripts/add-carnegie-seafoam-images.mjs
new file mode 100644
index 00000000..d856609b
--- /dev/null
+++ b/scripts/add-carnegie-seafoam-images.mjs
@@ -0,0 +1,15 @@
+#!/usr/bin/env node
+import fs from'node:fs';import path from'node:path';
+const ROOT='/Users/macstudio3/Projects/Designer-Wallcoverings',apply=process.argv.includes('--apply'),productId='7923378487347',stamp=new Date().toISOString().replace(/[:.]/g,'-');
+const env=Object.fromEntries(fs.readFileSync(path.join(ROOT,'.env'),'utf8').split('\n').filter(x=>x.includes('=')).map(x=>{const i=x.indexOf('=');return[x.slice(0,i).trim(),x.slice(i+1).trim()]})),domain=env.SHOPIFY_STORE_DOMAIN||'designer-laboratory-sandbox.myshopify.com',token=env.SHOPIFY_ADMIN_TOKEN||env.SHOPIFY_ADMIN_ACCESS_TOKEN,headers={'X-Shopify-Access-Token':token,'Content-Type':'application/json'},sleep=ms=>new Promise(r=>setTimeout(r,ms));
+const targets=[
+ {src:'https://carnegiefabrics.com/media/catalog/product/beauty_shots/image/X/o/Xorel-Seafoam-Lifestyle_1.jpg',alt:'Carnegie Xorel Seafoam wallcovering room installation'},
+ {src:'https://carnegiefabrics.com/media/catalog/product/beauty_shots/image/S/e/Seafoam_3_1.jpg',alt:'Carnegie Xorel Seafoam wallcovering texture detail'},
+ {src:'https://carnegiefabrics.com/media/catalog/product/beauty_shots/image/s/e/seafoam-marketingimage-4.jpg',alt:'Carnegie Xorel Seafoam collection rolls'}
+];
+async function rest(method,endpoint,body,auth=token){for(let n=0;n<12;n++){const r=await fetch(`https://${domain}/admin/api/2024-10/${endpoint}`,{method,headers:{...headers,'X-Shopify-Access-Token':auth},body:body?JSON.stringify(body):undefined}),text=await r.text();let json;try{json=JSON.parse(text)}catch{json={raw:text}}if(r.status!==429&&r.status<500)return{status:r.status,json};await sleep(Math.min(12000,1000*(n+1)))}throw new Error('Shopify retries exhausted')}
+const before=await rest('GET',`products/${productId}.json?fields=id,title,images`);if(before.status!==200)throw new Error(`backup failed ${before.status}`);const images=before.json.product.images||[],existingAlts=new Set(images.map(x=>x.alt).filter(Boolean)),pending=targets.filter(x=>!existingAlts.has(x.alt));
+console.log(JSON.stringify({ticket:'TK-11047',apply,product_id:productId,title:before.json.product.title,before_images:images.length,pending:pending.length,targets},null,2));if(!apply)process.exit(0);
+const backupPath=path.join(ROOT,`data/carnegie-seafoam-images-RESTORE-${stamp}.json`);fs.writeFileSync(backupPath,JSON.stringify({ticket:'TK-11047',timestamp:new Date().toISOString(),product:before.json.product},null,2));
+const created=[];for(const x of pending){const r=await rest('POST',`products/${productId}/images.json`,{image:x});if(r.status!==200)throw new Error(`image upload failed ${r.status}: ${JSON.stringify(r.json).slice(0,500)}`);created.push({id:r.json.image.id,alt:r.json.image.alt,src:r.json.image.src,width:r.json.image.width,height:r.json.image.height});await sleep(700)}
+const after=await rest('GET',`products/${productId}.json?fields=id,title,images`);if(after.status!==200)throw new Error(`readback failed ${after.status}`);const got=after.json.product.images||[],checks=targets.map(t=>{const x=got.find(i=>i.alt===t.alt);return{alt:t.alt,present:!!x,width:x?.width||0,height:x?.height||0,valid_dimensions:(x?.width||0)>500&&(x?.height||0)>500}}),negative=await rest('GET','shop.json',null,'invalid'),idempotentPending=targets.filter(x=>!new Set(got.map(i=>i.alt).filter(Boolean)).has(x.alt)).length,proof={ticket:'TK-11047',risk_tier:'R4',timestamp:new Date().toISOString(),product_id:productId,before_images:images.length,after_images:got.length,created,checks,negative_auth_status:negative.status,idempotent_pending:idempotentPending,restore_path:backupPath,rollback:'Delete only created image IDs listed in this proof; original image snapshot retained.',verdict:checks.every(x=>x.present&&x.valid_dimensions)&&negative.status===401&&idempotentPending===0?'PASS':'FAIL'},proofPath=path.join(ROOT,'verification/TK-11047-seafoam-images-e2e.json');fs.writeFileSync(proofPath,JSON.stringify(proof,null,2));console.log(JSON.stringify({proof_path:proofPath,restore_path:backupPath,before_images:images.length,after_images:got.length,created:created.length,negative_auth_status:negative.status,idempotent_pending:idempotentPending,verdict:proof.verdict},null,2));if(proof.verdict!=='PASS')process.exit(2);
diff --git a/verification/TK-11047-seafoam-images-e2e.json b/verification/TK-11047-seafoam-images-e2e.json
new file mode 100644
index 00000000..af0dac73
--- /dev/null
+++ b/verification/TK-11047-seafoam-images-e2e.json
@@ -0,0 +1,59 @@
+{
+ "ticket": "TK-11047",
+ "risk_tier": "R4",
+ "timestamp": "2026-09-01T20:24:46.053Z",
+ "product_id": "7923378487347",
+ "before_images": 1,
+ "after_images": 4,
+ "created": [
+ {
+ "id": 38000633053235,
+ "alt": "Carnegie Xorel Seafoam wallcovering room installation",
+ "src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Xorel-Seafoam-Lifestyle_1.jpg?v=1788294279",
+ "width": 1250,
+ "height": 800
+ },
+ {
+ "id": 38000633151539,
+ "alt": "Carnegie Xorel Seafoam wallcovering texture detail",
+ "src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Seafoam_3_1.jpg?v=1788294282",
+ "width": 1024,
+ "height": 1024
+ },
+ {
+ "id": 38000633184307,
+ "alt": "Carnegie Xorel Seafoam collection rolls",
+ "src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/seafoam-marketingimage-4.jpg?v=1788294284",
+ "width": 1250,
+ "height": 800
+ }
+ ],
+ "checks": [
+ {
+ "alt": "Carnegie Xorel Seafoam wallcovering room installation",
+ "present": true,
+ "width": 1250,
+ "height": 800,
+ "valid_dimensions": true
+ },
+ {
+ "alt": "Carnegie Xorel Seafoam wallcovering texture detail",
+ "present": true,
+ "width": 1024,
+ "height": 1024,
+ "valid_dimensions": true
+ },
+ {
+ "alt": "Carnegie Xorel Seafoam collection rolls",
+ "present": true,
+ "width": 1250,
+ "height": 800,
+ "valid_dimensions": true
+ }
+ ],
+ "negative_auth_status": 401,
+ "idempotent_pending": 0,
+ "restore_path": "/Users/macstudio3/Projects/Designer-Wallcoverings/data/carnegie-seafoam-images-RESTORE-2026-09-01T20-24-37-589Z.json",
+ "rollback": "Delete only created image IDs listed in this proof; original image snapshot retained.",
+ "verdict": "PASS"
+}
\ No newline at end of file
← 1292724e complete Carnegie exact spec recovery
·
back to Designer Wallcoverings
·
auto-data-snapshot: 2026-09-01T13:36:10 (5 data files) — dat b3a7325c →