← back to Wallco Ai
needs-tif admin: count disk truth (findTifOnDisk), not PG tif_path
d6068de1611681a20184a8e142e82cab74b2ab36 · 2026-06-02 09:22:27 -0700 · Steve Abrams
pilot-build-tifs.py writes TIF files without setting all_designs.tif_path, and
the hires route resolves by disk — so 'tif_path IS NULL' over-reported the
backlog by thousands. /api/admin/needs-tif now iterates the in-memory catalog
and counts published designs with no TIF file on disk. by_group + newest-first
items computed in JS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit d6068de1611681a20184a8e142e82cab74b2ab36
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jun 2 09:22:27 2026 -0700
needs-tif admin: count disk truth (findTifOnDisk), not PG tif_path
pilot-build-tifs.py writes TIF files without setting all_designs.tif_path, and
the hires route resolves by disk — so 'tif_path IS NULL' over-reported the
backlog by thousands. /api/admin/needs-tif now iterates the in-memory catalog
and counts published designs with no TIF file on disk. by_group + newest-first
items computed in JS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
server.js | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/server.js b/server.js
index c568dcb..c98585a 100644
--- a/server.js
+++ b/server.js
@@ -1927,18 +1927,30 @@ app.get('/api/admin/needs-tif', requireAdmin, (req, res) => {
const limit = Math.min(2000, Math.max(1, parseInt(req.query.limit, 10) || 500));
const offset = Math.max(0, parseInt(req.query.offset, 10) || 0);
try {
- const total = parseInt(String(psqlQuery(
- "SELECT COUNT(*) FROM all_designs WHERE is_published AND tif_path IS NULL")).trim(), 10) || 0;
- const groups = JSON.parse(String(psqlQuery(
- `SELECT COALESCE(json_agg(json_build_object('grp', grp, 'n', n) ORDER BY n DESC), '[]')
- FROM (SELECT split_part(category, ' · ', 1) AS grp, COUNT(*) AS n
- FROM all_designs WHERE is_published AND tif_path IS NULL GROUP BY 1) t`)) || '[]');
- const items = JSON.parse(String(psqlQuery(
- `SELECT COALESCE(json_agg(row_to_json(t)), '[]') FROM (
- SELECT id, category, created_at, dominant_hex, image_url
- FROM all_designs WHERE is_published AND tif_path IS NULL
- ORDER BY created_at DESC NULLS LAST, id DESC LIMIT ${limit} OFFSET ${offset}) t`)) || '[]');
- res.json({ ok: true, total, limit, offset, by_group: groups, items });
+ // DISK TRUTH (2026-06-02): the old query was `all_designs WHERE tif_path IS
+ // NULL`, but the disk-based builder (pilot-build-tifs.py) writes TIF FILES
+ // without setting the PG tif_path column — and the /designs/hires/:id route
+ // resolves TIFs by DISK (findTifOnDisk), not PG. So the PG query massively
+ // over-reported. A published design "needs a TIF" iff no TIF file is on disk.
+ const pub = DESIGNS.filter(d => d && d.is_published !== false);
+ const missing = pub.filter(d => !findTifOnDisk(d.id));
+ const total = missing.length;
+ const groupMap = new Map();
+ for (const d of missing) {
+ const grp = String(d.category || '?').split(' · ')[0];
+ groupMap.set(grp, (groupMap.get(grp) || 0) + 1);
+ }
+ const by_group = [...groupMap.entries()].map(([grp, n]) => ({ grp, n })).sort((a, b) => b.n - a.n);
+ const sorted = missing.slice().sort((a, b) => {
+ const ca = a.created_at || '', cb = b.created_at || '';
+ if (ca !== cb) return ca < cb ? 1 : -1; // newest first
+ return (b.id || 0) - (a.id || 0);
+ });
+ const items = sorted.slice(offset, offset + limit).map(d => ({
+ id: d.id, category: d.category, created_at: d.created_at || null,
+ dominant_hex: d.dominant_hex, image_url: d.image_url || ('/designs/img/by-id/' + d.id)
+ }));
+ res.json({ ok: true, total, limit, offset, by_group, items });
} catch (e) {
res.status(500).json({ ok: false, error: e.message });
}
← 1044ed0 PDP theme switcher: fix dropdown on bare /design/:id — treat
·
back to Wallco Ai
·
draft_corey_letter.py: env-first George auth (GMAIL_BASIC_AU 546e9b4 →