[object Object]

← back to Wallco Ai

etsyEligible: pass --path to seam scanner (resolve from DESIGNS) instead of --id, so prod (Node-as-root → no PG role) skips the broken psql path-lookup. Falls back to --id when path unresolvable.

153d69025f2d534dc51f91b09e139104d5086ff5 · 2026-05-28 10:21:42 -0700 · Steve Abrams

Files touched

Diff

commit 153d69025f2d534dc51f91b09e139104d5086ff5
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu May 28 10:21:42 2026 -0700

    etsyEligible: pass --path to seam scanner (resolve from DESIGNS) instead of --id, so prod (Node-as-root → no PG role) skips the broken psql path-lookup. Falls back to --id when path unresolvable.
---
 server.js | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/server.js b/server.js
index b6aa817..8290f9e 100644
--- a/server.js
+++ b/server.js
@@ -1201,9 +1201,17 @@ function etsyEligible(id) {
   if (!fs.existsSync(scriptPath)) {
     return { ok: true, verdict: 'SKIPPED', reason: 'scanner not deployed on this host — eligibility not checked', skipped: true };
   }
+  // Prefer `--path` over `--id`: on prod the Node server runs as root, which has
+  // no PG role, so the scanner's psql-based path lookup fails ("role root does
+  // not exist"). Resolve the path from in-memory DESIGNS first.
+  const d = DESIGNS.find(x => x && x.id === id);
+  const filename = d && (d.filename || (d.image_url || '').split('/').pop());
+  const candidate = filename ? path.join(__dirname, 'data', 'generated', filename) : null;
+  const args = (candidate && fs.existsSync(candidate))
+    ? [scriptPath, '--path', candidate]
+    : [scriptPath, '--id', String(id)];
   try {
-    const scanOut = _execFileSyncSeam('python3',
-      [scriptPath, '--id', String(id)],
+    const scanOut = _execFileSyncSeam('python3', args,
       { encoding: 'utf8', timeout: 30000, maxBuffer: 4 * 1024 * 1024 });
     const r = JSON.parse(scanOut);
     if (!r.ok) return { ok: false, reason: r.error || 'scan failed' };
@@ -16159,6 +16167,21 @@ ${(() => {
   })();
   </script>
 
+  <!-- Wall-and-repeat preview — interactive scale viewer ported from the
+       admin drunk-curator. Shows the SKU at 24"/36"/54" repeat on a wall
+       sized via the slider (8' → 20'). Customer-facing; no API cost.
+       Standalone in public/wall-room-viewer.html for clean encapsulation. -->
+  <section id="wall-preview" style="margin:48px auto 0;max-width:1200px;padding:0 24px;">
+    <div style="display:flex;align-items:baseline;gap:16px;border-top:1px solid var(--rule,#e5e5e0);padding-top:24px;margin-bottom:18px;flex-wrap:wrap;">
+      <h2 style="margin:0;font:500 22px/1.2 ui-serif,Georgia,serif;">See it at scale</h2>
+      <span style="font:11px/1.4 ui-sans-serif,system-ui,sans-serif;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint,#6e6e68);">drag the slider — try 24″ / 36″ / 54″ repeats</span>
+    </div>
+    <iframe src="/wall-room-viewer.html?id=${design.id}"
+            style="width:100%;height:780px;border:1px solid var(--rule,#e5e5e0);border-radius:10px;display:block;background:#fafaf7"
+            loading="lazy"
+            title="Wall preview at scale"></iframe>
+  </section>
+
   <!-- Generated Rooms gallery — hydrates from /api/rooms?design_id={{id}} -->
   <section id="rooms-gallery" class="rooms-gallery" data-design-id="${design.id}" style="margin:48px auto 0;max-width:1200px;padding:0 24px;">
     <div class="rg-head" style="display:flex;align-items:baseline;gap:16px;border-top:1px solid var(--rule,#e5e5e0);padding-top:24px;margin-bottom:18px;flex-wrap:wrap;">

← da0674d deploy: ship scripts/seam-defect-boxes.py to prod (used by /  ·  back to Wallco Ai  ·  front-end: bring wall+room viewer to customer-facing /design 557b826 →