diff --git a/docs/superpowers/specs/2026-04-06-phase2b-dashboard-sante-design.md b/docs/superpowers/specs/2026-04-06-phase2b-dashboard-sante-design.md new file mode 100644 index 0000000..be60f5a --- /dev/null +++ b/docs/superpowers/specs/2026-04-06-phase2b-dashboard-sante-design.md @@ -0,0 +1,147 @@ +# Phase 2b — Dashboard sante + +## Contexte + +Central gere les applications du SI Malio avec leurs environnements. Le socket Docker est monte dans le container Central (phase 2a). Cette phase ajoute un dashboard de sante qui affiche l'etat des containers Docker de chaque environnement, et enrichit la page detail avec des metriques. + +## Architecture + +### Service DockerService + +Classe PHP dans `src/Service/DockerService.php`. + +Utilise `Symfony\Component\Process\Process` pour executer des commandes Docker CLI via le socket monte. + +**Methode `getContainerStatus(string $containerName): array`** + +Execute `docker inspect --format '{{.State.Status}}||{{.Config.Image}}||{{.State.StartedAt}}' {containerName}`. + +Retourne : +```php +[ + 'status' => 'running', // running | exited | restarting | not_found + 'image' => 'gitea.malio.fr/malio-dev/sirh:v1.2.3', + 'version' => 'v1.2.3', // tag extrait de l'image + 'startedAt' => '2026-04-06T10:00:00Z', +] +``` + +Si le container n'existe pas ou la commande echoue, retourne `status: not_found` avec des valeurs vides. + +Le tag/version est extrait en splitant l'image sur `:` — si pas de tag, retourne `latest`. + +**Methode `getContainerStats(string $containerName): array`** + +Execute `docker stats --no-stream --format '{{.CPUPerc}}||{{.MemUsage}}||{{.MemPerc}}' {containerName}`. + +Retourne : +```php +[ + 'cpuPercent' => 2.5, + 'memoryUsage' => '150MiB', + 'memoryLimit' => '2GiB', + 'memoryPercent' => 7.3, +] +``` + +### Endpoints API + +| Route | Methode | Description | Securite | +|-------|---------|-------------|----------| +| `GET /api/dashboard` | GET | Toutes les apps avec statut de chaque env | ROLE_ADMIN | +| `GET /api/environments/{id}/health` | GET | Statut + stats detaillees d'un env | ROLE_ADMIN | + +#### GET /api/dashboard + +Provider custom `DashboardProvider` dans `src/State/`. + +Charge toutes les Applications avec leurs Environments via le repository. Pour chaque Environment, appelle `DockerService::getContainerStatus()`. + +Response : +```json +{ + "applications": [ + { + "name": "SIRH", + "slug": "sirh", + "environments": [ + { + "id": 1, + "name": "production", + "status": "running", + "version": "v1.2.3" + } + ] + } + ] +} +``` + +#### GET /api/environments/{id}/health + +Provider custom `EnvironmentHealthProvider` dans `src/State/`. + +Charge l'Environment par id, appelle `getContainerStatus()` + `getContainerStats()`. + +Response : +```json +{ + "status": "running", + "version": "v1.2.3", + "startedAt": "2026-04-06T10:00:00Z", + "cpuPercent": 2.5, + "memoryUsage": "150MiB", + "memoryLimit": "2GiB", + "memoryPercent": 7.3 +} +``` + +### Frontend + +#### Page dashboard — `/dashboard` + +Nouvelle page. Grille 2 colonnes fixe (`grid-cols-1 lg:grid-cols-2`). + +Une card par application (fond `bg-tertiary-500`, style existant). + +Chaque card : +- Header : nom de l'app (lien vers `/applications/{slug}`) +- Body : une ligne par environnement avec : + - Nom de l'env + - Badge statut : vert `running`, rouge `exited`, orange `restarting`, gris `not_found` + - Version deployee (tag, en `font-mono`) + +Bouton refresh en haut a droite du titre. + +Appel API : `GET /api/dashboard` au chargement. + +#### Page detail — `/applications/{slug}` + +Enrichir chaque bloc d'environnement avec un sous-bloc de metriques : +- Statut container (badge, meme style que dashboard) +- Version deployee +- Uptime (calcule depuis `startedAt` — ex: "2j 5h") +- CPU % +- Memoire : usage / limit (ex: "150MiB / 2GiB — 7.3%") + +Appel API : `GET /api/environments/{id}/health` pour chaque env au chargement de la page. + +#### Sidebar + +Ajouter un lien "Dashboard" (`/dashboard`, icone `mdi:view-dashboard`) au-dessus du lien "Applications" existant. + +### Frontend services + +- `frontend/services/dashboard.ts` : `getDashboard()` et `getEnvironmentHealth(envId)` +- `frontend/services/dto/dashboard.ts` : types TypeScript + +### i18n + +Nouvelles cles dans `fr.json` pour le dashboard (titre, statuts, metriques, refresh). + +## Hors scope + +- Polling automatique +- Alertes / notifications +- Historique de sante +- Restart count, ports, taille des logs