← back to Filemaker Mcp
scripts/greenland-disco-2026-07-14.mjs
89 lines
import fs from 'fs';
import * as fm from '/Users/macstudio3/Projects/filemaker-mcp/src/fm-client.js';
import { execFileSync } from 'child_process';
const env = fs.readFileSync('/Users/macstudio3/Projects/secrets-manager/.env','utf8');
const get = k => (env.match(new RegExp('^'+k+'=(.*)$','m'))||[])[1]?.trim();
const TOKEN = get('SHOPIFY_ADMIN_TOKEN');
const STORE = get('SHOPIFY_STORE') || 'designer-laboratory-sandbox.myshopify.com';
const API = `https://${STORE}/admin/api/2024-10`;
const H = { 'X-Shopify-Access-Token': TOKEN, 'Content-Type':'application/json' };
const FULL = '*List Wallpapers - Full View';
const ENTRY = 'Add wallcovering';
const TODAY = '07/14/2026'; // FileMaker date format MM/DD/DD
const TODAY_ISO = '2026-07-14';
const sleep = ms=>new Promise(r=>setTimeout(r,ms));
// [dw_sku, color, mfr, city, product_id, fm_recId, series]
const items = [
['Cork-500210','Sharkskin','G0154NQ8290','Southampton','7880972369971','536960'],
['Cork-500220','Eden','G0154NQ8291','Southampton','7880972402739','536961'],
['Cork-500230','Deep Taupe','G0154NQ8292','Southampton','7880972533811','536962'],
['Cork-500240','Coffee Bean','G0154NQ8293','Southampton','7880972468275','536963'],
['Cork-500250','Argan Oil','G0154NQ8294','Southampton','7880972435507','536964'],
['Cork-500260','Winter Bloom','G0154NQ8295','Southampton','7880972501043','536965'],
['Cork-500270','White','G0155NQ8296','Palm Beach','7880972140595','536966'],
['Cork-500280','Eiffel Tower','G0155NQ8297','Palm Beach','7880972075059','536967'],
['Cork-500290','Amphora','G0155NQ8298','Palm Beach','7880972173363','536968'],
['Cork-500300','Rhododendron','G0155NQ8299','Palm Beach','7880972206131','536969'],
['Cork-500310','Picante','G0155NQ8300','Palm Beach','7880972238899','536970'],
['Cork-500320','Taupe Gray','G0155NQ8301','Palm Beach','7880972271667','536971'],
['Cork-500330','Java','G0155NQ8302','Palm Beach','7880972337203','536972'],
['Cork-500340','Blue Nights','G0155NQ8303','Palm Beach','7880972304435','536973'],
['Cork-500350','Turkish Tile','G0155NQ8304','Palm Beach','7880972107827','536974'],
];
const ONLY = process.env.ONLY; // canary: only this dw_sku
const work = ONLY ? items.filter(i=>i[0]===ONLY) : items;
function psql(sql){
return execFileSync('psql', ['host=/tmp dbname=dw_unified','-tAc',sql], {encoding:'utf8'}).trim();
}
async function shopifyArchive(pid){
const gid = `gid://shopify/Product/${pid}`;
const q = `mutation($id:ID!){ productUpdate(input:{id:$id, status:ARCHIVED}){ product{ id status } userErrors{ field message } } }`;
const r = await fetch(`${API}/graphql.json`, {method:'POST',headers:H,body:JSON.stringify({query:q,variables:{id:gid}})});
const j = await r.json();
if (j.errors) throw new Error('GQL:'+JSON.stringify(j.errors));
const ue = j.data.productUpdate.userErrors;
if (ue && ue.length) throw new Error('userErrors:'+JSON.stringify(ue));
return j.data.productUpdate.product.status;
}
const report = [];
for (const [sku,color,mfr,city,pid,recId] of work){
const row = { sku, color, mfr, pid, recId, shopify:null, fm:null, disco:null, err:[] };
// 1. Shopify archive
try { row.shopify = await shopifyArchive(pid); }
catch(e){ row.err.push('shopify:'+e.message); }
// 2. FileMaker Date Discontinued
try {
await fm.updateRecord('WALLPAPER', ENTRY, recId, { 'Date Discontinued': TODAY }, { dryRun:false });
row.fm = 'set';
} catch(e){
// fall back to FULL layout if the field isn't on ENTRY
try { await fm.updateRecord('WALLPAPER', FULL, recId, { 'Date Discontinued': TODAY }, { dryRun:false }); row.fm='set(full)'; }
catch(e2){ row.err.push('fm:'+(e2.fmCode||e2.message)); }
}
// 3. dw_unified disco_items + mirror status=archived
try {
const name = `${city}-${color} Cork Wallcovering`;
const combo = sku; // Cork-#####
const esc = s => s.replace(/'/g,"''");
psql(`INSERT INTO disco_items (combo_sku,date_discontinued,on_shopify,shopify_handle,name,mfr_name,color,series,js_pattern,mfr_pattern,supplier,shopify_status,source)
VALUES ('${combo}','${TODAY_ISO}','archived',NULL,'${esc(name)}','Phillipe Romano','${esc(color)}','Cork','${sku.replace('Cork-','')}','${mfr}','GREEN','archived','greenland-disco-2026-07-14')
ON CONFLICT DO NOTHING;`);
// update mirror: authoritative live rows keyed by gid, sku Cork-#####-Sample
const n = psql(`UPDATE shopify_products SET status='archived' WHERE shopify_id='gid://shopify/Product/${pid}' RETURNING 1;`);
row.disco = `disco+mirror(${(n.match(/1/g)||[]).length} rows)`;
} catch(e){ row.err.push('disco:'+e.message); }
report.push(row);
console.log(`${sku} | ${city}-${color} | shopify=${row.shopify||'ERR'} | fm=${row.fm||'ERR'} | ${row.disco||'ERR'} ${row.err.length?('| ERRORS: '+row.err.join(' ;; ')):''}`);
await sleep(150);
}
fs.writeFileSync('/tmp/gl-disco-apply-'+(ONLY||'all')+'.json', JSON.stringify(report,null,2));