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>
This commit is contained in:
Kpa-clawbotandCopilot committed 2026-03-27 09:31:59 -07:00
1 parent e47b5f85ed
commit a1e17ef171
4 files changed
+12 -1

No files matched your search

+2
View File
@@ -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)
+6
View File
@@ -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) {
+2 -1
View File
@@ -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) => {
+2
View File
@@ -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 ---