← back to Designerwallcoverings
chore: lint, refactor, v0.1.1 (session close) — execFileSync + negative-limit guards + set -e + error log on stroheim-onboard
6bae8c2655bed67ffbf7770ceb9962bdbbeee7ba · 2026-07-26 19:57:41 -0700 · Steve Abrams
Files touched
M package.jsonM scripts/stroheim-onboard/build-payloads.mjsM scripts/stroheim-onboard/create-drafts.mjsM scripts/stroheim-onboard/go-live.mjsM scripts/stroheim-onboard/resume.shM scripts/stroheim-onboard/settlement-gate.mjs
Diff
commit 6bae8c2655bed67ffbf7770ceb9962bdbbeee7ba
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sun Jul 26 19:57:41 2026 -0700
chore: lint, refactor, v0.1.1 (session close) — execFileSync + negative-limit guards + set -e + error log on stroheim-onboard
---
package.json | 6 ++++--
scripts/stroheim-onboard/build-payloads.mjs | 10 ++++++----
scripts/stroheim-onboard/create-drafts.mjs | 4 ++--
scripts/stroheim-onboard/go-live.mjs | 2 +-
scripts/stroheim-onboard/resume.sh | 2 +-
scripts/stroheim-onboard/settlement-gate.mjs | 2 +-
6 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/package.json b/package.json
index 533ed9e..64c9e07 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,15 @@
{
"name": "designerwallcoverings-ai",
- "version": "0.1.0",
+ "version": "0.1.1",
"private": true,
"description": "designerwallcoverings.ai — AI room-render landing. Upload a room photo, get matching wallcoverings.",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
- "engines": { "node": ">=20" },
+ "engines": {
+ "node": ">=20"
+ },
"dependencies": {
"express": "^4.19.2",
"multer": "^2.0.1"
diff --git a/scripts/stroheim-onboard/build-payloads.mjs b/scripts/stroheim-onboard/build-payloads.mjs
index 97435bd..6734004 100644
--- a/scripts/stroheim-onboard/build-payloads.mjs
+++ b/scripts/stroheim-onboard/build-payloads.mjs
@@ -21,11 +21,12 @@
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
-import { execSync } from 'node:child_process';
+import { execFileSync } from 'node:child_process';
const HERE = path.dirname(fileURLToPath(import.meta.url));
const OUT = path.join(HERE, 'out');
-const DB = 'postgresql:///dw_unified?host=/tmp';
+const PSQL = '/opt/homebrew/opt/postgresql@14/bin/psql';
+const PGENV = { ...process.env, PGHOST: '/tmp', PGDATABASE: 'dw_unified' };
const BRAND = 'Stroheim';
const SAMPLE_PRICE = '4.25';
@@ -36,13 +37,14 @@ const clean = s => (s || '').replace(/wall\s*paper/ig, 'Wallcovering').replace(/
const isBadWord = s => !s || /unknown/i.test(s);
function rows() {
- const json = execSync(`psql "${DB}" -tAc "select coalesce(json_agg(row_to_json(t))::text,'[]') from (
+ const SQL = `select coalesce(json_agg(row_to_json(t))::text,'[]') from (
select mfr_sku, proposed_dw_sku as dw_sku, pattern_name, color_name, collection, product_type,
width, repeat_v, repeat_h, material, book,
price_retail, dedup_status, image_url, thumb_url, product_url, shopify_product_id
from stroheim_catalog
where mfr_sku is not null
- order by mfr_sku) t"`, { encoding: 'utf8', maxBuffer: 256 * 1024 * 1024 });
+ order by mfr_sku) t`;
+ const json = execFileSync(PSQL, ['-d', 'dw_unified', '-tAc', SQL], { env: PGENV, encoding: 'utf8', maxBuffer: 256 * 1024 * 1024 });
return JSON.parse(json.trim());
}
diff --git a/scripts/stroheim-onboard/create-drafts.mjs b/scripts/stroheim-onboard/create-drafts.mjs
index c1f56bf..e6916b7 100644
--- a/scripts/stroheim-onboard/create-drafts.mjs
+++ b/scripts/stroheim-onboard/create-drafts.mjs
@@ -72,7 +72,7 @@ async function liveStroheimSkus() {
const s = new Set();
for (const p of prods) for (const v of (p.variants || [])) if (v.sku) s.add(v.sku.toUpperCase());
return s;
- } catch { return new Set(); }
+ } catch (e) { console.error(' ⚠ liveStroheimSkus() failed:', String(e).slice(0, 120), '— live-SKU dedup disabled this run'); return new Set(); }
}
async function main() {
@@ -86,7 +86,7 @@ async function main() {
const blocked = payloads.filter(p => verdict.get(p.sku.toUpperCase()) === 'BLOCK').length;
const ungated = payloads.filter(p => !verdict.has(p.sku.toUpperCase())).length;
let todo = gatedOk.filter(p => !liveSkus.has(p.sku.toUpperCase()) && !createdSku.has(p.sku.toUpperCase()));
- if (LIMIT) todo = todo.slice(0, LIMIT);
+ if (LIMIT > 0) todo = todo.slice(0, LIMIT);
const headroom = budget.remaining(BUDGET_CAT);
console.log(`Store ${SHOP} · token …${TOKEN.slice(-4)} · payloads ${payloads.length} · settlement OK ${gatedOk.length} / BLOCK ${blocked} / ungated ${ungated} · live ${liveSkus.size} · to create ${todo.length} · '${BUDGET_CAT}' headroom ${headroom} variants (~${Math.floor(headroom/2)} products) · ${APPLY ? 'APPLY' : 'DRY-RUN'}`);
diff --git a/scripts/stroheim-onboard/go-live.mjs b/scripts/stroheim-onboard/go-live.mjs
index 8a76d3e..8aea4fb 100644
--- a/scripts/stroheim-onboard/go-live.mjs
+++ b/scripts/stroheim-onboard/go-live.mjs
@@ -117,7 +117,7 @@ async function goLive(pid, sku, mfrSku) {
const verdict = new Map(loadJsonl('settlement-verdicts.jsonl').map(r => [r.sku.toUpperCase(), r.verdict]));
const payload = new Map(loadJsonl('payloads.jsonl').map(o => [o.sku.toUpperCase(), o]));
let todo = loadJsonl('created.jsonl').filter(r => !done.has(r.sku));
- if (LIMIT) todo = todo.slice(0, LIMIT);
+ if (LIMIT > 0) todo = todo.slice(0, LIMIT);
console.log(`go-live: ${todo.length} drafts · loc ${LOCATION_ID} · qty ${TARGET_QTY} · ${PUBLICATIONS.length} channels (Google excluded) · ${APPLY ? 'APPLY' : 'DRY-RUN'}`);
if (!APPLY) { console.log('first 3:', todo.slice(0, 3).map(r => r.sku).join(', ')); console.log('DRY-RUN. --apply to execute (Steve-gated activation).'); return; }
diff --git a/scripts/stroheim-onboard/resume.sh b/scripts/stroheim-onboard/resume.sh
index 2900caf..ecb55f9 100755
--- a/scripts/stroheim-onboard/resume.sh
+++ b/scripts/stroheim-onboard/resume.sh
@@ -13,7 +13,7 @@
#
# HARD BLOCK: while price_retail is NULL, steps 1-4 no-op cleanly (build emits 0). This script
# is NOT scheduled in launchd (scheduled-job install is itself gated) — run it by hand.
-set -uo pipefail
+set -euo pipefail
cd "$(dirname "$0")" || exit 1
export PATH="/opt/homebrew/bin:/opt/homebrew/opt/postgresql@14/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
NODE="$(command -v node)"
diff --git a/scripts/stroheim-onboard/settlement-gate.mjs b/scripts/stroheim-onboard/settlement-gate.mjs
index 9ba2950..9263e37 100644
--- a/scripts/stroheim-onboard/settlement-gate.mjs
+++ b/scripts/stroheim-onboard/settlement-gate.mjs
@@ -87,7 +87,7 @@ async function main() {
const done = new Map(loadJsonl('settlement-verdicts.jsonl').map(r => [r.sku.toUpperCase(), r]));
let todo = payloads.filter(p => !done.has(p.sku.toUpperCase()));
if (ONLY_SET) todo = todo.filter(p => ONLY_SET.has(p.sku.toUpperCase()));
- if (LIMIT) todo = todo.slice(0, LIMIT);
+ if (LIMIT > 0) todo = todo.slice(0, LIMIT);
console.log(`settlement-gate · model ${MODEL} · payloads ${payloads.length} · already-gated ${done.size} · to gate ${todo.length} · est $${(todo.length * COST_PER_IMG).toFixed(4)} · ${APPLY ? 'APPLY' : 'DRY-RUN'}`);
if (payloads.length === 0) { console.log(' ℹ 0 payloads (price not yet sourced) — nothing to gate. $0.'); return; }
← 999aac3 recover wiped scripts/ tree: restore 325 untracked source fi
·
back to Designerwallcoverings
·
maharam-onboard: dedicated daily drip runner + launchd plist 18333b8 →