← back to build-pages
api: /api/projects/:slug now includes authors[] breakdown
4acf48acbe7dc4c3ecb4d6dd120689f3264dd9ac · 2026-05-13 19:02:39 -0700 · SteveStudio2
Files touched
Diff
commit 4acf48acbe7dc4c3ecb4d6dd120689f3264dd9ac
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 13 19:02:39 2026 -0700
api: /api/projects/:slug now includes authors[] breakdown
---
server.js | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/server.js b/server.js
index 682bdfe..2f944ed 100644
--- a/server.js
+++ b/server.js
@@ -1072,6 +1072,12 @@ app.get('/api/projects/:slug', async (req, res, next) => {
const bundle = await getProjectBundle(req.params.slug, p);
const first = bundle.commits[bundle.commits.length - 1];
const last = bundle.commits[0];
+ // Author breakdown — who landed how many commits on this project.
+ const authorTallies = new Map();
+ for (const c of bundle.commits) authorTallies.set(c.author, (authorTallies.get(c.author) || 0) + 1);
+ const authors = [...authorTallies.entries()]
+ .map(([name, count]) => ({ name, count }))
+ .sort((a, b) => b.count - a.count);
res.setHeader('Cache-Control', 'public, max-age=30, stale-while-revalidate=60');
res.json({
slug: req.params.slug,
@@ -1082,6 +1088,7 @@ app.get('/api/projects/:slug', async (req, res, next) => {
file_count: bundle.files.length,
first_commit: first ? { hash: first.shortHash, date: first.dateISO.slice(0, 10), subject: first.subject } : null,
last_commit: last ? { hash: last.shortHash, date: last.dateISO.slice(0, 10), subject: last.subject } : null,
+ authors,
agents_top: bundle.facets.agents.slice(0, 10),
skills_top: bundle.facets.skills.slice(0, 10),
ideas_count: bundle.facets.ideas.length,
← 66f4335 smoke: X-Response-Time + rendered-in footer assertions on /p
·
back to build-pages
·
api: canonAuthor() collapses 'SteveStudio2'/'Steve Abrams'/e c7c7763 →