0fbca06d3d
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>
533 lines
14 KiB
Markdown
533 lines
14 KiB
Markdown
# 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`.
|