← 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}`);