const express = require('express'); const queue = require('../queue/queue'); const { renderDashboardPage } = require('./dashboard/page'); function toIsoFromEpochSeconds(epochSeconds) { if (epochSeconds === null || epochSeconds === undefined) return null; const value = Number(epochSeconds); if (!Number.isFinite(value) || value <= 0) return null; return new Date(value * 1000).toISOString(); } function createDashboardRouter(connectors = []) { const router = express.Router(); router.get('/', (req, res) => { res.type('html').send(renderDashboardPage()); }); router.get('/api/summary', async (req, res) => { const [pending, retrying, deadLetters, attempts, avgLatency] = await Promise.all([ queue.pendingCount(), queue.retryingCount(), queue.deadLetterCount(), queue.getDeliveryAttempts(), queue.getAverageLatency() ]); res.json({ status: 'ok', metrics: { pending, retrying, deadLetters, attempts, avgLatency } }); }); router.get('/api/queue', async (req, res) => { const limit = Number(req.query.limit || 20); const rows = await queue.listOutbox({ limit }); res.json({ status: 'ok', items: rows.map((row) => ({ ...row, next_attempt_at_iso: toIsoFromEpochSeconds(row.next_attempt_at) })) }); }); router.get('/api/instruments', async (req, res) => { const items = connectors.map((connector) => { const status = connector.health(); const address = status.comPort || status.port || [status.remoteAddress, status.remotePort].filter(Boolean).join(':') || '-'; return { instrument_id: status.instrument_id || null, connector: connector.type(), status: status.status, address }; }); res.json({ status: 'ok', items }); }); router.get('/api/recent', async (req, res) => { const limit = Number(req.query.limit || 20); const items = await queue.listRecentDeliveryAttempts(limit); res.json({ status: 'ok', items }); }); return router; } module.exports = { createDashboardRouter };