← back to Koroseal Goodrich Audit
TK-10347: applied 6 approved Koroseal cross-link image swaps live + verified; ED01-04 still pending decision
09a9d53b7d69bb5f2dcd59e67ed745230c25c56a · 2026-08-08 07:46:24 -0700 · Steve Abrams
Files touched
A tk10347/apply_swaps.mjs
Diff
commit 09a9d53b7d69bb5f2dcd59e67ed745230c25c56a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat Aug 8 07:46:24 2026 -0700
TK-10347: applied 6 approved Koroseal cross-link image swaps live + verified; ED01-04 still pending decision
---
tk10347/apply_swaps.mjs | 89 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/tk10347/apply_swaps.mjs b/tk10347/apply_swaps.mjs
new file mode 100644
index 0000000..80b4436
--- /dev/null
+++ b/tk10347/apply_swaps.mjs
@@ -0,0 +1,89 @@
+#!/usr/bin/env node
+// TK-10347 — apply 6 approved Koroseal cross-link image swaps on LIVE store.
+// Steve APPROVED + UNGATED (2026-08-08). Idempotent-ish: skips upload if same source already present.
+import fs from 'node:fs';
+const ENV = fs.readFileSync(process.env.HOME + '/Projects/secrets-manager/.env','utf8');
+const TOKEN = (ENV.match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m)||[])[1]?.trim().replace(/^["']|["']$/g,'');
+const STORE = 'designer-laboratory-sandbox.myshopify.com', API='2024-10';
+const URL = `https://${STORE}/admin/api/${API}/graphql.json`;
+const AK='https://koroseal.asset.akeneo.cloud';
+const KM='https://koroseal.com';
+const APPLY = process.argv.includes('--apply');
+
+const JOBS = [
+ {sku:'TAK-EA02-04', pid:'gid://shopify/Product/7519950110771', mode:'upload',
+ src:`${AK}/images/media/Kilika_ROOMSET_TAK_EA02_04.jpg`, alt:'Kilika Deep Taupe TAK-EA02-04',
+ wrong:'gid://shopify/MediaImage/24773828247603'},
+ {sku:'TAK-EA01-01', pid:'gid://shopify/Product/7519949357107', mode:'upload',
+ src:`${AK}/images/media/TAKUMI_ROOMSET_TAK_EA01_01__WEAVES_.jpg`, alt:'Cyrus Weave Linen Natural TAK-EA01-01',
+ wrong:'gid://shopify/MediaImage/24773827788851'},
+ {sku:'TAK-CA05-01', pid:'gid://shopify/Product/7519948603443', mode:'upload',
+ src:`${AK}/images/media/TAKUMI_ROOMSET_TAK_CA05_01__CORK_.jpg`, alt:'Aura Cork Silver TAK-CA05-01',
+ wrong:'gid://shopify/MediaImage/24773827297331'},
+ {sku:'SRD-CH1-02', pid:'gid://shopify/Product/7634018566195', mode:'upload',
+ src:`${AK}/thumbnails/media/chess_1_gray_pink_srd_ch1_02__sarah_rowland_for_koroseal.jpg`, alt:'Chess 1 Gray Pink SRD-CH1-02',
+ wrong:'gid://shopify/MediaImage/26514726125619'},
+ {sku:'8221-08', pid:'gid://shopify/Product/7584922009651', mode:'upload',
+ src:`${AK}/thumbnails/media/ramie_woven_8221_08_.jpg`, alt:'Ramie Woven 8221-08',
+ wrong:'gid://shopify/MediaImage/26434620620851'},
+ {sku:'SRD-AUR-02', pid:'gid://shopify/Product/7634018074675', mode:'reorder',
+ keep:'gid://shopify/MediaImage/26514716131379', // existing AURORA_SMOKE_SRD-AUR-02
+ wrong:'gid://shopify/MediaImage/26514747752499'},
+];
+
+async function gql(query, variables){
+ const r = await fetch(URL, {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) throw new Error('GraphQL errors: '+JSON.stringify(j.errors));
+ return j.data;
+}
+const sleep = ms => new Promise(r=>setTimeout(r,ms));
+
+async function firstMediaId(pid){
+ const d = await gql(`query($id:ID!){ product(id:$id){ media(first:1){ edges{ node{ id } } } } }`, {id:pid});
+ return d.product.media.edges[0]?.node?.id;
+}
+
+async function run(){
+ console.log(`APPLY=${APPLY} token=${TOKEN? 'present':'MISSING'}`);
+ for(const j of JOBS){
+ console.log(`\n=== ${j.sku} (${j.mode}) ===`);
+ let newId = j.keep;
+ if(j.mode==='upload'){
+ if(!APPLY){ console.log(' DRY: would createMedia', j.src); }
+ else {
+ const d = await gql(`mutation($pid:ID!,$m:[CreateMediaInput!]!){ productCreateMedia(productId:$pid, media:$m){ media{ ... on MediaImage{ id status } } mediaUserErrors{ field message } } }`,
+ {pid:j.pid, m:[{originalSource:j.src, mediaContentType:'IMAGE', alt:j.alt}]});
+ const ue=d.productCreateMedia.mediaUserErrors; if(ue.length) throw new Error(j.sku+' createMedia: '+JSON.stringify(ue));
+ newId = d.productCreateMedia.media[0].id;
+ console.log(' created', newId, 'status', d.productCreateMedia.media[0].status);
+ // poll READY
+ for(let i=0;i<30;i++){
+ const p = await gql(`query($id:ID!){ node(id:$id){ ... on MediaImage{ status image{ url } } } }`, {id:newId});
+ const st=p.node.status;
+ if(st==='READY'){ console.log(' READY', (p.node.image?.url||'').slice(-70)); break; }
+ if(st==='FAILED') throw new Error(j.sku+' media FAILED');
+ await sleep(2000);
+ }
+ }
+ }
+ // reorder new/keep media to position 0 (featured)
+ if(!APPLY){ console.log(' DRY: would reorder', newId||'<newId>', '->0 and delete', j.wrong); continue; }
+ const rd = await gql(`mutation($id:ID!,$moves:[MoveInput!]!){ productReorderMedia(id:$id, moves:$moves){ mediaUserErrors{ message } job{ id done } } }`,
+ {id:j.pid, moves:[{id:newId, newPosition:'0'}]});
+ const rue=rd.productReorderMedia.mediaUserErrors; if(rue.length) throw new Error(j.sku+' reorder: '+JSON.stringify(rue));
+ console.log(' reordered ->0');
+ await sleep(2500);
+ // delete the wrong sibling
+ const dd = await gql(`mutation($pid:ID!,$ids:[ID!]!){ productDeleteMedia(productId:$pid, mediaIds:$ids){ deletedMediaIds mediaUserErrors{ message } } }`,
+ {pid:j.pid, ids:[j.wrong]});
+ const due=dd.productDeleteMedia.mediaUserErrors; if(due.length) throw new Error(j.sku+' delete: '+JSON.stringify(due));
+ console.log(' deleted wrong', dd.productDeleteMedia.deletedMediaIds);
+ // verify featured
+ const fm = await firstMediaId(j.pid);
+ console.log(' NOW featured media =', fm, fm===newId?'✓':'(check)');
+ }
+ console.log('\nDONE');
+}
+run().catch(e=>{ console.error('ERROR:', e.message); process.exit(1); });
← 934f4d2 TK-10347: koroseal re-scrape resolution — 7 true defects w/
·
back to Koroseal Goodrich Audit
·
TK-10347: TAK-ED01-04 cropped cream weave applied live (Stev 3677657 →