[object Object]

← back to Wallco Ai

by-color: emit ETag on every response + 304 short-circuit on If-None-Match (pairs with TTL cache to skip JSON wire transfer)

c3467a12b52cdd19aa87ecd8fbe474b6982baf52 · 2026-05-13 06:56:16 -0700 · SteveStudio2

Files touched

Diff

commit c3467a12b52cdd19aa87ecd8fbe474b6982baf52
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date:   Wed May 13 06:56:16 2026 -0700

    by-color: emit ETag on every response + 304 short-circuit on If-None-Match (pairs with TTL cache to skip JSON wire transfer)
---
 server.js | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/server.js b/server.js
index ab2bb7c..7ef1f29 100644
--- a/server.js
+++ b/server.js
@@ -407,10 +407,22 @@ app.get('/api/designs/by-color', (req, res) => {
   if (!target) return res.status(400).json({ ok:false, error:'invalid hex (try ?hex=%23c16d74 or hex=c16d74)' });
   // Cache key sorts exclude so e.g. exclude=72,5 and exclude=5,72 hit the same entry.
   const cacheKey = `v${_byColorCacheVer}|${hex.toLowerCase()}|${n}|${within}|${excludeArr.join(',')}`;
+  // ETag wraps the same key — deterministic given (catalog version, hex, n, within, sorted excludes).
+  // Lets browsers/CDNs skip the JSON body transfer on revalidation; pairs with the in-memory cache
+  // (cache saves recompute, ETag saves the bytes on the wire). Wrapped in double quotes per RFC.
+  const _bcEtag = `"bc-${CATALOG_LAST_MODIFIED.getTime()}-${cacheKey}"`;
+  if (req.headers['if-none-match'] === _bcEtag) {
+    _byColorStats.hits++;
+    res.setHeader('ETag', _bcEtag);
+    res.setHeader('Cache-Control', 'public, max-age=300, must-revalidate');
+    res.setHeader('X-Cache', 'HIT-ETAG');
+    return res.status(304).end();
+  }
   const now = Date.now();
   const hit = _byColorCache.get(cacheKey);
   if (hit && hit.expiresAt > now) {
     _byColorStats.hits++;
+    res.setHeader('ETag', _bcEtag);
     res.setHeader('Cache-Control', 'public, max-age=300, must-revalidate');
     res.setHeader('X-Cache', 'HIT');
     return res.json(hit.body);
@@ -434,6 +446,7 @@ app.get('/api/designs/by-color', (req, res) => {
     if (firstKey !== undefined) { _byColorCache.delete(firstKey); _byColorStats.evictions++; }
   }
   _byColorCache.set(cacheKey, { body, expiresAt: now + _BY_COLOR_TTL_MS });
+  res.setHeader('ETag', _bcEtag);
   res.setHeader('Cache-Control', 'public, max-age=300, must-revalidate');
   res.setHeader('X-Cache', 'MISS');
   res.json(body);

← ae55f6d /brief: add If-None-Match ETag short-circuit (ids+project+cl  ·  back to Wallco Ai  ·  /admin/reload-designs: also bump by-color cache version + cl e884616 →