[object Object]

← back to Wallco Ai

cactus-curator: 📦 TIF badge on every card (green when archive present + tif dims/MB on hover, amber 'NO TIF' otherwise); server cactus/list returns tif_path/tif_w_px/tif_h_px/tif_bytes

1f7752023caecb094494ab4825d142b44cc747cf · 2026-05-28 09:40:14 -0700 · Steve Abrams

Files touched

Diff

commit 1f7752023caecb094494ab4825d142b44cc747cf
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu May 28 09:40:14 2026 -0700

    cactus-curator: 📦 TIF badge on every card (green when archive present + tif dims/MB on hover, amber 'NO TIF' otherwise); server cactus/list returns tif_path/tif_w_px/tif_h_px/tif_bytes
---
 data/cactus-decisions.jsonl      | 34 ++++++++++++++++++++++++++++++++++
 public/admin/cactus-curator.html |  4 ++++
 server.js                        |  5 +++++
 3 files changed, 43 insertions(+)

diff --git a/data/cactus-decisions.jsonl b/data/cactus-decisions.jsonl
index c6faa03..09964f3 100644
--- a/data/cactus-decisions.jsonl
+++ b/data/cactus-decisions.jsonl
@@ -3842,3 +3842,37 @@
 {"ts":"2026-05-28T16:28:21.490Z","id":53861,"action":"live"}
 {"ts":"2026-05-28T16:28:22.283Z","id":53824,"action":"live"}
 {"ts":"2026-05-28T16:28:23.095Z","id":53857,"action":"live"}
