[object Object]

← back to Designerwallcoverings

TK-10484: reversible archiver for 15 imageless unminted JStevens drafts (gated, not fired)

e51b1da73e8247ada9bb23467e4c5eeaaab4d9f7 · 2026-09-24 12:46:42 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit e51b1da73e8247ada9bb23467e4c5eeaaab4d9f7
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Sep 24 12:46:42 2026 -0700

    TK-10484: reversible archiver for 15 imageless unminted JStevens drafts (gated, not fired)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 scripts/tk10484-archive-noimage.mjs | 75 +++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/scripts/tk10484-archive-noimage.mjs b/scripts/tk10484-archive-noimage.mjs
new file mode 100644
index 0000000..f76644f
--- /dev/null
+++ b/scripts/tk10484-archive-noimage.mjs
@@ -0,0 +1,75 @@
+#!/usr/bin/env node
+// TK-10484 — archive the 15 imageless, unminted, off-Shopify JStevens draft rows (Steve 2026-09-24).
+// These EXCLUDE/named-5 rows have a dead Shopify CDN url (404) AND no og:image on their product page,
+// AND on_shopify=false / no shopify_product_id -> they don't exist as sellable products. Archive = a
+// staging-only flag on jeffrey_stevens_catalog. No customer-facing / Shopify change. Fully reversible.
+//
+//   node scripts/tk10484-archive-noimage.mjs            # dry-run (no writes)
+//   node scripts/tk10484-archive-noimage.mjs --apply    # add archived_* cols + flag the 15 + refresh viewer
+//   node scripts/tk10484-archive-noimage.mjs --rollback # un-archive the 15 (clears archived_at/reason)
+
+import { execFileSync } from 'node:child_process';
+import { writeFileSync } from 'node:fs';
+import { fileURLToPath } from 'node:url';
+import { dirname, join } from 'node:path';
+
+const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
+const PG = ['-h', '/tmp', '-d', 'dw_unified', '-v', 'ON_ERROR_STOP=1'];
+const mode = process.argv.includes('--apply') ? 'apply'
+           : process.argv.includes('--rollback') ? 'rollback' : 'dry';
+
+const SKUS = [
+  'DWAA-500440-Roll','DWAA-500870-PerRoll','DWAA-500950-Roll','DWAA-500960-Roll','DWAA-500970-Roll',
+  'DWAA-501010-Roll','DWAA-501020-Roll','DWAA-501030-PerRoll','DWAA-501040-Roll','DWAA-501100-Roll',
+  'DWAA-501110-Roll','DWAA-501120-Roll','DWAA-501130-Roll','DWAA-501210-Roll','DWAA-501220-Roll',
+];
+const inList = SKUS.map((s) => `'${s}'`).join(',');
+const psql = (sql) => execFileSync('psql', [...PG, '-c', sql], { encoding: 'utf8' });
+
+console.log(`TK-10484 archive-noimage — mode: ${mode} — ${SKUS.length} skus`);
+
+if (mode === 'dry') {
+  console.log('DRY-RUN. Would: ADD archived_at/archived_reason (IF NOT EXISTS); set them on the 15 rows;');
+  console.log('then rebuild the viewer data.json to exclude archived rows.');
+  console.log('Apply: node scripts/tk10484-archive-noimage.mjs --apply');
+  process.exit(0);
+}
+
+if (mode === 'rollback') {
+  psql(`UPDATE jeffrey_stevens_catalog SET archived_at=NULL, archived_reason=NULL WHERE sku IN (${inList});`);
+  console.log('ROLLBACK done — 15 rows un-archived (columns kept).');
+  process.exit(0);
+}
+
+// apply
+psql(`BEGIN;
+ALTER TABLE jeffrey_stevens_catalog
+  ADD COLUMN IF NOT EXISTS archived_at timestamptz,
+  ADD COLUMN IF NOT EXISTS archived_reason text;
+UPDATE jeffrey_stevens_catalog
+  SET archived_at=now(),
+      archived_reason='no_image_unminted_draft; Steve 2026-09-24 (settlement EXCLUDE, off-Shopify, dead CDN + no og:image)'
+  WHERE sku IN (${inList}) AND archived_at IS NULL;
+COMMIT;`);
+const n = psql(`SELECT count(*) FROM jeffrey_stevens_catalog WHERE archived_at IS NOT NULL AND sku IN (${inList});`).trim().split('\n').find((l) => /^\s*\d+\s*$/.test(l))?.trim();
+console.log(`APPLIED — ${n} rows archived.`);
+
+// rebuild viewer data.json excluding archived (remaining rows all have real images)
+const json = psql(`\\pset format unaligned
+\\pset tuples_only on
+SELECT json_agg(row_to_json(t)) FROM (
+  SELECT sku, dw_sku, COALESCE(NULLIF(name,''),pattern_name) AS title, collection,
+         settlement_status, settlement_flag_reason AS reason, settlement_cody_flag AS cody_flag,
+         on_shopify, image_url, false AS img_placeholder,
+         CASE vendor_code WHEN 'nuwallpaper' THEN 'NuWallpaper' WHEN 'misc_peel_stick' THEN 'Jeffrey Stevens'
+              ELSE COALESCE(NULLIF(vendor_code,''),'Jeffrey Stevens') END AS vendor,
+         to_char(settlement_flagged_at,'Mon DD, YYYY, HH12:MI AM') AS flagged_at,
+         settlement_flagged_at AS flagged_iso
+  FROM jeffrey_stevens_catalog
+  WHERE settlement_status IS NOT NULL AND archived_at IS NULL
+  ORDER BY CASE settlement_status WHEN 'EXCLUDE' THEN 0 WHEN 'REVIEW' THEN 1 ELSE 2 END, reason, title
+) t;`).trim();
+writeFileSync(join(ROOT, 'tmp/settlement-viewer/data.json'), json);
+const rows = JSON.parse(json);
+console.log(`Viewer data.json rebuilt: ${rows.length} rows (archived excluded), all have image: ${rows.every((r) => r.image_url)}`);
+console.log('Undo: node scripts/tk10484-archive-noimage.mjs --rollback');

← 4faa847 auto-data-snapshot: 2026-09-24T12:18:37 (2 data files) — $OU  ·  back to Designerwallcoverings  ·  TK-10484: archived 15 imageless unminted drafts; fix viewer- 5481337 →