58 lines
2.4 KiB
TypeScript
58 lines
2.4 KiB
TypeScript
import axios from 'axios';
|
|
import { type Pool } from 'pg';
|
|
import { type Proyecto, RepositoryError } from '../domain/common.js';
|
|
|
|
export class MonitorUsecases {
|
|
constructor(private db: Pool) {}
|
|
|
|
async checkAllProjectsHealth(): Promise<void> {
|
|
try {
|
|
const { rows: projects } = await this.db.query<Proyecto>('SELECT * FROM proyectos');
|
|
|
|
const checks = projects.map(async (p) => {
|
|
let status: Proyecto['estado_codigo'] = 'OK';
|
|
try {
|
|
// Solo 200 es válido: cualquier otro código (301, 403, 5xx) indica un problema real del servicio.
|
|
await axios.get(p.url_health, { timeout: 5000, validateStatus: (s) => s === 200 });
|
|
} catch (e) {
|
|
const axiosError = e as { code?: string };
|
|
status = axiosError.code === 'ECONNABORTED' ? 'TIMEOUT' : 'ERROR';
|
|
}
|
|
|
|
return this.db.query(
|
|
'INSERT INTO estados (proyecto_id, estado_codigo, fecha) VALUES ($1, $2, NOW())',
|
|
[p.id, status]
|
|
);
|
|
});
|
|
|
|
// allSettled en lugar de all: un fallo al insertar en BD no debe cancelar el resto de checks.
|
|
await Promise.allSettled(checks);
|
|
} catch (err) {
|
|
throw new RepositoryError('Fallo masivo en el chequeo de salud', { cause: err instanceof Error ? err.message : String(err) });
|
|
}
|
|
}
|
|
|
|
async getDashboardData(): Promise<Proyecto[]> {
|
|
// LEFT JOIN LATERAL nos deja calcular "la última fila de estados" para cada proyecto.
|
|
// Usamos LEFT JOIN para no perder proyectos que todavía no tienen estados registrados.
|
|
const query = `
|
|
SELECT p.id, p.nombre, p.url_health, e.estado_codigo, e.fecha
|
|
FROM proyectos p
|
|
LEFT JOIN LATERAL (
|
|
SELECT estado_codigo, fecha
|
|
FROM estados
|
|
WHERE proyecto_id = p.id
|
|
ORDER BY fecha DESC
|
|
LIMIT 1
|
|
) e ON true
|
|
ORDER BY p.nombre ASC;
|
|
`;
|
|
try {
|
|
const { rows } = await this.db.query<Proyecto>(query);
|
|
return rows;
|
|
} catch (err) {
|
|
throw new RepositoryError('Error al recuperar datos del dashboard', { cause: err instanceof Error ? err.message : String(err) });
|
|
}
|
|
}
|
|
}
|