← back to Greenland Onboard
scripts/rerule-material-collections.mjs
40 lines
#!/usr/bin/env node
// Tighten the 19 material smart collections to THIS line only: re-rule from
// [vendor=Phillipe Romano, tag=<material>] → [tag="Coastal Naturals", tag=<material>].
import { readFileSync } from 'node:fs';
import { execFileSync } from 'node:child_process';
const env = readFileSync(`${process.env.HOME}/Projects/secrets-manager/.env`, 'utf8');
const pick = (k) => (env.match(new RegExp(`^${k}=(.*)$`, 'm'))?.[1] || '').replace(/^['"]|['"]$/g, '').trim();
const STORE = pick('SHOPIFY_STORE') || 'designer-laboratory-sandbox.myshopify.com';
const TOKEN = pick('SHOPIFY_ADMIN_TOKEN');
const API = `https://${STORE}/admin/api/2024-10`;
const DB = 'postgresql:///dw_unified?host=/tmp&user=stevestudio2';
const H = { 'X-Shopify-Access-Token': TOKEN, 'Content-Type': 'application/json' };
const sleep = ms => new Promise(r => setTimeout(r, ms));
const PSQL = '/opt/homebrew/opt/postgresql@14/bin/psql';
const MATWORD = { Silk:'Silk', Grass:'Grasscloth', Wood:'Wood Veneer', Suede:'Suede', Linen:'Linen', Raffia:'Raffia',
'Paper Weave':'Paper Weave', Abaca:'Abaca', Hemp:'Hemp', Sisal:'Sisal', Jute:'Jute', Velvet:'Velvet', Wool:'Wool',
Arrowroot:'Arrowroot', 'Cotton Yarn':'Cotton', 'Water hyacinth':'Water Hyacinth', 'Metal Leaf':'Metal Leaf',
'PE Weaving / PE Woven Material':'Woven', Specialty:'Signature', 'Multi-material':'Mixed Media' };
const slug = s => s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
const materials = JSON.parse(execFileSync(PSQL, [DB, '-tAc', `select coalesce(json_agg(distinct material),'[]') from greenland_full_catalog`], { encoding: 'utf8' }).trim());
let ok = 0, fail = 0;
for (const m of materials) {
const handle = `pr-${slug(MATWORD[m] || m)}`;
try {
const found = await (await fetch(`${API}/smart_collections.json?handle=${handle}&fields=id`, { headers: H })).json();
const id = found.smart_collections?.[0]?.id;
if (!id) { console.log(` ? ${handle} not found`); fail++; continue; }
const body = { smart_collection: { id, disjunctive: false,
rules: [ { column: 'tag', relation: 'equals', condition: 'Coastal Naturals' },
{ column: 'tag', relation: 'equals', condition: m } ] } };
const r = await fetch(`${API}/smart_collections/${id}.json`, { method: 'PUT', headers: H, body: JSON.stringify(body) });
if (!r.ok) throw new Error(`${r.status} ${(await r.text()).slice(0,120)}`);
ok++; console.log(` ~ ${handle} → [Coastal Naturals AND ${m}]`);
await sleep(500);
} catch (e) { fail++; console.log(` FAIL ${handle}: ${String(e.message).slice(0,100)}`); await sleep(700); }
}
console.log(`\nDONE re-ruled=${ok} failed=${fail}`);