← back to Wallco Ai
/admin/health: extended JSON w/ by-color cache stats (hits/misses/evictions/hit_rate) + uptime + rss
01a41fa031ef33615773b917ab60f02b0d893468 · 2026-05-12 19:53:03 -0700 · SteveStudio2
Files touched
Diff
commit 01a41fa031ef33615773b917ab60f02b0d893468
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date: Tue May 12 19:53:03 2026 -0700
/admin/health: extended JSON w/ by-color cache stats (hits/misses/evictions/hit_rate) + uptime + rss
---
server.js | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/server.js b/server.js
index 5a7f882..f249181 100644
--- a/server.js
+++ b/server.js
@@ -394,6 +394,7 @@ const _BY_COLOR_TTL_MS = 300_000;
const _BY_COLOR_MAX = 1000;
const _byColorCache = new Map(); // key -> { body, expiresAt }
let _byColorCacheVer = 0; // bump to invalidate
+const _byColorStats = { hits: 0, misses: 0, evictions: 0, since: Date.now() };
app.get('/api/designs/by-color', (req, res) => {
const hex = String(req.query.hex || '').trim();
const n = Math.max(1, Math.min(50, parseInt(req.query.n || '12', 10)));
@@ -409,11 +410,13 @@ app.get('/api/designs/by-color', (req, res) => {
const now = Date.now();
const hit = _byColorCache.get(cacheKey);
if (hit && hit.expiresAt > now) {
+ _byColorStats.hits++;
res.setHeader('Cache-Control', 'public, max-age=300, must-revalidate');
res.setHeader('X-Cache', 'HIT');
return res.json(hit.body);
}
if (hit) _byColorCache.delete(cacheKey); // expired — drop before recompute
+ _byColorStats.misses++;
const ranked = [];
for (const d of DESIGNS) {
if (exclude.has(d.id)) continue;
@@ -428,7 +431,7 @@ app.get('/api/designs/by-color', (req, res) => {
// FIFO evict if full. Map preserves insertion order, so the first key is the oldest.
if (_byColorCache.size >= _BY_COLOR_MAX) {
const firstKey = _byColorCache.keys().next().value;
- if (firstKey !== undefined) _byColorCache.delete(firstKey);
+ if (firstKey !== undefined) { _byColorCache.delete(firstKey); _byColorStats.evictions++; }
}
_byColorCache.set(cacheKey, { body, expiresAt: now + _BY_COLOR_TTL_MS });
res.setHeader('Cache-Control', 'public, max-age=300, must-revalidate');
@@ -10117,6 +10120,34 @@ app.get('/health', (_req, res) => {
res.json({ ok: true, site: SITE, count: DESIGNS.length, port: PORT });
});
+// ── /admin/health — admin-gated extended health + by-color cache stats. Useful to
+// confirm the in-process ΔE cache is actually serving HITs and that eviction is bounded.
+// 404 (not 401/403) on non-admin so we don't leak the endpoint's existence.
+app.get('/admin/health', (req, res) => {
+ if (!isAdmin(req)) return res.status(404).type('html').send('<h1>404</h1>');
+ const total = _byColorStats.hits + _byColorStats.misses;
+ res.setHeader('Cache-Control', 'no-store');
+ res.json({
+ ok: true,
+ site: SITE,
+ port: PORT,
+ designs: DESIGNS.length,
+ uptime_s: Math.round(process.uptime()),
+ rss_mb: Math.round(process.memoryUsage().rss / 1048576),
+ by_color_cache: {
+ size: _byColorCache.size,
+ max: _BY_COLOR_MAX,
+ ttl_ms: _BY_COLOR_TTL_MS,
+ ver: _byColorCacheVer,
+ hits: _byColorStats.hits,
+ misses: _byColorStats.misses,
+ evictions: _byColorStats.evictions,
+ hit_rate: total > 0 ? Math.round((_byColorStats.hits / total) * 1000) / 10 : null,
+ since: new Date(_byColorStats.since).toISOString(),
+ },
+ });
+});
+
// ── DEV LOGIN — sets dw_auth HS256 cookie for admin layer + inline editor (dev mode only)
const __crypto = require('crypto');
function __b64u(s) { return Buffer.from(s).toString('base64').replace(/=+$/,'').replace(/\+/g,'-').replace(/\//g,'_'); }
← 1370963 drunk-animals: /drunk-animals friendly URL → 302 to /designs
·
back to Wallco Ai
·
/api/designs/random: ETag + 304 on seeded calls (determinist 4f0ff5e →