← back to Dw Boardroom Governance
src/api/routes/governance.ts
81 lines
import { Router, Request, Response } from 'express';
import { query, execute } from '../../db/db';
import { isRunning, getActiveMeetingId } from '../../engine/meetingEngine';
import { getConnectionCount } from '../../ws/broadcast';
const router = Router();
// GET /api/governance/config — get all governance settings
router.get('/config', async (_req: Request, res: Response) => {
try {
const rows = await query('SELECT key, value FROM gov_config ORDER BY key');
const config: Record<string, any> = {};
rows.forEach((r: any) => { config[r.key] = r.value; });
res.json(config);
} catch (err: any) {
res.status(500).json({ error: err.message });
}
});
// POST /api/governance/config — update config
router.post('/config', async (req: Request, res: Response) => {
try {
const updates = req.body;
for (const [key, value] of Object.entries(updates)) {
await execute(
`INSERT INTO gov_config (key, value, updated_at) VALUES ($1, $2, NOW())
ON CONFLICT (key) DO UPDATE SET value = $2, updated_at = NOW()`,
[key, JSON.stringify(value)]
);
}
const rows = await query('SELECT key, value FROM gov_config ORDER BY key');
const config: Record<string, any> = {};
rows.forEach((r: any) => { config[r.key] = r.value; });
res.json(config);
} catch (err: any) {
res.status(400).json({ error: err.message });
}
});
// GET /api/governance/status — full system status
router.get('/status', async (_req: Request, res: Response) => {
try {
const [decisions, delegations, initiatives, meetings, config] = await Promise.all([
query("SELECT status, COUNT(*)::int as count FROM gov_decision_log GROUP BY status"),
query("SELECT status, COUNT(*)::int as count FROM gov_delegation_contract GROUP BY status"),
query("SELECT status, COUNT(*)::int as count FROM gov_initiative_registry GROUP BY status"),
query("SELECT status, COUNT(*)::int as count FROM gov_meetings GROUP BY status"),
query("SELECT key, value FROM gov_config"),
]);
const toMap = (rows: any[]) => {
const m: Record<string, number> = {};
rows.forEach(r => { m[r.status] = r.count; });
return m;
};
const configMap: Record<string, any> = {};
config.forEach((r: any) => { configMap[r.key] = r.value; });
res.json({
meeting: {
active: isRunning(),
activeMeetingId: getActiveMeetingId(),
},
decisions: toMap(decisions),
delegations: toMap(delegations),
initiatives: toMap(initiatives),
meetings: toMap(meetings),
config: configMap,
websocket: {
connections: getConnectionCount(),
},
uptime: process.uptime(),
});
} catch (err: any) {
res.status(500).json({ error: err.message });
}
});
export default router;