← back to York Reprice 2026 08
cadence/york-auto-onboard.mjs
60 lines
#!/usr/bin/env node
/**
* york-auto-onboard.mjs — the ONE place the York cadence is allowed to WRITE to Shopify.
*
* Steve authorized (2026-07-13, AskUserQuestion): the cadence auto-onboards New York items as
* DRAFT, capped ~100 per run. This drips the pre-vetted onboard queue
* (data/onboard-payloads-enriched.json) into Shopify over successive mornings until exhausted.
*
* HARD RAILS (never widened here):
* • DRAFT only — york-new-create sets status:'DRAFT'; nothing goes ACTIVE. Publish stays a
* separate, explicit, Steve-gated step.
* • Cap 100 NEW creates per run (--limit); idempotent — SKUs already live are skipped.
* • ONBOARD bucket only. Reprice + disco remain strictly propose-only (memo, never auto-write).
* • The queue is PRE-VETTED: settlement-deepened (flora/fauna held), 39 image-flags excluded,
* dead-CDN images dropped, priced (naturals@roll_price_single, standard@MAP), gate-clean.
* • Fail-safe: any error is caught and logged; it never throws up into the cadence diff.
*
* Called at the tail of york-cadence.mjs. Returns {created,skipped,err,total_remaining}.
*/
import fs from 'node:fs';
import { execSync } from 'node:child_process';
const ROOT = process.env.HOME + '/Projects/york-reprice-2026-08';
const QUEUE = ROOT + '/data/onboard-payloads-enriched.json';
const CAP = 100;
export function autoOnboard() {
const result = { created: 0, skipped: 0, err: 0, queue_size: 0, ran: false, note: '' };
try {
if (!fs.existsSync(QUEUE)) { result.note = 'no onboard queue file — nothing to onboard'; return result; }
const queue = JSON.parse(fs.readFileSync(QUEUE, 'utf8'));
result.queue_size = queue.length;
if (!queue.length) { result.note = 'onboard queue empty'; return result; }
// Spawn the vetted creator (DRAFT, idempotent, cap=CAP new creates). cwd=ROOT for its relative paths.
// Use process.execPath (absolute path of THIS node), not bare `node` — launchd's stripped PATH
// has no Homebrew node, so `node ...` silently ExecSync-failed every 6:35am run (fixed 2026-07-14).
const out = execSync(
`"${process.execPath}" york-new-create.mjs --file=data/onboard-payloads-enriched.json --limit=${CAP} --apply --i-am-steve`,
{ cwd: ROOT, encoding: 'utf8', timeout: 30 * 60 * 1000 }
);
result.ran = true;
// parse the creator's DONE line: "DONE — N DRAFT created, M create-err, K skipped(exists), ..."
const m = out.match(/DONE — (\d+) DRAFT created, (\d+) create-err, (\d+) skipped/);
if (m) { result.created = +m[1]; result.err = +m[2]; result.skipped = +m[3]; }
result.note = m ? `created ${result.created}, skipped(exists) ${result.skipped}, err ${result.err}` : 'ran; could not parse creator output';
// tail of creator output for the log
result.tail = out.trim().split('\n').slice(-4).join(' | ');
} catch (e) {
result.note = 'auto-onboard error (caught, cadence unaffected): ' + String(e.message || e).slice(0, 160);
}
return result;
}
// Standalone run (for testing / manual drip): `node cadence/york-auto-onboard.mjs`
if (import.meta.url === `file://${process.argv[1]}`) {
const r = autoOnboard();
console.log('york-auto-onboard:', JSON.stringify(r, null, 2));
}