Files
system_update/tache5.md
T
gilles 0fbca06d3d 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>
2026-06-05 19:50:25 +02:00

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.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 :

{
  "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 :

{
  "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 :

{
  "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 :

{
  "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 :

{
  "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 :

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/ :

  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

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.