← back to Greenland Onboard
auto-save: 2026-07-13T01:52:00 (1 files) — scripts/rerule-material-collections.mjs
3fd488ba15b85556425972e96254018afa9e444b · 2026-07-13 01:52:14 -0700 · Steve Abrams
Files touched
A scripts/rerule-material-collections.mjs
Diff
commit 3fd488ba15b85556425972e96254018afa9e444b
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jul 13 01:52:14 2026 -0700
auto-save: 2026-07-13T01:52:00 (1 files) — scripts/rerule-material-collections.mjs
---
scripts/rerule-material-collections.mjs | 39 +++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/scripts/rerule-material-collections.mjs b/scripts/rerule-material-collections.mjs
new file mode 100644
index 0000000..00042b5
--- /dev/null
+++ b/scripts/rerule-material-collections.mjs
@@ -0,0 +1,39 @@
+#!/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}`);
← b9d4529 Add refresh-viewer.sh, README internal-tool docs, .deploy.co
·
back to Greenland Onboard
·
auto-save: 2026-07-13T08:53:46 (1 files) — scripts/make-cork 1809334 →