docs: roadmap tâches 1.9-8 (briefs, gates de validation, designs tâche 2) + plans d'implémentation
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>
This commit is contained in:
@@ -0,0 +1,532 @@
|
||||
# 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.md`
|
||||
- `tache1.9.md`
|
||||
- `tache2.md`
|
||||
- `tache3.md`
|
||||
- `tache4.md`
|
||||
- `validation_tache2.md`
|
||||
- `shared/types.ts`
|
||||
- `server/db/schema.ts`
|
||||
- `server/services/refresh.ts`
|
||||
- `server/services/execute.ts`
|
||||
- `server/jobs/worker.ts`
|
||||
- `server/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/analyse` de 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_snapshot`
|
||||
- `machine_probe_snapshot`
|
||||
- `machine_metrics_snapshot`
|
||||
- `apt_update_analyze_snapshot`
|
||||
- `docker_scan_snapshot`
|
||||
- `docker_pull_check_snapshot`
|
||||
- `post_install_manifest_snapshot`
|
||||
- `reboot_check_snapshot`
|
||||
|
||||
Champs communs :
|
||||
|
||||
```json
|
||||
{
|
||||
"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_upgrade`
|
||||
- `apt_full_upgrade`
|
||||
- `apt_autoremove`
|
||||
- `apt_clean`
|
||||
- `docker_apply`
|
||||
- `docker_prune`
|
||||
- `post_install_profile`
|
||||
- `reboot_verified`
|
||||
|
||||
Champs communs :
|
||||
|
||||
```json
|
||||
{
|
||||
"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>/...log` ou 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 :
|
||||
|
||||
```json
|
||||
{
|
||||
"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 update` ne 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 :
|
||||
|
||||
```json
|
||||
{
|
||||
"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_analyze` de toutes les machines à heure précise ;
|
||||
- `machine_metrics_simple` pé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 :
|
||||
|
||||
```json
|
||||
{
|
||||
"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é :
|
||||
|
||||
- `croner` dé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-boss` si 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_locks` ou statut job courant ;
|
||||
- `idempotencyKey` pour é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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```json
|
||||
{
|
||||
"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/` :
|
||||
|
||||
1. Schéma de données backend.
|
||||
2. Modèle d'événements machine.
|
||||
3. Modèle d'état courant machine.
|
||||
4. Spécification des schedules automatisés.
|
||||
5. Règles de verrouillage/idempotence.
|
||||
6. API backend.
|
||||
7. Modèle des messages importants extraits des logs.
|
||||
8. Modèle snapshots hardware/profil machine/métriques simples.
|
||||
9. Politique de rétention/logs/rapports/messages.
|
||||
10. Intégration avec UI et Hermes.
|
||||
11. 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.
|
||||
- [ ] `croner` pour 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.md` pour schéma BDD.
|
||||
- `tache2.md` pour actions/templates/JSON.
|
||||
- `tache4.md` pour scripts post-install.
|
||||
- Enfants :
|
||||
- `tache3.md` consomme les API.
|
||||
- `tache6.md` consomme API/MCP.
|
||||
- `tache7.md` ajoute métriques/nettoyage/sécurité.
|
||||
- `tache8.md` consomme API/capabilities.
|
||||
- Validation : `validation_tache5.md`.
|
||||
Reference in New Issue
Block a user