/** * Stack Observer API Route * GET /api/stack-observer - Get divergence data from observer.db * Provides real-time automation liveness metrics (result_real divergences) * @author Descomplicar® | @link descomplicar.pt | @copyright 2026 */ import { Router } from 'express' import type { Request, Response } from 'express' import * as observerService from '../services/observer.js' const router = Router() /** * Get divergence data * Returns evaluations with result_real != result_nominal (automation failures/liveness violations) */ router.get('/', async (_req: Request, res: Response) => { try { const data = await observerService.getDivergences() res.json(data) } catch (error: unknown) { console.error('Stack Observer API error:', error) const message = error instanceof Error ? error.message : 'Internal server error' res.status(500).json({ error: message }) } }) /** * Get single divergence by ID * Returns full evaluation record with context */ router.get('/:id', async (req: Request, res: Response) => { try { const { id } = req.params if (!id || typeof id !== 'string') { res.status(400).json({ error: 'Invalid divergence ID' }) return } const data = await observerService.getDivergenceById(id) if (!data) { res.status(404).json({ error: 'Divergence not found' }) return } res.json(data) } catch (error: unknown) { console.error('Stack Observer detail error:', error) const message = error instanceof Error ? error.message : 'Internal server error' res.status(500).json({ error: message }) } /** * Get list of automations (from hermes_jobs) * F1b: Colector ingesta jobs do Hermes */ router.get('/automations', async (_req: Request, res: Response) => { try { const data = await observerService.getAutomations() res.json(data) } catch (error: unknown) { console.error('Get automations error:', error) const message = error instanceof Error ? error.message : 'Internal server error' res.status(500).json({ error: message }) } }) /** * Get list of gate events * F1a: Colector ingesta gate_events da fila */ router.get('/gate-events', async (_req: Request, res: Response) => { try { const data = await observerService.getGateEvents() res.json(data) } catch (error: unknown) { console.error('Get gate events error:', error) const message = error instanceof Error ? error.message : 'Internal server error' res.status(500).json({ error: message }) } }) export default router