From a1e17ef171e8b1da6fd0befc507089f69c3e8fc5 Mon Sep 17 00:00:00 2001 From: Kpa-clawbot <259247574+Kpa-clawbot@users.noreply.github.com> Date: Fri, 27 Mar 2026 09:31:59 -0700 Subject: [PATCH] feat: add engine identifier to /api/stats and /api/health Both backends now return an 'engine' field ('node' or 'go') in /api/stats and /api/health responses so the frontend can display which backend is running. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- cmd/server/routes.go | 2 ++ cmd/server/routes_test.go | 6 ++++++ server.js | 3 ++- test-server-routes.js | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cmd/server/routes.go b/cmd/server/routes.go index 72036cb8..d537f9b2 100644 --- a/cmd/server/routes.go +++ b/cmd/server/routes.go @@ -264,6 +264,7 @@ func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) { writeJSON(w, map[string]interface{}{ "status": "ok", + "engine": "go", "uptime": int(uptime), "uptimeHuman": fmt.Sprintf("%dh %dm", int(uptime)/3600, (int(uptime)%3600)/60), "memory": map[string]interface{}{ @@ -314,6 +315,7 @@ func (s *Server) handleStats(w http.ResponseWriter, r *http.Request) { "totalNodesAllTime": stats.TotalNodesAllTime, "totalObservers": stats.TotalObservers, "packetsLastHour": stats.PacketsLastHour, + "engine": "go", "counts": counts, } writeJSON(w, result) diff --git a/cmd/server/routes_test.go b/cmd/server/routes_test.go index fa9aed35..e4f8b05e 100644 --- a/cmd/server/routes_test.go +++ b/cmd/server/routes_test.go @@ -35,6 +35,9 @@ func TestHealthEndpoint(t *testing.T) { if body["status"] != "ok" { t.Errorf("expected status ok, got %v", body["status"]) } + if body["engine"] != "go" { + t.Errorf("expected engine go, got %v", body["engine"]) + } } func TestStatsEndpoint(t *testing.T) { @@ -54,6 +57,9 @@ func TestStatsEndpoint(t *testing.T) { if body["totalNodes"] != float64(3) { t.Errorf("expected 3 nodes, got %v", body["totalNodes"]) } + if body["engine"] != "go" { + t.Errorf("expected engine go, got %v", body["engine"]) + } } func TestPacketsEndpoint(t *testing.T) { diff --git a/server.js b/server.js index a0b591fc..04a7f4ea 100644 --- a/server.js +++ b/server.js @@ -471,6 +471,7 @@ app.get('/api/health', (req, res) => { res.json({ status: 'ok', + engine: 'node', uptime: Math.round(uptime), uptimeHuman: `${Math.floor(uptime / 3600)}h ${Math.floor((uptime % 3600) / 60)}m`, memory: { @@ -885,7 +886,7 @@ app.get('/api/stats', (req, res) => { const r = db.db.prepare(`SELECT COUNT(*) as count FROM nodes WHERE role = ? AND last_seen > ?`).get(role, sevenDaysAgo); counts[role + 's'] = r.count; } - res.json({ ...stats, counts }); + res.json({ ...stats, engine: 'node', counts }); }); app.get('/api/packets', (req, res) => { diff --git a/test-server-routes.js b/test-server-routes.js index c1e9c2e8..c2ae9a66 100644 --- a/test-server-routes.js +++ b/test-server-routes.js @@ -171,12 +171,14 @@ seedTestData(); await t('GET /api/health', async () => { const r = await request(app).get('/api/health').expect(200); assert(r.body.status, 'should have status'); + assert(r.body.engine === 'node', 'health should include engine=node'); }); // --- Stats --- await t('GET /api/stats', async () => { const r = await request(app).get('/api/stats').expect(200); assert(typeof r.body === 'object', 'should return stats'); + assert(r.body.engine === 'node', 'stats should include engine=node'); }); // --- Perf ---