[object Object]

← back to Rentv

5x sweep 2: 20s server-side cache for /api/crm (was rebuilding CRCP fetch + LinkedIn graph + 5k-match on every request → saturated under repeated loads)

f356373e1a0485f318df57bddee51dad7dcb652c · 2026-08-12 19:04:40 -0700 · Steve Abrams

Files touched

Diff

commit f356373e1a0485f318df57bddee51dad7dcb652c
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Aug 12 19:04:40 2026 -0700

    5x sweep 2: 20s server-side cache for /api/crm (was rebuilding CRCP fetch + LinkedIn graph + 5k-match on every request → saturated under repeated loads)
---
 server.js | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/server.js b/server.js
index d2d3075a..23cedf36 100644
--- a/server.js
+++ b/server.js
@@ -2425,8 +2425,18 @@ function loadLinkedInGraph(){
     },
   };
 }
+let _crmCache = { at: 0, key: '', payload: null };  // 20s server-side cache — /api/crm assembly (CRCP fetch + LinkedIn graph + 5k-contact match) is expensive
 app.get('/api/crm', adminOnly, async (req, res) => {
   try {
+    // admin-only green (genuine admin credential, honoring basic-auth even under the OPEN=1 dev bypass)
+    const isAdmin = req.role === 'admin' && (
+      req.authVia === 'basic' || req.authVia === 'session' || req.authVia === 'service' ||
+      (() => { const az = req.headers.authorization || ''; if (az.startsWith('Basic ')) { try { return Buffer.from(az.slice(6), 'base64').toString().split(':')[0] === 'admin'; } catch { return false; } } return false; })()
+    );
+    const _ckey = isAdmin ? 'admin' : 'public';
+    if (_crmCache.payload && _crmCache.key === _ckey && Date.now() - _crmCache.at < 20000) {
+      res.set('Cache-Control', 'private, max-age=20'); return res.json(_crmCache.payload);
+    }
     let subs = [];
     try { subs = fs.readFileSync(SUBS, 'utf8').split('\n').filter(Boolean).map((l) => { try { return JSON.parse(l); } catch { return null; } }).filter(Boolean); } catch { /* none */ }
     // Owned streams (guarded) + the two small desk sets in parallel.
@@ -2440,14 +2450,7 @@ app.get('/api/crm', adminOnly, async (req, res) => {
     const owners = crmNormalizeOwners(readJSON('la-commercial.json', { marquee: [] }));
     const commercial = crmNormalizeCommercial(commercialRows);
     const directory = crmLoadImported();      // manually-imported contacts (scanned lists, business cards, etc.)
-    // LinkedIn green-highlight is ADMIN-ONLY (it reveals Steve's personal network). Require a
-    // GENUINE admin credential — a real basic/session/service admin, OR (under the OPEN=1 dev
-    // bypass, which clobbers authVia to 'open') a request that still carries admin basic-auth.
-    // A plain unauthenticated hit (even when OPEN=1 makes it role=admin) gets NO relationship data.
-    const isAdmin = req.role === 'admin' && (
-      req.authVia === 'basic' || req.authVia === 'session' || req.authVia === 'service' ||
-      (() => { const az = req.headers.authorization || ''; if (az.startsWith('Basic ')) { try { return Buffer.from(az.slice(6), 'base64').toString().split(':')[0] === 'admin'; } catch { return false; } } return false; })()
-    );
+    // isAdmin computed at handler top (drives the admin-only green + cache key)
     const liGraph = isAdmin ? loadLinkedInGraph() : null;
     const all = [...ownedContacts, ...commercial, ...owners, ...directory].map((c) => {
       const lr = (isAdmin && (c.name || c.firm)) ? liGraph.rel(c.name, c.firm) : { any: false, label: null };
@@ -2469,8 +2472,7 @@ app.get('/api/crm', adminOnly, async (req, res) => {
     ];
     const counts = { all: all.length };
     TYPES.forEach((t) => { counts[t.key] = all.filter((c) => c.type === t.key).length; });
-    res.set('Cache-Control', 'private, max-age=60');
-    res.json({
+    const payload = {
       generated_at: new Date().toISOString(),
       types: TYPES,
       counts,
@@ -2481,7 +2483,10 @@ app.get('/api/crm', adminOnly, async (req, res) => {
         { key: 'firms', label: 'CA DRE Firms', emoji: '🏢', endpoint: '/api/firms', note: 'registry — server search' },
       ],
       contacts: all,
-    });
+    };
+    _crmCache = { at: Date.now(), key: _ckey, payload };
+    res.set('Cache-Control', 'private, max-age=20');
+    res.json(payload);
   } catch (e) {
     res.json({ generated_at: new Date().toISOString(), types: [], counts: { all: 0 }, segments: [], registries: [], contacts: [], error: 'crm unavailable' });
   }

← 34e4fb84 5x sweep 1: cap CRM render at 400 rows (was rendering all 5,  ·  back to Rentv  ·  auto-data-snapshot: 2026-08-12T19:06:56 (8 data files) — 5x/ 0204ec82 →