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>
1336 lines
36 KiB
Markdown
1336 lines
36 KiB
Markdown
# Consigne de dev — Architecture base de données cible
|
|
|
|
> **Type** : mission d'**analyse + design architecture BDD** (PAS d'implémentation).
|
|
> **Langue** : français.
|
|
> **Livrable final attendu** : spec de schéma de données prête à passer en plan d'implémentation.
|
|
|
|
---
|
|
|
|
## 0. Contexte
|
|
|
|
Le projet `system_update` dispose actuellement d'un schéma SQLite minimal :
|
|
|
|
- `machines`
|
|
- `snapshots`
|
|
- `executions`
|
|
|
|
Ce schéma suffit au jalon 1, mais les tâches suivantes ajoutent de nouveaux besoins :
|
|
|
|
- APT update/analyse, diff avant/après, reboot vérifié ;
|
|
- Docker Compose, roots, stacks, pull-check, apply, prune ;
|
|
- profils post-install et installateurs externes ;
|
|
- sauvegarde de tous les JSON machine ↔ webapp ;
|
|
- automatisations planifiées ;
|
|
- Hermes/MCP/skills/rapports globaux ;
|
|
- optimisation tokens ;
|
|
- nettoyage DB/logs ;
|
|
- découverte de machines SSH ;
|
|
- sécurité credentials et host keys ;
|
|
- observabilité backend.
|
|
|
|
Objectif de cette tâche : concevoir la **meilleure structure BDD cible**, compatible avec le MVP SQLite/Drizzle, mais prévue pour évoluer vers PostgreSQL si le projet grandit.
|
|
|
|
---
|
|
|
|
## 1. Analyse du schéma actuel
|
|
|
|
Schéma actuel :
|
|
|
|
```text
|
|
machines
|
|
├─ id
|
|
├─ name
|
|
├─ hostname
|
|
├─ port
|
|
├─ os_family
|
|
├─ username
|
|
├─ enc_password
|
|
├─ enc_sudo_password
|
|
├─ apt_proxy_mode
|
|
├─ apt_proxy_url
|
|
├─ status
|
|
├─ last_checked_at
|
|
└─ created_at
|
|
|
|
snapshots
|
|
├─ id
|
|
├─ machine_id
|
|
├─ checked_at
|
|
├─ status
|
|
└─ payload_json
|
|
|
|
executions
|
|
├─ id
|
|
├─ machine_id
|
|
├─ action
|
|
├─ mode
|
|
├─ started_at
|
|
├─ finished_at
|
|
├─ status
|
|
├─ result_json
|
|
├─ report_path
|
|
└─ raw_log_path
|
|
```
|
|
|
|
Points forts :
|
|
|
|
- simple ;
|
|
- compatible jalon 1 ;
|
|
- `payload_json` et `result_json` permettent une évolution rapide ;
|
|
- séparation snapshot/exécution correcte ;
|
|
- suppression cascade par machine.
|
|
|
|
Limites :
|
|
|
|
- credentials mélangés à la table machine ;
|
|
- pas de table événements/timeline ;
|
|
- pas de table jobs/schedules persistants ;
|
|
- pas de configuration Docker/post-install par machine ;
|
|
- pas de modèle de templates/scripts ;
|
|
- pas de demandes d'action Hermes en attente de validation ;
|
|
- pas de métriques système/token usage ;
|
|
- pas de rétention/purge ;
|
|
- pas de host keys SSH ;
|
|
- pas de tags/groupes machines ;
|
|
- pas de notion de snapshot kind ;
|
|
- pas de version de schéma JSON.
|
|
|
|
Conclusion : le modèle actuel doit être conservé comme base, mais élargi en couches spécialisées.
|
|
|
|
---
|
|
|
|
## 2. Principe d'architecture BDD
|
|
|
|
### Recommandation MVP
|
|
|
|
Continuer en **SQLite + Drizzle** pour l'application locale/mono-instance :
|
|
|
|
- simple à déployer ;
|
|
- cohérent avec le jalon 1 ;
|
|
- suffisant pour quelques dizaines/centaines de machines ;
|
|
- WAL déjà activé ;
|
|
- backups faciles.
|
|
|
|
### Prévoir PostgreSQL plus tard
|
|
|
|
Garder une architecture compatible PostgreSQL :
|
|
|
|
- IDs text/UUID ;
|
|
- dates ISO ou timestamp abstrait côté code ;
|
|
- JSON stocké en `text` côté SQLite, futur `jsonb` côté PostgreSQL ;
|
|
- tables normalisées pour les recherches fréquentes ;
|
|
- payload complet conservé en JSON ;
|
|
- index explicites.
|
|
|
|
### Règle structurante
|
|
|
|
Chaque donnée métier importante existe sous deux formes :
|
|
|
|
1. **JSON complet archivé** : vérité canonique, relecture, Hermes, audit.
|
|
2. **Colonnes indexées dérivées** : recherche, filtres UI, badges, performances.
|
|
|
|
Exemple :
|
|
|
|
```text
|
|
snapshots.payload_json ← JSON complet
|
|
snapshots.kind/status/checked_at ← filtres rapides
|
|
machine_state.apt_updates_count ← affichage tuile rapide
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Architecture cible — groupes de tables
|
|
|
|
```text
|
|
Core
|
|
├─ machines
|
|
├─ machine_credentials
|
|
├─ machine_host_keys
|
|
├─ machine_tags
|
|
├─ tags
|
|
├─ machine_state
|
|
├─ machine_hardware
|
|
├─ machine_metrics_latest
|
|
├─ app_settings
|
|
├─ user_preferences
|
|
└─ machine_ui_state
|
|
|
|
JSON / Historique
|
|
├─ snapshots
|
|
├─ executions
|
|
├─ machine_events
|
|
├─ important_messages
|
|
├─ reports
|
|
├─ raw_artifacts
|
|
└─ ssh_terminal_sessions
|
|
|
|
APT
|
|
├─ apt_planned_packages
|
|
├─ apt_applied_packages
|
|
└─ apt_errors
|
|
|
|
Docker
|
|
├─ docker_settings
|
|
├─ docker_compose_roots
|
|
├─ docker_compose_stacks
|
|
├─ docker_stack_services
|
|
└─ docker_image_events
|
|
|
|
Post-install / scripts
|
|
├─ install_profiles
|
|
├─ install_recipes
|
|
├─ install_recipe_versions
|
|
├─ machine_profile_state
|
|
└─ script_variables_presets
|
|
|
|
Jobs / automatisations
|
|
├─ jobs
|
|
├─ schedules
|
|
├─ machine_locks
|
|
└─ action_requests
|
|
|
|
Hermes / MCP
|
|
├─ hermes_sessions
|
|
├─ hermes_runs
|
|
├─ hermes_usage
|
|
├─ mcp_audit_log
|
|
└─ api_clients
|
|
|
|
Optimisation / maintenance
|
|
├─ system_metrics
|
|
├─ cleanup_runs
|
|
├─ discovery_scans
|
|
└─ discovery_candidates
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Schéma ASCII global
|
|
|
|
```text
|
|
┌──────────────┐
|
|
│ machines │
|
|
└──────┬───────┘
|
|
│ 1
|
|
├──────────────┬───────────────┬───────────────┐
|
|
│ │ │ │
|
|
▼ ▼ ▼ ▼
|
|
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
│ credentials │ │ host_keys │ │ machine_state│ │ docker_config│
|
|
└──────────────┘ └──────────────┘ └──────────────┘ └──────┬───────┘
|
|
│
|
|
▼
|
|
┌──────────────┐
|
|
│ compose │
|
|
│ roots/stacks │
|
|
└──────────────┘
|
|
|
|
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
│ snapshots │◄────►│ executions │◄────►│ reports │
|
|
└──────┬───────┘ └──────┬───────┘ └──────────────┘
|
|
│ │
|
|
▼ ▼
|
|
┌──────────────┐ ┌──────────────┐
|
|
│ apt planned │ │ apt applied │
|
|
│ docker state │ │ docker events│
|
|
└──────────────┘ └──────────────┘
|
|
|
|
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
│ schedules │─────►│ jobs │─────►│ machine_locks│
|
|
└──────────────┘ └──────────────┘ └──────────────┘
|
|
|
|
┌──────────────┐ ┌──────────────┐
|
|
│ hermes_runs │─────►│ hermes_usage │
|
|
└──────────────┘ └──────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Tables core
|
|
|
|
### `machines`
|
|
|
|
Table publique machine, sans secret.
|
|
|
|
```text
|
|
id text primary key
|
|
name text not null
|
|
hostname text not null
|
|
port integer not null default 22
|
|
os_family text not null
|
|
os_version text
|
|
os_codename text
|
|
arch text
|
|
machine_kind text -- physical | vm | proxmox_host | lxc | raspberry_pi | workstation | unknown
|
|
virtualization text -- none | qemu | kvm | lxc | docker | vmware | virtualbox | ...
|
|
hardware_profile text -- generic_vm | baremetal_server | raspberry_pi | gpu_server | proxmox_host | ...
|
|
username text not null
|
|
status text not null
|
|
created_at text not null
|
|
updated_at text not null
|
|
last_seen_at text
|
|
deleted_at text null
|
|
```
|
|
|
|
Évolutions :
|
|
|
|
- `deleted_at` permet une suppression douce future ;
|
|
- `hostname` peut être IP ou DNS ;
|
|
- `last_seen_at` utile pour statut.
|
|
- `os_family` et `machine_kind` sont deux dimensions différentes : Debian VM, Debian physique, Proxmox hôte, Raspberry Pi OS, etc.
|
|
- ces champs peuvent être choisis manuellement à l'ajout puis corrigés par `machine_probe`.
|
|
|
|
### `machine_credentials`
|
|
|
|
Secrets chiffrés séparés de `machines`.
|
|
|
|
```text
|
|
machine_id text primary key references machines(id)
|
|
auth_method text not null -- password | ssh_key
|
|
enc_password text
|
|
enc_sudo_password text
|
|
enc_private_key text
|
|
enc_key_passphrase text
|
|
sudo_mode text not null -- same_as_ssh | separate | none
|
|
created_at text not null
|
|
updated_at text not null
|
|
last_test_at text
|
|
status text -- ok | error | unknown
|
|
```
|
|
|
|
Règles :
|
|
|
|
- jamais exposée via API publique ;
|
|
- audit obligatoire quand lue/déchiffrée ;
|
|
- migration possible depuis `machines.enc_password`.
|
|
|
|
### `machine_host_keys`
|
|
|
|
Validation host key SSH.
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text references machines(id)
|
|
hostname text not null
|
|
port integer not null
|
|
key_type text
|
|
fingerprint_sha256 text not null
|
|
public_key text
|
|
status text not null -- approved | changed | rejected | unknown
|
|
first_seen_at text not null
|
|
last_seen_at text not null
|
|
```
|
|
|
|
### `machine_state`
|
|
|
|
État courant dérivé pour tuiles et dashboard.
|
|
|
|
```text
|
|
machine_id text primary key
|
|
status text not null
|
|
apt_status text
|
|
apt_updates_count integer default 0
|
|
apt_reboot_required integer default 0
|
|
apt_last_analyze_at text
|
|
docker_status text
|
|
docker_installed integer default 0
|
|
docker_stacks_count integer default 0
|
|
docker_updates_count integer default 0
|
|
docker_prune_available integer default 0
|
|
post_install_status text
|
|
metrics_last_collected_at text
|
|
cpu_load1 real
|
|
memory_used_percent real
|
|
root_used_percent real
|
|
disk_warnings_count integer default 0
|
|
hardware_warnings_count integer default 0
|
|
running_job_id text
|
|
last_error_kind text
|
|
last_error_message text
|
|
updated_at text not null
|
|
```
|
|
|
|
Objectif :
|
|
|
|
- éviter de parser les derniers snapshots à chaque affichage ;
|
|
- les tuiles lisent cette table.
|
|
|
|
### `tags` et `machine_tags`
|
|
|
|
Pour groupes, schedules et filtres.
|
|
|
|
```text
|
|
tags(id, name, color, created_at)
|
|
machine_tags(machine_id, tag_id)
|
|
```
|
|
|
|
Exemples :
|
|
|
|
- `debian`
|
|
- `proxmox`
|
|
- `docker`
|
|
- `domotique`
|
|
- `prod`
|
|
- `lab`
|
|
|
|
### `machine_hardware`
|
|
|
|
Dernier inventaire matériel détecté.
|
|
|
|
```text
|
|
machine_id text primary key references machines(id)
|
|
probe_snapshot_id text references snapshots(id)
|
|
cpu_model text
|
|
cpu_cores integer
|
|
memory_bytes integer
|
|
gpus_json text -- vendor/model/driver/recommendations
|
|
disks_json text -- name/type/size/rotational/smart
|
|
network_json text
|
|
firmware_json text
|
|
driver_json text
|
|
warnings_json text
|
|
updated_at text not null
|
|
```
|
|
|
|
### `machine_metrics_latest`
|
|
|
|
Dernières métriques simples par machine.
|
|
|
|
```text
|
|
machine_id text primary key references machines(id)
|
|
snapshot_id text references snapshots(id)
|
|
collected_at text not null
|
|
cpu_load1 real
|
|
cpu_load5 real
|
|
cpu_cores integer
|
|
memory_total_bytes integer
|
|
memory_used_bytes integer
|
|
memory_available_bytes integer
|
|
memory_used_percent real
|
|
filesystems_json text not null
|
|
root_used_percent real
|
|
warnings_json text
|
|
```
|
|
|
|
Ces métriques ne remplacent pas un vrai outil de monitoring ; elles servent à l'affichage rapide, aux alertes simples et aux rapports Hermes.
|
|
|
|
---
|
|
|
|
## 6. Snapshots, exécutions, événements
|
|
|
|
### `snapshots`
|
|
|
|
Élargir la table existante.
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text not null references machines(id)
|
|
kind text not null -- apt_update_analyze | docker_scan | reboot_check | ...
|
|
schema_version integer not null default 1
|
|
created_at text not null
|
|
status text not null -- ok | warning | error
|
|
payload_json text not null
|
|
important_json text -- version réduite pour Hermes/UI
|
|
raw_log_path text
|
|
raw_artifact_id text
|
|
source_job_id text
|
|
```
|
|
|
|
Index :
|
|
|
|
```text
|
|
(machine_id, kind, created_at desc)
|
|
(kind, status, created_at desc)
|
|
```
|
|
|
|
### `executions`
|
|
|
|
Élargir la table existante.
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text not null references machines(id)
|
|
action text not null
|
|
mode text not null -- manual | scheduled | hermes_requested
|
|
schema_version integer not null default 1
|
|
started_at text not null
|
|
finished_at text
|
|
status text not null -- running | ok | warning | error | cancelled
|
|
request_id text
|
|
job_id text
|
|
result_json text
|
|
important_json text
|
|
raw_log_path text
|
|
raw_artifact_id text
|
|
report_id text
|
|
exit_code integer
|
|
error_kind text
|
|
error_message text
|
|
```
|
|
|
|
Index :
|
|
|
|
```text
|
|
(machine_id, started_at desc)
|
|
(action, status, started_at desc)
|
|
(job_id)
|
|
(request_id)
|
|
```
|
|
|
|
### `machine_events`
|
|
|
|
Timeline/audit unifiée.
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text references machines(id)
|
|
event_type text not null
|
|
severity text not null -- info | warning | error
|
|
created_at text not null
|
|
actor_type text -- user | system | schedule | hermes
|
|
actor_id text
|
|
snapshot_id text
|
|
execution_id text
|
|
job_id text
|
|
message text
|
|
payload_json text
|
|
```
|
|
|
|
### `important_messages`
|
|
|
|
Messages extraits des logs et JSON pour analyse UI/Hermes.
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text references machines(id)
|
|
source text not null -- apt | docker | post_install | ssh | system
|
|
category text not null -- error | warning | future_major_change | deprecation | security_notice | repository_notice
|
|
severity text not null -- info | warning | error
|
|
package_name text
|
|
component text
|
|
message text not null -- résumé nettoyé sans secret
|
|
raw_line_ref text -- artifact_id#line
|
|
snapshot_id text references snapshots(id)
|
|
execution_id text references executions(id)
|
|
first_seen_at text not null
|
|
last_seen_at text not null
|
|
acknowledged integer default 0
|
|
acknowledged_at text
|
|
acknowledged_by text
|
|
payload_json text
|
|
```
|
|
|
|
Objectif :
|
|
|
|
- conserver les warnings importants même si le log brut est purgé ;
|
|
- permettre à Hermes de rechercher les évolutions majeures futures, notices sécurité, dépôts obsolètes ou changements de politique paquet ;
|
|
- alimenter les badges et alertes des tuiles machine ;
|
|
- permettre un acquittement utilisateur sans supprimer l'historique.
|
|
|
|
### `reports`
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text references machines(id)
|
|
execution_id text
|
|
kind text not null -- machine | global | cleanup | hermes
|
|
title text not null
|
|
path text not null
|
|
created_at text not null
|
|
pinned integer default 0
|
|
summary_json text
|
|
```
|
|
|
|
### `raw_artifacts`
|
|
|
|
Pour logs bruts, previews, exports.
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text
|
|
kind text not null -- raw_log | rendered_template | export | screenshot
|
|
path text not null
|
|
bytes integer
|
|
sha256 text
|
|
created_at text not null
|
|
expires_at text
|
|
pinned integer default 0
|
|
redacted integer default 1
|
|
retention_policy text -- default | failed | pinned | short
|
|
deleted_at text
|
|
delete_reason text
|
|
metadata_json text
|
|
```
|
|
|
|
### `ssh_terminal_sessions`
|
|
|
|
Sessions de vrai terminal SSH interactif ouvertes depuis la webapp.
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text not null references machines(id)
|
|
username text
|
|
opened_by text
|
|
opened_at text not null
|
|
closed_at text
|
|
status text not null -- open | closed | error | killed
|
|
interactive integer default 1
|
|
recording_enabled integer default 0
|
|
raw_artifact_id text
|
|
last_error text
|
|
metadata_json text
|
|
```
|
|
|
|
---
|
|
|
|
## 6.1 Préférences frontend et paramètres UI
|
|
|
|
Les paramètres frontend qui doivent survivre au navigateur sont stockés en BDD. Le `localStorage` ne sert qu'à accélérer l'affichage initial ou garder un fallback local.
|
|
|
|
### `app_settings`
|
|
|
|
Paramètres globaux de l'application.
|
|
|
|
```text
|
|
key text primary key
|
|
value_json text not null
|
|
updated_at text not null
|
|
updated_by text
|
|
```
|
|
|
|
Exemples :
|
|
|
|
- thème par défaut ;
|
|
- densité UI ;
|
|
- zoom global ;
|
|
- largeur par défaut volet Hermes/terminal ;
|
|
- terminal SSH interactif activé/désactivé ;
|
|
- rétention logs ;
|
|
- CIDR autorisés pour découverte réseau.
|
|
|
|
### `user_preferences`
|
|
|
|
Préférences par utilisateur/session opérateur, si authentification ajoutée.
|
|
|
|
```text
|
|
id text primary key
|
|
user_id text
|
|
key text not null
|
|
value_json text not null
|
|
updated_at text not null
|
|
```
|
|
|
|
Exemples :
|
|
|
|
- thème choisi ;
|
|
- zoom ;
|
|
- largeur des volets ;
|
|
- taille/densité des tuiles ;
|
|
- mode compact/confort ;
|
|
- onglet par défaut.
|
|
|
|
### `machine_ui_state`
|
|
|
|
État UI par machine, non critique mais utile.
|
|
|
|
```text
|
|
machine_id text primary key references machines(id)
|
|
sections_open_json text -- docker/post-install/logs
|
|
tile_mode text -- compact | expanded
|
|
last_active_tab text
|
|
updated_at text not null
|
|
```
|
|
|
|
Règle :
|
|
|
|
- aucune décision métier ne dépend de cette table ;
|
|
- elle sert uniquement à retrouver l'ergonomie choisie.
|
|
|
|
## 7. APT
|
|
|
|
Les détails APT peuvent rester dans `payload_json`, mais certaines tables dérivées accélèrent recherche/dédup/Hermes.
|
|
|
|
### `apt_planned_packages`
|
|
|
|
Paquets prévus avant upgrade.
|
|
|
|
```text
|
|
id text primary key
|
|
snapshot_id text not null references snapshots(id)
|
|
machine_id text not null
|
|
mode text not null -- upgrade | dist_upgrade
|
|
name text not null
|
|
arch text
|
|
current_version text
|
|
target_version text
|
|
origin text
|
|
operation text not null -- upgrade | install | remove | hold
|
|
dedup_key text not null
|
|
```
|
|
|
|
### `apt_applied_packages`
|
|
|
|
Diff réel après exécution.
|
|
|
|
```text
|
|
id text primary key
|
|
execution_id text not null references executions(id)
|
|
machine_id text not null
|
|
name text not null
|
|
arch text
|
|
from_version text
|
|
to_version text
|
|
operation text not null -- upgraded | installed | removed | unchanged
|
|
origin text
|
|
dedup_key text
|
|
```
|
|
|
|
### `apt_errors`
|
|
|
|
```text
|
|
id text primary key
|
|
snapshot_id text
|
|
execution_id text
|
|
machine_id text not null
|
|
kind text not null -- apt_lock_busy | dpkg_interrupted | ...
|
|
severity text not null
|
|
message text not null
|
|
important_lines_json text
|
|
remediation text
|
|
created_at text not null
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Docker Compose
|
|
|
|
### `docker_settings`
|
|
|
|
Configuration Docker par machine.
|
|
|
|
```text
|
|
machine_id text primary key references machines(id)
|
|
enabled integer default 0
|
|
scan_depth integer default 4
|
|
prune_mode text default 'safe' -- safe | aggressive
|
|
last_scan_at text
|
|
last_pull_check_at text
|
|
updated_at text not null
|
|
```
|
|
|
|
### `docker_compose_roots`
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text not null references machines(id)
|
|
path text not null
|
|
enabled integer default 1
|
|
scan_depth integer
|
|
created_at text not null
|
|
updated_at text not null
|
|
```
|
|
|
|
### `docker_compose_stacks`
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text not null
|
|
name text not null
|
|
working_dir text not null
|
|
compose_files_json text not null
|
|
project_name text
|
|
env_file text
|
|
status text not null -- candidate | enabled | ignored | error
|
|
detected_by text -- root_scan | label | manual
|
|
last_scan_at text
|
|
last_update_at text
|
|
created_at text not null
|
|
updated_at text not null
|
|
```
|
|
|
|
### `docker_stack_services`
|
|
|
|
Dernier état service/image par stack.
|
|
|
|
```text
|
|
id text primary key
|
|
stack_id text not null references docker_compose_stacks(id)
|
|
service_name text not null
|
|
image_ref text
|
|
current_image_id text
|
|
current_digest text
|
|
candidate_image_id text
|
|
candidate_digest text
|
|
version_label text
|
|
status text -- up_to_date | updates_available | error
|
|
updated_at text not null
|
|
```
|
|
|
|
### `docker_image_events`
|
|
|
|
Historique pull/apply/prune.
|
|
|
|
```text
|
|
id text primary key
|
|
execution_id text references executions(id)
|
|
machine_id text not null
|
|
stack_id text
|
|
service_name text
|
|
image_ref text
|
|
from_image_id text
|
|
to_image_id text
|
|
from_digest text
|
|
to_digest text
|
|
operation text -- pulled | recreated | pruned
|
|
bytes_reclaimed integer
|
|
created_at text not null
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Post-install, scripts, templates
|
|
|
|
### `install_profiles`
|
|
|
|
Catalogue de profils.
|
|
|
|
```text
|
|
id text primary key
|
|
label text not null
|
|
category text not null
|
|
risk text
|
|
enabled integer default 1
|
|
manifest_json text not null
|
|
created_at text not null
|
|
updated_at text not null
|
|
```
|
|
|
|
### `install_recipes`
|
|
|
|
Installateurs externes ou scripts custom.
|
|
|
|
```text
|
|
id text primary key
|
|
profile_id text references install_profiles(id)
|
|
label text not null
|
|
source_type text not null -- apt_packages | official_external | custom
|
|
risk text
|
|
current_version_id text
|
|
enabled integer default 1
|
|
created_at text not null
|
|
updated_at text not null
|
|
```
|
|
|
|
### `install_recipe_versions`
|
|
|
|
Versionner les scripts/manifests.
|
|
|
|
```text
|
|
id text primary key
|
|
recipe_id text not null references install_recipes(id)
|
|
version integer not null
|
|
template_path text not null
|
|
manifest_json text not null
|
|
sha256 text
|
|
created_at text not null
|
|
created_by text
|
|
```
|
|
|
|
### `machine_profile_state`
|
|
|
|
État des profils par machine.
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text not null references machines(id)
|
|
profile_id text not null references install_profiles(id)
|
|
status text not null -- not_run | ok | warning | error | pending
|
|
last_execution_id text
|
|
last_run_at text
|
|
variables_json text -- non sensible seulement
|
|
```
|
|
|
|
### `script_variables_presets`
|
|
|
|
Préréglages réutilisables.
|
|
|
|
```text
|
|
id text primary key
|
|
scope text not null -- global | machine | profile
|
|
machine_id text
|
|
profile_id text
|
|
name text not null
|
|
variables_json text not null
|
|
created_at text not null
|
|
updated_at text not null
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Jobs, schedules, demandes d'action
|
|
|
|
### `jobs`
|
|
|
|
```text
|
|
id text primary key
|
|
kind text not null
|
|
machine_id text
|
|
schedule_id text
|
|
request_id text
|
|
status text not null -- queued | running | ok | warning | error | cancelled
|
|
priority integer default 0
|
|
created_at text not null
|
|
started_at text
|
|
finished_at text
|
|
attempt integer default 0
|
|
max_attempts integer default 1
|
|
payload_json text
|
|
result_json text
|
|
error_kind text
|
|
error_message text
|
|
```
|
|
|
|
### `schedules`
|
|
|
|
```text
|
|
id text primary key
|
|
name text not null
|
|
enabled integer default 1
|
|
cron text not null
|
|
timezone text not null
|
|
scope_json text not null
|
|
actions_json text not null
|
|
concurrency integer default 1
|
|
notify_on_json text
|
|
last_run_at text
|
|
next_run_at text
|
|
created_at text not null
|
|
updated_at text not null
|
|
```
|
|
|
|
### `machine_locks`
|
|
|
|
```text
|
|
machine_id text primary key references machines(id)
|
|
job_id text not null
|
|
lock_kind text not null -- apt | docker | post_install | reboot | exclusive
|
|
created_at text not null
|
|
expires_at text
|
|
```
|
|
|
|
### `action_requests`
|
|
|
|
Demandes venant UI ou Hermes, avec validation.
|
|
|
|
```text
|
|
id text primary key
|
|
machine_id text references machines(id)
|
|
requested_by_type text not null -- user | hermes | schedule
|
|
requested_by_id text
|
|
action text not null
|
|
risk text
|
|
status text not null -- pending | approved | rejected | executed | expired
|
|
summary text
|
|
payload_json text
|
|
created_at text not null
|
|
approved_at text
|
|
approved_by text
|
|
execution_id text
|
|
expires_at text
|
|
```
|
|
|
|
---
|
|
|
|
## 11. Hermes, MCP, token usage
|
|
|
|
### `hermes_sessions`
|
|
|
|
```text
|
|
id text primary key
|
|
source text not null -- webapp | tui | telegram | discord | ...
|
|
session_key text
|
|
created_at text not null
|
|
last_message_at text
|
|
status text
|
|
```
|
|
|
|
### `hermes_runs`
|
|
|
|
```text
|
|
id text primary key
|
|
session_id text references hermes_sessions(id)
|
|
prompt_kind text
|
|
status text
|
|
started_at text not null
|
|
finished_at text
|
|
request_json text -- réduit, sans secret
|
|
response_json text
|
|
report_id text
|
|
```
|
|
|
|
### `hermes_usage`
|
|
|
|
```text
|
|
id text primary key
|
|
run_id text references hermes_runs(id)
|
|
provider text
|
|
model text
|
|
prompt_tokens integer
|
|
cached_tokens integer
|
|
completion_tokens integer
|
|
total_tokens integer
|
|
raw_bytes integer
|
|
reduced_bytes integer
|
|
reduction_ratio real
|
|
created_at text not null
|
|
```
|
|
|
|
### `mcp_audit_log`
|
|
|
|
```text
|
|
id text primary key
|
|
server_name text not null
|
|
tool_name text not null
|
|
actor text
|
|
request_json text
|
|
response_summary_json text
|
|
status text
|
|
created_at text not null
|
|
```
|
|
|
|
### `api_clients`
|
|
|
|
Clients API externes : app locale Rust/GNOME, scripts internes, clients admin.
|
|
|
|
```text
|
|
id text primary key
|
|
label text not null
|
|
client_kind text not null -- webapp | rust_gnome_app | script | mcp | other
|
|
token_hash text not null
|
|
scopes_json text not null -- read | operate | admin | debug_logs
|
|
status text not null -- active | revoked | expired
|
|
created_at text not null
|
|
last_seen_at text
|
|
expires_at text
|
|
revoked_at text
|
|
metadata_json text
|
|
```
|
|
|
|
Règles :
|
|
|
|
- ne jamais stocker le token en clair ;
|
|
- audit des actions via `machine_events` ou table dédiée si nécessaire ;
|
|
- scopes minimaux ;
|
|
- révocation depuis les paramètres sécurité.
|
|
|
|
---
|
|
|
|
## 12. Optimisation, maintenance, découverte
|
|
|
|
### `system_metrics`
|
|
|
|
```text
|
|
id text primary key
|
|
created_at text not null
|
|
cpu_percent real
|
|
memory_rss_bytes integer
|
|
memory_heap_bytes integer
|
|
db_bytes integer
|
|
wal_bytes integer
|
|
jobs_running integer
|
|
machines_count integer
|
|
payload_json text
|
|
```
|
|
|
|
### `cleanup_runs`
|
|
|
|
```text
|
|
id text primary key
|
|
mode text not null -- dry_run | apply
|
|
status text not null
|
|
started_at text not null
|
|
finished_at text
|
|
deleted_counts_json text
|
|
bytes_reclaimed integer
|
|
result_json text
|
|
```
|
|
|
|
### `discovery_scans`
|
|
|
|
```text
|
|
id text primary key
|
|
cidr text not null
|
|
ports_json text not null
|
|
method text not null -- nmap | tcp
|
|
status text not null
|
|
started_at text not null
|
|
finished_at text
|
|
result_json text
|
|
```
|
|
|
|
### `discovery_candidates`
|
|
|
|
```text
|
|
id text primary key
|
|
scan_id text not null references discovery_scans(id)
|
|
host text not null
|
|
port integer not null
|
|
service text
|
|
host_key_fingerprint text
|
|
reverse_dns text
|
|
already_known integer default 0
|
|
created_at text not null
|
|
```
|
|
|
|
---
|
|
|
|
## 13. Index recommandés
|
|
|
|
```text
|
|
machines(hostname, port)
|
|
machines(status)
|
|
machines(os_family, machine_kind)
|
|
machines(hardware_profile)
|
|
|
|
snapshots(machine_id, kind, created_at desc)
|
|
snapshots(kind, status, created_at desc)
|
|
|
|
executions(machine_id, started_at desc)
|
|
executions(action, status, started_at desc)
|
|
executions(job_id)
|
|
|
|
machine_events(machine_id, created_at desc)
|
|
machine_events(event_type, created_at desc)
|
|
|
|
machine_hardware(updated_at desc)
|
|
machine_metrics_latest(collected_at desc)
|
|
machine_metrics_latest(root_used_percent)
|
|
|
|
apt_planned_packages(dedup_key)
|
|
apt_planned_packages(machine_id, name)
|
|
apt_applied_packages(dedup_key)
|
|
apt_applied_packages(execution_id)
|
|
|
|
docker_compose_stacks(machine_id, status)
|
|
docker_stack_services(stack_id, status)
|
|
|
|
jobs(status, created_at)
|
|
jobs(machine_id, status)
|
|
schedules(enabled, next_run_at)
|
|
action_requests(status, created_at)
|
|
|
|
reports(machine_id, created_at desc)
|
|
reports(kind, created_at desc)
|
|
|
|
important_messages(machine_id, severity, last_seen_at desc)
|
|
important_messages(category, acknowledged, last_seen_at desc)
|
|
important_messages(package_name)
|
|
|
|
raw_artifacts(machine_id, created_at desc)
|
|
raw_artifacts(expires_at)
|
|
|
|
ssh_terminal_sessions(machine_id, opened_at desc)
|
|
ssh_terminal_sessions(status)
|
|
|
|
hermes_runs(session_id, started_at desc)
|
|
hermes_usage(run_id)
|
|
api_clients(status, client_kind)
|
|
```
|
|
|
|
---
|
|
|
|
## 14. Migration progressive recommandée
|
|
|
|
Ne pas tout implémenter d'un coup.
|
|
|
|
### Phase 1 — Séparer et fiabiliser le socle
|
|
|
|
- ajouter `machine_state` ;
|
|
- ajouter `machine_kind/virtualization/hardware_profile` dans `machines` ;
|
|
- ajouter `machine_hardware` ;
|
|
- ajouter `machine_metrics_latest` ;
|
|
- ajouter `machine_events` ;
|
|
- ajouter `important_messages` ;
|
|
- ajouter `reports` ;
|
|
- ajouter `raw_artifacts` ;
|
|
- ajouter `kind/schema_version/important_json` à `snapshots` ;
|
|
- ajouter `schema_version/important_json/error_kind/error_message` à `executions`.
|
|
|
|
### Phase 1.5 — Préférences frontend
|
|
|
|
- créer `app_settings` ;
|
|
- créer `user_preferences` ;
|
|
- créer `machine_ui_state` ;
|
|
- migrer le thème actuel depuis une logique `localStorage` vers une préférence persistée côté backend, avec fallback local.
|
|
|
|
### Phase 2 — Sécurité credentials
|
|
|
|
- créer `machine_credentials` ;
|
|
- migrer `enc_password`, `enc_sudo_password` ;
|
|
- créer `machine_host_keys` ;
|
|
- ajouter audit événements secrets.
|
|
|
|
### Phase 3 — APT complet
|
|
|
|
- créer `apt_planned_packages` ;
|
|
- créer `apt_applied_packages` ;
|
|
- créer `apt_errors`.
|
|
|
|
### Phase 4 — Docker
|
|
|
|
- créer `docker_settings` ;
|
|
- créer `docker_compose_roots` ;
|
|
- créer `docker_compose_stacks` ;
|
|
- créer `docker_stack_services` ;
|
|
- créer `docker_image_events`.
|
|
|
|
### Phase 5 — Post-install/scripts
|
|
|
|
- créer `install_profiles` ;
|
|
- créer `install_recipes` ;
|
|
- créer `install_recipe_versions` ;
|
|
- créer `machine_profile_state` ;
|
|
- créer `script_variables_presets`.
|
|
|
|
### Phase 6 — Automatisations
|
|
|
|
- créer `jobs` ;
|
|
- créer `schedules` ;
|
|
- créer `machine_locks` ;
|
|
- créer `action_requests`.
|
|
|
|
### Phase 7 — Hermes/optimisation
|
|
|
|
- créer `hermes_sessions` ;
|
|
- créer `hermes_runs` ;
|
|
- créer `hermes_usage` ;
|
|
- créer `mcp_audit_log` ;
|
|
- créer `api_clients`.
|
|
|
|
### Phase 8 — Maintenance/découverte
|
|
|
|
- créer `system_metrics` ;
|
|
- créer `cleanup_runs` ;
|
|
- créer `discovery_scans` ;
|
|
- créer `discovery_candidates`.
|
|
|
|
### Phase 9 — Terminal SSH interactif
|
|
|
|
- créer `ssh_terminal_sessions` ;
|
|
- définir activation globale dans `app_settings` ;
|
|
- journaliser ouverture/fermeture ;
|
|
- décider si l'enregistrement de session est désactivé, optionnel ou obligatoire selon profil de sécurité.
|
|
|
|
---
|
|
|
|
## 15. Recommandations importantes
|
|
|
|
### Garder les JSON complets
|
|
|
|
Même avec tables dérivées, conserver les payloads JSON complets :
|
|
|
|
- audit ;
|
|
- relecture ;
|
|
- compatibilité Hermes ;
|
|
- évolution future ;
|
|
- debug.
|
|
|
|
### Versionner les JSON
|
|
|
|
Ajouter `schema_version` sur snapshots/executions.
|
|
|
|
### Ne jamais stocker de secrets dans JSON métier
|
|
|
|
Secrets seulement dans `machine_credentials`, chiffrés.
|
|
|
|
### Dériver `machine_state`
|
|
|
|
Le dashboard ne doit pas recalculer les compteurs depuis l'historique à chaque requête.
|
|
|
|
### Prévoir rétention
|
|
|
|
Les tables historiques peuvent grossir :
|
|
|
|
- snapshots ;
|
|
- executions ;
|
|
- events ;
|
|
- raw_artifacts ;
|
|
- hermes_usage.
|
|
|
|
Tâche 7 définit la purge.
|
|
|
|
### Préparer PostgreSQL
|
|
|
|
Si migration PostgreSQL future :
|
|
|
|
- `payload_json` → `jsonb` ;
|
|
- `text ISO` → `timestamptz` ;
|
|
- index GIN sur JSON si besoin ;
|
|
- jobs persistants avec `pg-boss`.
|
|
|
|
---
|
|
|
|
## 16. Livrables attendus
|
|
|
|
À produire sous `docs/` :
|
|
|
|
1. Schéma BDD détaillé.
|
|
2. Diagramme relationnel.
|
|
3. Plan de migration depuis le schéma actuel.
|
|
4. Priorisation par phases.
|
|
5. Stratégie SQLite maintenant / PostgreSQL futur.
|
|
6. Liste des index.
|
|
7. Règles de rétention.
|
|
8. Règles sécurité secrets.
|
|
9. Contrats JSON versionnés.
|
|
|
|
---
|
|
|
|
## 17. Définition de terminé
|
|
|
|
- Le schéma couvre les tâches 2 à 8.
|
|
- Le schéma reste compatible MVP SQLite.
|
|
- Les évolutions futures sont prévues.
|
|
- Les secrets sont isolés.
|
|
- Les JSON complets restent archivés.
|
|
- Les tuiles machine peuvent lire un état courant rapide.
|
|
- Les automatisations et Hermes ont leurs tables dédiées.
|
|
- Aucun code de production n'est livré pendant cette mission de design.
|
|
|
|
---
|
|
|
|
## 18. Technos à utiliser — checklist
|
|
|
|
- [ ] SQLite au MVP, avec WAL activé.
|
|
- [ ] Drizzle ORM pour schéma TypeScript et migrations.
|
|
- [ ] JSON stocké en `text` côté SQLite, compatible futur `jsonb` PostgreSQL.
|
|
- [ ] Index explicites sur colonnes de recherche/fréquence.
|
|
- [ ] Volumes persistants Docker Compose pour DB, WAL, logs, reports, artifacts.
|
|
- [ ] Chiffrement applicatif des secrets avant stockage.
|
|
- [ ] Table `api_clients` pour tokens externes hashés/révocables.
|
|
- [ ] Plan de migration progressif, phase par phase.
|
|
|
|
## 19. URLs utiles
|
|
|
|
- SQLite WAL : https://www.sqlite.org/wal.html
|
|
- SQLite `PRAGMA optimize` : https://www.sqlite.org/pragma.html#pragma_optimize
|
|
- SQLite VACUUM : https://www.sqlite.org/lang_vacuum.html
|
|
- Drizzle ORM SQLite : https://orm.drizzle.team/docs/get-started-sqlite
|
|
- Drizzle migrations : https://orm.drizzle.team/docs/migrations
|
|
- PostgreSQL JSON types : https://www.postgresql.org/docs/current/datatype-json.html
|
|
- Docker volumes : https://docs.docker.com/engine/storage/volumes/
|
|
- Docker Compose volumes : https://docs.docker.com/reference/compose-file/volumes/
|
|
|
|
## 20. Liens parent/enfant avec les autres tâches
|
|
|
|
- Parent direct : aucune, cette tâche structure la donnée cible.
|
|
- Enfants directs :
|
|
- `tache2.md` : contrats JSON/templates à stocker.
|
|
- `tache3.md` : préférences UI, état tuiles.
|
|
- `tache4.md` : profils/scripts/variables.
|
|
- `tache5.md` : API/jobs/historique.
|
|
- `tache6.md` : Hermes/MCP/audit.
|
|
- `tache7.md` : rétention, métriques, nettoyage.
|
|
- `tache8.md` : `api_clients` et compatibilité app locale.
|
|
- Validation : `validation_tache1.9.md`.
|