// server/routes/machines.ts import { Hono } from "hono"; import { listMachines, createMachine, deleteMachine, updateMachine, getMachineRow, getCreds, testConnection, getMachineHardware, type CreateMachineInput, type UpdateMachineInput, } from "../services/machines.js"; import { refreshMachine, getLatestSnapshot } from "../services/refresh.js"; import { runProbe } from "../services/machineProbe.js"; import { collectMetrics, getLatestMetrics } from "../services/machineMetrics.js"; import { analyzeMachineRepositories } from "../services/aptRepositories.js"; import { listImportantMessages, acknowledgeMessage } from "../services/importantMessages.js"; import { listMachineEvents } from "../services/machineState.js"; export const machinesRoutes = new Hono(); machinesRoutes.get("/", (c) => c.json(listMachines())); machinesRoutes.post("/", async (c) => { const body = (await c.req.json()) as CreateMachineInput; try { const m = await createMachine(body); return c.json(m, 201); } catch (err) { return c.json({ error: `Connexion échouée: ${(err as Error).message}` }, 400); } }); machinesRoutes.post("/:id/test-connection", async (c) => { const m = getMachineRow(c.req.param("id")); if (!m) return c.json({ error: "Machine introuvable" }, 404); try { return c.json(await testConnection(getCreds(m))); } catch (err) { return c.json({ error: (err as Error).message }, 400); } }); machinesRoutes.get("/:id/snapshot", (c) => { const snap = getLatestSnapshot(c.req.param("id")); return snap ? c.json(snap) : c.json({ error: "Aucun snapshot" }, 404); }); machinesRoutes.post("/:id/refresh", async (c) => { try { return c.json(await refreshMachine(c.req.param("id"))); } catch (err) { return c.json({ error: (err as Error).message }, 400); } }); machinesRoutes.patch("/:id", async (c) => { const body = (await c.req.json()) as UpdateMachineInput; try { return c.json(updateMachine(c.req.param("id"), body)); } catch (err) { return c.json({ error: (err as Error).message }, 400); } }); // Dernières métriques stockées (sans SSH). machinesRoutes.get("/:id/metrics", (c) => c.json(getLatestMetrics(c.req.param("id")))); // Collecte fraîche (SSH léger, non destructif). machinesRoutes.post("/:id/metrics/collect", async (c) => { try { return c.json(await collectMetrics(c.req.param("id"))); } catch (err) { return c.json({ error: (err as Error).message }, 400); } }); // Analyse des dépôts APT (lecture seule). machinesRoutes.post("/:id/apt-repositories", async (c) => { try { return c.json(await analyzeMachineRepositories(c.req.param("id"))); } catch (err) { return c.json({ error: (err as Error).message }, 400); } }); // Timeline d'événements machine. machinesRoutes.get("/:id/events", (c) => c.json(listMachineEvents(c.req.param("id")))); // Messages importants (warnings/erreurs/évolutions) extraits des sorties. machinesRoutes.get("/:id/messages", (c) => c.json(listImportantMessages(c.req.param("id")))); machinesRoutes.post("/:id/messages/:msgId/ack", (c) => { acknowledgeMessage(c.req.param("msgId")); return c.json({ ok: true }); }); machinesRoutes.get("/:id/hardware", (c) => { try { return c.json(getMachineHardware(c.req.param("id"))); } catch (err) { return c.json({ error: (err as Error).message }, 404); } }); // Sonde synchrone (lecture seule) : renvoie faits + proposition de correction. machinesRoutes.post("/:id/probe", async (c) => { try { const o = await runProbe(c.req.param("id")); return c.json({ probe: o.probe, proposal: o.proposal, recommendations: o.recommendations, changes: o.changes }); } catch (err) { return c.json({ error: (err as Error).message }, 400); } }); machinesRoutes.delete("/:id", (c) => { deleteMachine(c.req.param("id")); return c.json({ ok: true }); });