← back to build-pages
api: /api/fleet/all one-shot aggregate (projects + velocity + recent + top skills/agents) + 4 smoke
b6ddd076403021d2f0fc3c0d1ca9199c2a7fbaaf · 2026-05-13 17:43:03 -0700 · SteveStudio2
Files touched
M server.jsM test/smoke.js
Diff
commit b6ddd076403021d2f0fc3c0d1ca9199c2a7fbaaf
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 13 17:43:03 2026 -0700
api: /api/fleet/all one-shot aggregate (projects + velocity + recent + top skills/agents) + 4 smoke
---
server.js | 45 +++++++++++++++++++++++++++++++++++++++++++++
test/smoke.js | 7 +++++++
2 files changed, 52 insertions(+)
diff --git a/server.js b/server.js
index 7d3a03c..2fe46ca 100644
--- a/server.js
+++ b/server.js
@@ -630,6 +630,50 @@ app.get('/p/:slug/c/:hash', async (req, res, next) => {
} catch (e) { next(e); }
});
+// /api/fleet/all — one-shot aggregate for dashboards that don't want to make
+// 5 separate calls. Pulls velocity + top agents + top skills + recent commits
+// in parallel. Each piece is already cache-warm via the per-repo bundle, so
+// this lands in ~5-15ms after the first hit.
+app.get('/api/fleet/all', async (_req, res, next) => {
+ try {
+ const now = Date.now();
+ const dayMs = 24 * 60 * 60 * 1000;
+ let last24 = 0, last7d = 0;
+ const recent = [];
+ const skillTallies = new Map(), agentTallies = new Map();
+ const byProject = [];
+ for (const [slug, p] of Object.entries(PROJECTS)) {
+ const bundle = await getProjectBundle(slug, p).catch(() => null);
+ if (!bundle) continue;
+ let d24 = 0, d7 = 0;
+ for (const c of bundle.commits) {
+ const age = now - new Date(c.dateISO).getTime();
+ if (age < dayMs) d24++;
+ if (age < 7 * dayMs) d7++;
+ }
+ last24 += d24;
+ last7d += d7;
+ byProject.push({ slug, name: p.name, commits: bundle.commits.length, last_24h: d24, last_7d: d7 });
+ for (const c of bundle.commits.slice(0, 10)) {
+ recent.push({ slug, project: p.name, hash: c.shortHash, date: c.dateISO, subject: c.subject });
+ }
+ for (const f of bundle.facets.skills) skillTallies.set(f.name, (skillTallies.get(f.name) || 0) + f.count);
+ for (const f of bundle.facets.agents) agentTallies.set(f.name, (agentTallies.get(f.name) || 0) + f.count);
+ }
+ recent.sort((a, b) => (b.date < a.date ? -1 : b.date > a.date ? 1 : 0));
+ const top = (m) => [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, 15).map(([name, count]) => ({ name, count }));
+ res.setHeader('Cache-Control', 'public, max-age=60, stale-while-revalidate=120');
+ res.json({
+ projects: byProject,
+ velocity: { last_24h: last24, last_7d: last7d },
+ recent: recent.slice(0, 10),
+ top_skills: top(skillTallies),
+ top_agents: top(agentTallies),
+ as_of: new Date().toISOString(),
+ });
+ } catch (e) { next(e); }
+});
+
// /api/fleet/velocity — commit counts in rolling windows across every project.
// Returns total + per-project breakdown for last-24h and last-7d. Useful for
// "is the work continuing?" dashboards. Same cache lifetime as /api/fleet/*.
@@ -908,6 +952,7 @@ app.get('/api', (_req, res) => {
'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',
+ 'GET /api/fleet/all': 'One-shot dashboard aggregate — velocity + recent + top skills/agents + per-project counts',
'GET /p/:slug': 'Project journal HTML page (?q= deep-link supported)',
'GET /p/:slug/c/:hash': 'Commit detail page — full diff + body',
'GET /p/:slug/feed.atom': 'Atom 1.0 feed — up to 50 recent commits, autodiscovered on project page',
diff --git a/test/smoke.js b/test/smoke.js
index 8e4c412..ca8cdfd 100644
--- a/test/smoke.js
+++ b/test/smoke.js
@@ -212,6 +212,13 @@ function check(name, cond, hint = '') {
check(`fleet/${f}: field`, new RegExp(`"${f}":\\[`).test(r.body));
}
+ // 13b4. fleet/all — one-shot aggregate
+ r = await fetch('/api/fleet/all');
+ check('fleet/all: 200', r.status === 200);
+ check('fleet/all: projects', /"projects":\[/.test(r.body));
+ check('fleet/all: velocity', /"velocity":/.test(r.body));
+ check('fleet/all: top_skills', /"top_skills":\[/.test(r.body));
+
// 13b3. fleet/velocity — rolling-window commit counts
r = await fetch('/api/fleet/velocity');
check('fleet/velocity: 200', r.status === 200);
← 982149f p/:slug: per-project velocity (last 24h + last 7d) in meta l
·
back to build-pages
·
ui: prev/next project nav on /p/:slug — wraps at registry en 0c0d61c →