Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
import { Router, Request, Response } from 'express';
|
|
import { getStore } from './store.js';
|
|
import { calculateAllResults } from './aggregation.js';
|
|
|
|
// List of connected SSE clients
|
|
const clients: Response[] = [];
|
|
|
|
export const sseRouter = Router();
|
|
|
|
/**
|
|
* SSE endpoint: GET /api/results/stream
|
|
*/
|
|
sseRouter.get('/api/results/stream', (req: Request, res: Response) => {
|
|
// Set SSE headers
|
|
res.setHeader('Content-Type', 'text/event-stream');
|
|
res.setHeader('Cache-Control', 'no-cache');
|
|
res.setHeader('Connection', 'keep-alive');
|
|
|
|
// Add client to list
|
|
clients.push(res);
|
|
|
|
// Send initial data immediately on connect
|
|
const store = getStore();
|
|
const criteriaCount = store.session.config.criteria.length;
|
|
const results = calculateAllResults(store.scores, store.teams, criteriaCount);
|
|
const payload = JSON.stringify({ results, timestamp: new Date().toISOString() });
|
|
res.write(`event: scores_updated\ndata: ${payload}\n\n`);
|
|
|
|
// Remove client on disconnect
|
|
req.on('close', () => {
|
|
const index = clients.indexOf(res);
|
|
if (index !== -1) {
|
|
clients.splice(index, 1);
|
|
}
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Broadcast current results to all connected SSE clients.
|
|
* Called whenever scores change.
|
|
*/
|
|
export function broadcastUpdate(): void {
|
|
const store = getStore();
|
|
const criteriaCount = store.session.config.criteria.length;
|
|
const results = calculateAllResults(store.scores, store.teams, criteriaCount);
|
|
const payload = JSON.stringify({ results, timestamp: new Date().toISOString() });
|
|
const message = `event: scores_updated\ndata: ${payload}\n\n`;
|
|
|
|
for (const client of clients) {
|
|
client.write(message);
|
|
}
|
|
}
|