+{"ts":"2026-05-28T16:37:45.352Z","id":37320,"action":"bad"}
+{"ts":"2026-05-28T16:37:53.396Z","id":37336,"action":"bad"}
+{"ts":"2026-05-28T16:37:55.586Z","id":36901,"action":"bad"}
+{"ts":"2026-05-28T16:37:57.443Z","id":35121,"action":"bad"}
+{"ts":"2026-05-28T16:37:58.550Z","id":36093,"action":"bad"}
+{"ts":"2026-05-28T16:38:01.665Z","id":36102,"action":"bad"}
+{"ts":"2026-05-28T16:38:04.318Z","id":36140,"action":"bad"}
+{"ts":"2026-05-28T16:38:06.083Z","id":36421,"action":"bad"}
+{"ts":"2026-05-28T16:38:23.245Z","id":20150,"action":"bad"}
+{"ts":"2026-05-28T16:38:25.664Z","id":19854,"action":"bad"}
+{"ts":"2026-05-28T16:38:36.421Z","id":20251,"action":"bad"}
+{"ts":"2026-05-28T16:38:40.672Z","id":20503,"action":"bad"}
+{"ts":"2026-05-28T16:38:59.106Z","id":22049,"action":"bad"}
+{"ts":"2026-05-28T16:39:00.056Z","id":21834,"action":"bad"}
+{"ts":"2026-05-28T16:39:01.148Z","id":21342,"action":"bad"}
+{"ts":"2026-05-28T16:39:02.685Z","id":22306,"action":"bad"}
+{"ts":"2026-05-28T16:39:09.906Z","id":22970,"action":"bad"}
+{"ts":"2026-05-28T16:39:32.472Z","id":35071,"action":"bad"}
+{"ts":"2026-05-28T16:39:34.274Z","id":34395,"action":"bad"}
+{"ts":"2026-05-28T16:39:35.352Z","id":34264,"action":"bad"}
+{"ts":"2026-05-28T16:39:36.552Z","id":33596,"action":"bad"}
+{"ts":"2026-05-28T16:39:39.675Z","id":30722,"action":"bad"}
+{"ts":"2026-05-28T16:39:41.354Z","id":31988,"action":"bad"}
+{"ts":"2026-05-28T16:39:42.359Z","id":32092,"action":"bad"}
+{"ts":"2026-05-28T16:39:44.820Z","id":33093,"action":"bad"}
+{"ts":"2026-05-28T16:39:46.564Z","id":33368,"action":"bad"}
+{"ts":"2026-05-28T16:39:49.389Z","id":28879,"action":"bad"}
+{"ts":"2026-05-28T16:39:50.618Z","id":30058,"action":"bad"}
+{"ts":"2026-05-28T16:39:53.140Z","id":28629,"action":"bad"}
+{"ts":"2026-05-28T16:39:56.840Z","id":27482,"action":"bad"}
+{"ts":"2026-05-28T16:39:58.719Z","id":27567,"action":"bad"}
+{"ts":"2026-05-28T16:39:59.805Z","id":27685,"action":"bad"}
+{"ts":"2026-05-28T16:40:00.979Z","id":27916,"action":"bad"}
+{"ts":"2026-05-28T16:40:10.233Z","id":24888,"action":"bad"}
diff --git a/public/admin/cactus-curator.html b/public/admin/cactus-curator.html
index 6751681..d2041a2 100644
--- a/public/admin/cactus-curator.html
+++ b/public/admin/cactus-curator.html
@@ -37,6 +37,7 @@
   .b.rank { background:rgba(123,201,111,.92); color:#0e0f10; }
   .b.pub { background:#2e7d32; } .b.unpub { background:#5a5f63; }
   .b.fix { background:#c98a00; } .b.dig { background:#7a5bd6; } .b.web { background:#1565c0; }
+  .b.tif { background:#2a6b35; color:#dff5e0; } .b.notif { background:#5a4030; color:#ffd0a8; opacity:.75; }
   .b.pass { background:#2e7d32; } .b.warn { background:#b07a00; } .b.fail { background:#a13030; } .b.none{background:#555;}
   .b.reason { background:#e11d2a; color:#fff; font-weight:800; letter-spacing:.02em; box-shadow:0 1px 4px rgba(0,0,0,.4); }
   .state { position:absolute; bottom:0; left:0; right:0; padding:18px 6px 5px; font-size:11px; font-weight:700; text-align:center;
@@ -324,6 +325,9 @@ function card(d){
         <span class="b rank">${rank!=null? '#'+Math.round(rank) : '—'}</span>
         <span class="b ${d.is_published?'pub':'unpub'}">${d.is_published?'PUB':'unpub'}</span>
         ${d.web_viewer?'<span class="b web">WEB</span>':''}
+        ${d.tif_path
+          ? `<span class="b tif" title="TIF archive: ${d.tif_w_px||'?'}×${d.tif_h_px||'?'}px · ${d.tif_bytes?(d.tif_bytes/1024/1024).toFixed(2)+' MB':'?'} · ${(d.tif_path||'').replace(/^.*\\//,'')}">📦 TIF ${d.tif_w_px||''}</span>`
+          : `<span class="b notif" title="no TIF archive — generate via /admin/etsy-bucket or scripts/archive-svg-5400.js">📦 NO TIF</span>`}
         <span class="b ${verdictClass(d.seam_verdict)}">${d.seam_verdict||'no scan'}</span>
         ${failReason(d).map(r=>`<span class="b reason" title="failed: ${r}">${r}</span>`).join('')}
       </div>
diff --git a/server.js b/server.js
index 09d8bf5..600d248 100644
--- a/server.js
+++ b/server.js
@@ -1718,6 +1718,11 @@ app.get('/api/admin/cactus/list', (req, res) => {
                "d.created_at, " +
                "r.seam_score, r.seam_verdict, r.seam_hmid_raw, r.seam_vmid_raw, r.vision_score, " +
                "be.boxes AS annotations, be.defect_tags AS defect_tags, " +
+               // TIF archive metadata — drives the 📦 badge on each card so the
+               // curator sees at a glance which designs have a full-size print
+               // master ready vs none yet (Steve standing rule: every published
+               // design must have a 150-DPI TIF archive).
+               "d.tif_path, d.tif_w_px, d.tif_h_px, d.tif_bytes, " +
                "CASE " +
                  "WHEN r.vision_score IS NOT NULL AND r.seam_score IS NOT NULL " +
                    "THEN round(0.6*r.vision_score + 0.4*r.seam_score, 1) " +

← 63a6271 refresh_designs_snapshot: include tags[] column so the curat  ·  back to Wallco Ai  ·  trade-login: wire PureLyMail SMTP (smtp.purelymail.com:465 S 54a2c78 →