feat(messages): extraction des messages importants APT (tâche 5 backlog)

- extractImportantMessages (TDD) : E:/dpkg error → error, W:/GPG → warning,
  déprecations/EOL → future_major_change ; nettoyage des secrets dans les URLs
- recordImportantMessages : dédup par (machine, source, message) non acquitté →
  maj lastSeenAt, sinon insert (firstSeen/lastSeen) dans important_messages
- branché dans refreshMachine (sortie APT) avec snapshotId
- routes GET /machines/:id/messages + POST .../:msgId/ack
- UI : carte « Messages importants » (badge sévérité + ack) dans le panneau détail

tsc 0 · 118 tests · build OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 19:30:07 +02:00
parent ff9cfaa9e1
commit a93a43e1c8
6 changed files with 208 additions and 0 deletions
+8
View File
@@ -9,6 +9,7 @@ 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";
export const machinesRoutes = new Hono();
@@ -77,6 +78,13 @@ machinesRoutes.post("/:id/apt-repositories", async (c) => {
}
});
// 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")));