Cartographie complète (liste_taches/coherence_taches), briefs tacheN + gates validation_tacheN, design tâche 2 (docs/design/tache2/), specs/plans jalon 1-2 et tâche 1.9/2 (Phase 1, Phase 2, SJ-0→3). Validations consignées (1.9 ✅, 2-8 🟡). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
14 KiB
Consigne de dev — Backend, historique JSON et automatisations
Type : mission d'investigation + design backend (PAS d'implémentation). Langue : français. Livrable final attendu : spec backend prête à passer en plan d'implémentation.
0. Contexte
La webapp system_update exécute des scripts SSH agentless sur des machines Linux et reçoit des sorties normalisées en JSON canonique :
- snapshots APT ;
- résultats d'exécution APT ;
- snapshots Docker ;
- résultats Docker ;
- profils post-install ;
- rapports ;
- erreurs structurées ;
- état reboot/reconnexion.
Cette tâche vise le backend : sauvegarde, historisation, automatisations planifiées, icônes/statuts machine, conservation et API interne.
À lire avant de travailler :
CLAUDE.mdtache1.9.mdtache2.mdtache3.mdtache4.mdvalidation_tache2.mdshared/types.tsserver/db/schema.tsserver/services/refresh.tsserver/services/execute.tsserver/jobs/worker.tsserver/ws/outputHub.ts
1. Objectif
Concevoir le backend qui stocke et exploite tous les échanges JSON entre machine et webapp.
Le backend doit permettre :
- historiser chaque interrogation/action machine ;
- relier snapshot, exécution, log brut et rapport Markdown ;
- afficher l'état actuel des icônes/statuts par machine ;
- planifier des tâches automatiques, par exemple
update/analysede toutes les machines à heure précise ; - déclencher les refresh Docker/APT/post-install selon un planning ;
- gérer erreurs, retries, verrouillage et idempotence ;
- exposer une API stable pour l'UI, Hermes/MCP et les rapports.
2. Données à sauvegarder
Chaque échange machine ↔ webapp doit être sauvegardé sous forme structurée.
Snapshots
machine_snapshotmachine_probe_snapshotmachine_metrics_snapshotapt_update_analyze_snapshotdocker_scan_snapshotdocker_pull_check_snapshotpost_install_manifest_snapshotreboot_check_snapshot
Champs communs :
{
"id": "snap_x",
"machineId": "machine_x",
"kind": "apt_update_analyze",
"createdAt": "ISO",
"status": "ok",
"payload": {},
"importantLines": [],
"rawLogRef": "reports/machine_x/snap_x.log"
}
Exécutions
apt_upgradeapt_full_upgradeapt_autoremoveapt_cleandocker_applydocker_prunepost_install_profilereboot_verified
Champs communs :
{
"executionId": "exec_x",
"machineId": "machine_x",
"action": "apt_upgrade",
"mode": "manual",
"startedAt": "ISO",
"finishedAt": "ISO",
"status": "ok",
"payload": {},
"rawLogRef": "reports/machine_x/exec_x.log",
"reportRef": "reports/machine_x/exec_x.md"
}
Logs, rapports et messages importants
Les logs bruts et rapports doivent être accessibles à Hermes, mais par références contrôlées :
- le JSON canonique complet reste en BDD ;
- le log brut complet reste dans
reports/<machineId>/...logou dans un stockage d'artefacts ; - le rapport Markdown reste dans
reports/<machineId>/...md; - la BDD garde
rawLogRef,reportRef, taille, checksum, dates, statut de rétention ; - Hermes reçoit par défaut un résumé réduit + des références, pas le log complet.
Le backend doit extraire et stocker les messages importants rencontrés dans les sorties APT/Docker/scripts :
- erreurs bloquantes :
E:,dpkg: error, lock APT, maintainer script en échec ; - warnings opérationnels :
W:, dépôt obsolète, signature, clé GPG, service non redémarré ; - messages d'évolution future : annonce de changement majeur Debian/Ubuntu, sécurité paquet, dépréciation de dépôt, changement de politique de paquet ;
- messages demandant analyse agent : évolution sécurité, migration de version majeure, configuration legacy, composant bientôt non supporté.
Ces messages doivent être stockés comme objets structurés, pas seulement comme lignes de log :
{
"messageId": "msg_x",
"machineId": "machine_x",
"source": "apt",
"category": "future_major_change",
"severity": "warning",
"packageName": "openssh-server",
"message": "résumé nettoyé sans secret",
"rawLineRef": "artifact_x#line_381",
"snapshotId": "snap_x",
"executionId": null,
"createdAt": "ISO",
"acknowledged": false
}
Objectif :
- afficher ces warnings dans la tuile machine ;
- permettre à Hermes de rechercher les évolutions importantes sans relire tous les logs ;
- garder une trace d'un warning même si le prochain
apt updatene l'affiche plus ; - générer des rapports de veille, par exemple "risques Debian à traiter avant la prochaine version majeure".
Événements machine
Prévoir une table ou collection d'événements :
- machine ajoutée ;
- connexion testée ;
- snapshot créé ;
- update disponible ;
- action lancée ;
- action terminée ;
- erreur ;
- reboot demandé ;
- machine revenue ;
- rapport créé ;
- notification envoyée.
Ces événements alimentent :
- timeline machine ;
- audit ;
- Hermes ;
- notifications ;
- rapports globaux.
3. État courant machine
Le backend doit dériver un état courant par machine à partir des derniers snapshots/exécutions.
État machine minimal :
{
"machineId": "machine_x",
"status": "ok",
"apt": {
"status": "updates_available",
"updatesCount": 4,
"lastAnalyzeAt": "ISO",
"rebootRequired": false
},
"docker": {
"status": "updates_available",
"installed": true,
"stacksCount": 3,
"updatesCount": 1,
"lastScanAt": "ISO",
"pruneAvailable": true
},
"postInstall": {
"availableProfiles": 12,
"pendingProfiles": 0,
"lastRunAt": "ISO"
},
"profile": {
"osFamily": "debian",
"osVersion": "13",
"osCodename": "trixie",
"arch": "amd64",
"machineKind": "vm",
"virtualization": "qemu",
"hardwareProfile": "generic_vm"
},
"metrics": {
"lastCollectedAt": "ISO",
"cpuLoad1": 0.08,
"memoryUsedPercent": 26,
"rootUsedPercent": 29,
"diskWarnings": 0
},
"lastError": null
}
Cet état sert à mettre à jour les icônes dans les tuiles machine :
- LED machine ;
- badge APT update ;
- badge Docker update ;
- reboot requis ;
- erreur ;
- action running ;
- prune disponible ;
- warning matériel/driver/repo ;
- alerte disque/RAM simple.
4. Automatisations backend
Besoin prioritaire
Planifier automatiquement :
apt_update_analyzede toutes les machines à heure précise ;machine_metrics_simplepériodique sur toutes les machines ou les machines sélectionnées ;- éventuellement Docker scan/pull-check selon configuration ;
- mise à jour des icônes si des updates sont disponibles ;
- notification ou rapport si anomalies.
Exemple :
{
"id": "schedule_daily_update_analyze",
"name": "Analyse quotidienne",
"enabled": true,
"schedule": "0 6 * * *",
"timezone": "Europe/Paris",
"scope": {
"machineIds": "all",
"tags": []
},
"actions": [
"apt_update_analyze",
"machine_metrics_simple",
"docker_scan"
],
"concurrency": 2,
"notifyOn": ["updates_available", "error"]
}
Moteur de planification
MVP recommandé :
cronerdéjà présent dans le projet ;- jobs in-process ;
- persistance des schedules en DB ;
- verrou machine pour éviter deux actions simultanées sur la même machine.
Alternative future :
- PostgreSQL +
pg-bosssi besoin de jobs distribués, reprise robuste, retries persistants.
Le design doit trancher MVP / futur.
5. Verrouillage et idempotence
Règles :
- une machine ne peut exécuter qu'une action à risque à la fois ;
- un refresh APT ne doit pas courir pendant un upgrade ;
- Docker scan peut être autorisé si aucune action Docker destructive n'est en cours ;
- post-install réseau bloque toute autre action machine ;
- reboot bloque tout jusqu'à reconnexion ou timeout.
Prévoir :
- table
machine_locksou statut job courant ; idempotencyKeypour éviter les doubles clics ;- retries contrôlés ;
- timeout global ;
- timeout d'inactivité ;
- reprise après redémarrage serveur selon le moteur choisi.
6. API backend attendue
À spécifier :
GET /api/capabilities
GET /api/system/status
GET /api/system/metrics
GET /api/machines
GET /api/machines/:id/state
GET /api/machines/:id/hardware
GET /api/machines/:id/metrics
GET /api/machines/:id/snapshots
GET /api/machines/:id/snapshots/:snapshotId
GET /api/machines/:id/executions
GET /api/machines/:id/executions/:executionId
GET /api/machines/:id/events
GET /api/machines/:id/messages
POST /api/machines/:id/actions
GET /api/artifacts/:artifactId
GET /api/artifacts/:artifactId/important-lines
GET /api/reports
GET /api/reports/:id
GET /api/messages
GET /api/schedules
POST /api/schedules
PATCH /api/schedules/:id
POST /api/schedules/:id/run-now
POST /api/schedules/:id/pause
POST /api/schedules/:id/resume
DELETE /api/schedules/:id
GET /api/settings
PATCH /api/settings
GET /api/events
WS /api/ws/machines/:id/output
GET /api/search
Clients visés :
- frontend web ;
- Hermes/MCP via backend ;
- future app locale Rust/GNOME ;
- scripts d'administration internes éventuels.
Chaque endpoint doit garantir :
- aucun secret ;
- JSON stable ;
- erreurs structurées ;
- pagination sur historiques longs ;
- filtres par machine, action, statut, dates.
- versionnement API.
Authentification clients API
Prévoir pour la future app locale :
- tokens de clients distincts des credentials machines ;
- scopes :
read,operate,admin,debug_logs; - révocation ;
- rotation ;
- audit des appels ;
- stockage local côté app via trousseau système, jamais dans le navigateur.
Exemple capabilities :
{
"apiVersion": "1",
"features": {
"machines": true,
"actions": true,
"terminalOutput": true,
"interactiveSsh": false,
"hermes": true,
"settings": true
}
}
7. Rapports et rétention
Prévoir une politique :
- log brut complet conservé sous
reports/; - JSON canonique conservé en DB ;
- rapport Markdown lié à l'exécution ;
- rétention configurable ;
- purge manuelle ;
- export global.
Les logs bruts ne sont jamais envoyés à Hermes sans réduction déterministe.
Règles spécifiques Hermes :
- Hermes peut lire les rapports Markdown et les JSON réduits via API/MCP ;
- Hermes peut demander des extraits ciblés de log par
artifactId, plage de lignes ou recherche ; - accès log complet uniquement si l'utilisateur le demande explicitement ou si le rapport d'erreur l'exige ;
- toute sortie est masquée côté backend avant exposition ;
- chaque lecture Hermes est auditée.
Nettoyage :
- purge automatique des vieux logs selon paramètres ;
- conservation plus longue des logs d'échec et warnings non acquittés ;
- conservation des rapports épinglés ;
- dry-run obligatoire pour purge manuelle ;
- export possible avant suppression ;
- suppression en BDD et fichiers cohérente, avec vérification des chemins.
8. Notifications et intégration Hermes
Le backend doit pouvoir notifier :
- UI via WebSocket/SSE ;
- Hermes via webhook ou MCP selon tâche 6 ;
- messagerie via Hermes gateway si configuré.
Exemples :
- "3 machines ont des updates APT disponibles" ;
- "Docker prune possible sur vm_mqtt" ;
- "Upgrade terminé avec erreur dpkg" ;
- "Machine revenue après reboot en 74s".
Les notifications doivent contenir uniquement JSON réduit et références de rapport.
9. Livrables attendus
À produire sous docs/ :
- Schéma de données backend.
- Modèle d'événements machine.
- Modèle d'état courant machine.
- Spécification des schedules automatisés.
- Règles de verrouillage/idempotence.
- API backend.
- Modèle des messages importants extraits des logs.
- Modèle snapshots hardware/profil machine/métriques simples.
- Politique de rétention/logs/rapports/messages.
- Intégration avec UI et Hermes.
- Découpage en sous-jalons.
10. Définition de terminé
- Tous les JSON machine ↔ webapp sont historisables.
- L'état courant des tuiles peut être dérivé sans parser les logs.
- Les tâches automatiques sont spécifiées.
- Les métriques simples et le profil OS/type machine sont historisables.
- Les actions concurrentes sont sécurisées.
- Les rapports et logs ont une politique claire.
- Les warnings importants, dépréciations et annonces d'évolution future sont historisés et consultables.
- Aucun secret ne sort du backend.
- Aucun code de production n'est livré pendant cette mission de design.
11. Technos à utiliser — checklist
- Node.js runtime.
- Hono pour API HTTP.
- Drizzle ORM + SQLite.
- WebSocket ou SSE pour events/live output.
cronerpour schedules MVP.- Worker in-process au MVP.
- Verrous machine persistants.
- JSON canonique versionné.
- Stockage fichiers pour reports/logs/artifacts.
- Docker Compose pour packaging final webserver.
- Variables d'environnement pour configuration.
- Secrets chiffrés avec master key hors image.
12. URLs utiles
- Hono Node.js : https://hono.dev/docs/getting-started/nodejs
- Hono middleware : https://hono.dev/docs/guides/middleware
- Drizzle SQLite : https://orm.drizzle.team/docs/get-started-sqlite
- SQLite WAL : https://www.sqlite.org/wal.html
- Croner : https://github.com/Hexagon/croner
- MDN WebSocket : https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
- MDN Server-sent events : https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events
- Docker Compose : https://docs.docker.com/compose/
- Compose file reference : https://docs.docker.com/reference/compose-file/
- Docker volumes : https://docs.docker.com/engine/storage/volumes/
- Node.js Docker images : https://hub.docker.com/_/node
13. Liens parent/enfant avec les autres tâches
- Parents :
tache1.9.mdpour schéma BDD.tache2.mdpour actions/templates/JSON.tache4.mdpour scripts post-install.
- Enfants :
tache3.mdconsomme les API.tache6.mdconsomme API/MCP.tache7.mdajoute métriques/nettoyage/sécurité.tache8.mdconsomme API/capabilities.
- Validation :
validation_tache5.md.