[object Object]

← back to Wallco Ai

/design/:id 'Sell on Etsy' button — go one-click force-add by default (design-page = deliberate admin intent; gate becomes advisory). Surface scores in success status if seams > 12 so the admin sees the warning without being blocked. Curator bulk actions keep the eligibility gate

f538318ac4daa1b1c14ce26f2cda2bf9683d7f4c · 2026-05-28 10:59:45 -0700 · Steve Abrams

Files touched

Diff

commit f538318ac4daa1b1c14ce26f2cda2bf9683d7f4c
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu May 28 10:59:45 2026 -0700

    /design/:id 'Sell on Etsy' button — go one-click force-add by default (design-page = deliberate admin intent; gate becomes advisory). Surface scores in success status if seams > 12 so the admin sees the warning without being blocked. Curator bulk actions keep the eligibility gate
---
 server.js | 67 +++++++++++++++++++--------------------------------------------
 1 file changed, 20 insertions(+), 47 deletions(-)

diff --git a/server.js b/server.js
index 1fe23e1..e270c44 100644
--- a/server.js
+++ b/server.js
@@ -10804,63 +10804,36 @@ try {
     else setStatus('smart-fix failed: ' + (j.error || j.reason || r.status), 'err');
   });
   onClick('atb-etsy', async function(b){
-    if (!confirm('Queue #' + b.dataset.id + ' in wallco_etsy_bucket (runs a seam scan first — ~30-60s)? Does NOT create a live Etsy listing.')) return;
-    // The eligibility scan takes ~30-60s. Give a heartbeat so the UI doesn't
-    // look frozen. The disabled-overlay above already gates clicks.
-    setStatus('🔍 Running seam scan… (~30-60s)');
+    // From the design page, the admin has DELIBERATELY picked this design to
+    // sell on Etsy. The seam gate is advisory here, not gating — digital
+    // downloads have a lower quality bar than wall printing and we shouldn't
+    // make the admin click twice for an action they already chose. We pass
+    // force:true on the first call; if the eligibility scan reveals issues,
+    // they get surfaced in the success status (transparency) but don't block.
+    // Curator bulk-actions on /admin/cactus-curator KEEP the gate-checking
+    // behavior — different surface, different intent.
+    if (!confirm('Add #' + b.dataset.id + ' to the Etsy bucket? Runs a seam check (~30-60s) but goes through either way. Does NOT create a live Etsy listing yet.')) return;
+    setStatus('🔍 Running seam scan + adding…');
     var heartbeat = 0;
     var pulse = setInterval(function(){ heartbeat++;
-      setStatus('🔍 Running seam scan… ' + heartbeat + 's elapsed'); }, 1000);
+      setStatus('🔍 Running seam scan + adding… ' + heartbeat + 's'); }, 1000);
     var _o = location.protocol + '//' + location.host;
-    async function callBucket(force){
-      return fetch(_o + '/api/etsy-bucket/add', { method:'POST', credentials:'include',
-        headers:{'Content-Type':'application/json'},
-        body: JSON.stringify({ id: parseInt(b.dataset.id, 10), force: !!force }) });
-    }
     try {
-      var r = await callBucket(false);
+      var r = await fetch(_o + '/api/etsy-bucket/add', { method:'POST', credentials:'include',
+        headers:{'Content-Type':'application/json'},
+        body: JSON.stringify({ id: parseInt(b.dataset.id, 10), force: true }) });
       var j = await r.json();
       clearInterval(pulse);
       if (!(r.ok && j.ok)) { setStatus('etsy queue failed: ' + (j.error || r.status), 'err'); return; }
       var first = (j.results && j.results[0]) || {};
-      if (first.ok && first.already_in) {
-        setStatus('already in bucket (' + first.already_in + ')', 'ok'); return;
-      }
-      if (first.ok) {
-        setStatus('✓ queued · ' + first.target_dpi + ' DPI · ' + first.upscale_px + 'px upscale', 'ok'); return;
-      }
-      // Eligibility gate held — show the reason + an amber "Sell anyway" override.
-      // Digital downloads have a lower quality bar than wall printing, so an
-      // imperfect-seam design can still be Etsy-ready when Steve says so.
+      if (first.already_in) { setStatus('already in bucket (' + first.already_in + ')', 'ok'); return; }
+      if (!first.ok) { setStatus('add failed: ' + (first.reason || 'unknown'), 'err'); return; }
       var sc = first.scores || {};
-      var detail = 'Gate held — ' + (first.reason || 'not eligible');
-      if (sc.v_mid != null) detail += ' [v_mid=' + sc.v_mid + ' h_mid=' + sc.h_mid + ' edges=' + sc.edges_max + ']';
-      setStatus(detail, 'err');
-      // Inject a "Sell anyway" button next to the status line if not already there.
-      if (!document.getElementById('atb-etsy-force')) {
-        var btn = document.createElement('button');
-        btn.id = 'atb-etsy-force';
-        btn.type = 'button';
-        btn.textContent = '🛒 Sell anyway →';
-        btn.style.cssText = 'margin-left:8px;padding:4px 10px;border:1px solid #c98a00;border-radius:5px;background:#3b2e08;color:#f0b400;font:600 11px var(--sans);cursor:pointer;letter-spacing:.04em';
-        btn.title = 'Force-add to the Etsy bucket regardless of seam-gate verdict. Digital downloads tolerate imperfect seams better than print.';
-        btn.addEventListener('click', async function(){
-          btn.disabled = true; setStatus('🔍 Force-adding…');
-          try {
-            var r2 = await callBucket(true);
-            var j2 = await r2.json();
-            var first2 = (j2.results && j2.results[0]) || {};
-            if (r2.ok && j2.ok && first2.ok) {
-              setStatus('✓ force-queued · ' + first2.target_dpi + ' DPI · ' + first2.upscale_px + 'px upscale', 'ok');
-              btn.remove();
-            } else {
-              setStatus('force-add failed: ' + (first2.reason || j2.error || r2.status), 'err');
-              btn.disabled = false;
-            }
-          } catch(e){ setStatus('force-add error: ' + e.message, 'err'); btn.disabled = false; }
-        });
-        stat.parentNode.insertBefore(btn, stat.nextSibling);
+      var note = '';
+      if (sc.overall_max != null && sc.overall_max > 12) {
+        note = ' · ⚠ seams (v=' + sc.v_mid + ' h=' + sc.h_mid + ' e=' + sc.edges_max + ')';
       }
+      setStatus('✓ added · ' + first.target_dpi + ' DPI · ' + first.upscale_px + 'px upscale' + note, 'ok');
     } catch(e){ clearInterval(pulse); setStatus('error: ' + e.message, 'err'); }
   });
 })();

← d9d340a /design/:id admin toolbar: 'Sell on Etsy' button — (1) absol  ·  back to Wallco Ai  ·  homepage hero: prefer photoreal room-mockup over flat tile w 46eb294 →