[object Object]

← back to build-pages

api/recent: ?since= filter (24h|7d|YYYY-MM-DD) + 2 smoke

d96574185574c140944043beb3daf0edb9e65a0b · 2026-05-13 18:30:14 -0700 · SteveStudio2

Files touched

Diff

commit d96574185574c140944043beb3daf0edb9e65a0b
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Wed May 13 18:30:14 2026 -0700

    api/recent: ?since= filter (24h|7d|YYYY-MM-DD) + 2 smoke
---
 server.js     | 29 ++++++++++++++++++++++++-----
 test/smoke.js |  5 ++++-
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/server.js b/server.js
index 2976059..0177fc5 100644
--- a/server.js
+++ b/server.js
@@ -770,14 +770,28 @@ for (const facet of ['agents', 'skills']) {
 // cache so it's free after the first warm.
 app.get('/api/recent', async (req, res, next) => {
   const limit = Math.min(Math.max(parseInt(req.query.limit, 10) || 20, 1), 200);
+  // Optional ?since=YYYY-MM-DD or ?since=1d|7d|24h date filter — anything older
+  // than the cutoff is dropped before the merge. Lets you slice "what shipped
+  // since last Monday" without paginating through everything.
+  let sinceMs = 0;
+  if (typeof req.query.since === 'string' && req.query.since.length) {
+    const s = req.query.since;
+    const rel = s.match(/^(\d+)([dhm])$/);
+    if (rel) {
+      const [, n, u] = rel;
+      const mult = u === 'd' ? 86400000 : u === 'h' ? 3600000 : 60000;
+      sinceMs = Date.now() - parseInt(n, 10) * mult;
+    } else if (/^\d{4}-\d{2}-\d{2}/.test(s)) {
+      sinceMs = new Date(s).getTime();
+    }
+  }
   try {
     const all = [];
     for (const [slug, p] of Object.entries(PROJECTS)) {
       const bundle = await getProjectBundle(slug, p).catch(() => null);
       if (!bundle) continue;
-      // Each project's commits are already date-desc; take the leading slice
-      // up to `limit`. Final merge will sort the union back into date order.
-      for (const c of bundle.commits.slice(0, limit)) {
+      for (const c of bundle.commits.slice(0, limit * 4)) {
+        if (sinceMs && new Date(c.dateISO).getTime() < sinceMs) break;
         all.push({
           slug, project: p.name,
           hash: c.shortHash, date: c.dateISO, subject: c.subject,
@@ -786,7 +800,12 @@ app.get('/api/recent', async (req, res, next) => {
     }
     all.sort((a, b) => (b.date < a.date ? -1 : b.date > a.date ? 1 : 0));
     res.setHeader('Cache-Control', 'public, max-age=30, stale-while-revalidate=60');
-    res.json({ total: all.length, limit, results: all.slice(0, limit) });
+    res.json({
+      total:  all.length,
+      limit,
+      since:  sinceMs ? new Date(sinceMs).toISOString() : null,
+      results: all.slice(0, limit),
+    });
   } catch (e) { next(e); }
 });
 
@@ -988,7 +1007,7 @@ app.get('/api', (_req, res) => {
       'GET /api/projects/:slug/skills':        'Raw skills facet — /skill-name slugs auto-extracted from commit bodies',
       'GET /api/projects/:slug/ideas':         'Raw ideas — commit bodies ≥120 chars (design-rationale + scaffolds)',
       'GET /api/search':                       'Cross-project commit search — ?q=<term>&limit=N, round-robin + by_project breakdown',
-      'GET /api/recent':                       'Most recent N commits across the whole fleet — date-sorted, ?limit=20',
+      'GET /api/recent':                       'Most recent N commits across the whole fleet — date-sorted, ?limit=20&since=<24h|7d|YYYY-MM-DD>',
       'GET /api/fleet/agents':                 'Fleet-wide agent tallies merged across every project',
       'GET /api/fleet/skills':                 'Fleet-wide skill tallies merged across every project',
       'GET /api/fleet/velocity':               'Commits-per-rolling-window across the fleet — last 24h + last 7d, with per-project breakdown',
diff --git a/test/smoke.js b/test/smoke.js
index cfd7b5a..ba3435c 100644
--- a/test/smoke.js
+++ b/test/smoke.js
@@ -203,11 +203,14 @@ function check(name, cond, hint = '') {
   check('404: branded HTML',       /build-pages/.test(r.body));
   check('404: back-link',          /back to all projects/.test(r.body));
 
-  // 13b. /api/recent — fleet-wide recent commits
+  // 13b. /api/recent — fleet-wide recent commits, with ?since= filter
   r = await fetch('/api/recent?limit=5');
   check('recent: 200',             r.status === 200);
   check('recent: results array',   /"results":\[/.test(r.body));
   check('recent: hash field',      /"hash":"[a-f0-9]{4,}/.test(r.body));
+  r = await fetch('/api/recent?since=24h&limit=200');
+  check('recent ?since=24h: 200',  r.status === 200);
+  check('recent ?since=24h: filter', /"since":"[\d-]+T/.test(r.body));
 
   // 13b2. fleet-wide facet endpoints (agents + skills)
   for (const f of ['agents', 'skills']) {

← 552db5e home: color-coded host load badge (green <8, yellow <20, red  ·  back to build-pages  ·  refactor: parseSince() helper — apply ?since= filter to /api 4a5298c →