Files
pta/README_V7_9.md
PTA 13ee16e25d Démarrage de la pile par un simple docker compose up
La pile de test de la branche ne démarrait pas : « Connexion à la base
impossible ». Trois causes cumulées, toutes corrigées.

1. PTA_DB_PORT et DB_PORT étaient passés à 9306. Ces variables désignent le
   port joint À L'INTÉRIEUR du réseau Docker, où MariaDB écoute sur 3306, et
   non un port publié sur l'hôte : la connexion était refusée. Elles reviennent
   à 3306, et le port hôte 9306 est désormais réellement publié par le service
   db (sur la boucle locale), pour un client SQL externe.

2. Le service db-migrate manquait sur la branche. Le schéma d'initialisation ne
   contient aucune des tables et vues d'accès V7.8 : sur un volume neuf,
   l'application refusait de démarrer. db-migrate applique maintenant tous les
   database/migration_*.sql, dont celle du tableau de bord V7.9 — plus aucune
   étape SQL manuelle.

3. Le défaut de PTA_DB_PASS (change_me) différait de celui de MARIADB_PASSWORD
   (pta). Sans fichier .env — et ce répertoire n'en a pas, il est ignoré par
   git — l'authentification échouait. Les deux défauts sont alignés.

Le bandeau du tableau de bord ne prétend plus que « tous les lieux ont des
horaires attendus » quand aucun lieu n'est enregistré.

Vérifié : volume détruit puis « docker compose up -d --build » seul suffit à
obtenir les onze pages en 200, l'atterrissage sur le tableau de bord et les deux
migrations appliquées ; un second up les ignore ; la base répond sur
127.0.0.1:9306 ; la pile principale sur 8080 est restée intacte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 11:53:19 +02:00

119 lines
6.1 KiB
Markdown

# PTA V7.9 — Parcours et lisibilité du Service Enfance
## Le problème traité
Le rôle **Service Enfance** ouvre onze écrans. Jusqu'ici :
- il atterrissait sur **Saisie**, alors que son travail commence par le contrôle et non par la saisie ;
- les onze onglets étaient alignés à plat, sans hiérarchie : rien ne distinguait une tâche
quotidienne (« À valider ») d'un référentiel modifié deux fois par an (« Administration ») ;
- chaque bandeau de page affichait le **même** sous-titre générique, il fallait donc ouvrir un écran
pour savoir à quoi il servait ;
- les chiffres qui déclenchent une action (brouillons en attente, manques de couverture, quotas)
vivaient sur trois écrans distincts : personne ne voyait l'état général sans faire le tour ;
- la pastille « À valider » de la barre de navigation n'était alimentée que **sur la page
« À valider » elle-même**, donc invisible là où elle aurait servi.
## Ce qui change
### 1. Un tableau de bord comme page d'accueil
Nouvelle page `dashboard.php`, **réservée au Service Enfance**, qui devient sa page d'atterrissage.
- **Quatre tuiles d'action**, vertes quand il n'y a rien à faire, rouges dès qu'un compteur remonte :
plannings à valider, manques de couverture de la semaine, quotas dépassés, lieux sans horaires de
couverture. Chaque tuile est un lien vers l'écran de traitement.
- **« À valider en priorité »** : les cinq brouillons dont la semaine est la plus ancienne, avec un
bouton **Contrôler** qui ouvre directement l'écran de saisie sur le bon agent, le bon lieu, la
bonne semaine, curseur sur la validation.
- **« Couverture à renforcer »** : les cinq plages les plus déficitaires, triées par nombre d'agents
manquants, avec un lien vers l'écran de couverture déjà filtré.
- **« Suivi des quotas annuels »** : consommation globale, reste à affecter, agents sans aucune heure,
et le détail par agent avec une jauge et un lien vers sa vue annuelle.
- **« Actions fréquentes »** : six raccourcis vers les écrans les plus utilisés.
Un sélecteur de semaine en haut de page rejoue l'ensemble des indicateurs de couverture, et indique
si la semaine est scolaire, de vacances, ou à cheval sur les deux.
### 2. Navigation regroupée par intention
Les onglets sont désormais rangés en quatre groupes : **Piloter** (tableau de bord, à valider,
couverture), **Planifier** (saisie, équipes), **Consulter** (par agent, par lieu, vue annuelle, PTA
détaillé), **Paramétrer** (vacances, administration).
Les rôles qui n'ont que quelques pages — Agent (2), Responsable de structure (4) — gardent la barre
simple d'avant, sans titres de groupe. Une page autorisée en base mais absente des groupes reste
affichée dans un groupe « Autres » plutôt que de disparaître.
### 3. Chaque page dit ce qu'on y fait
Le sous-titre du bandeau est propre à chaque écran et décrit l'action, pas le produit.
### 4. La pastille « À valider » suit partout
Elle est alimentée depuis n'importe quel écran par un compteur léger
(`api/dashboard_summary.php?scope=badges`). L'échec de cet appel est silencieux : une commodité ne
doit jamais empêcher une page de fonctionner.
## Ce qui ne change pas
Aucune règle métier, aucun calcul, aucun droit n'est modifié.
Le tableau de bord ne fait que **relire** ce que les autres écrans calculent déjà : la file de
validation vient de `PlanningModel::pendingValidation()`, la couverture de
`CoverageModel::reportForStructure()`, et le quota reprend exactement la logique de `QuotaModel`
(année civile, motifs décomptés uniquement, quota de l'année la plus proche à défaut de l'année
exacte) — un agent ne peut donc pas afficher deux valeurs différentes selon l'écran consulté.
L'endpoint `api/dashboard_summary.php` est gardé par `requireService()` : 403 pour les autres rôles,
401 sans session.
## Migration
Aucun geste manuel : `database/migration_v7_9_tableau_de_bord.sql` est appliqué au démarrage par le
service `db-migrate`, qui joue tous les `database/migration_*.sql` dans l'ordre. Un simple
```bash
docker compose up -d --build
```
suffit, sur base neuve comme sur base existante. La migration insère une seule ligne dans
`acces_role_page` et est idempotente (`ON DUPLICATE KEY UPDATE`).
Si la migration n'était pas jouée, l'onglet n'apparaîtrait pas, le Service Enfance atterrirait comme
avant sur l'écran de saisie et `dashboard.php` renverrait vers l'accueil : l'application resterait
entièrement fonctionnelle, simplement sans tableau de bord.
Retour arrière :
```sql
DELETE FROM acces_role_page WHERE role = 'SERVICE_ENFANCE' AND page = 'dashboard';
DELETE FROM schema_migration WHERE fichier = 'migration_v7_9_tableau_de_bord.sql';
```
## Fichiers
| Ajouté | Rôle |
| --- | --- |
| `dashboard.php` | point d'entrée de la page |
| `api/dashboard_summary.php` | endpoint JSON |
| `app/Controllers/DashboardController.php` | agrégation et gardes d'accès |
| `app/Models/DashboardModel.php` | suivi des quotas et compteurs |
| `app/Views/pages/dashboard.php`, `app/Views/partials/dashboard.php` | vue |
| `assets/js/dashboard.js` | module `PTA.modules.dashboard` |
| `database/migration_v7_9_tableau_de_bord.sql` | droit d'accès à la page |
| Modifié | Raison |
| --- | --- |
| `docker-compose.yml` | service `db-migrate`, port interne de la base rétabli à 3306, défaut de mot de passe aligné entre `db` et `php` |
| `docker/db/apply-migrations.sh` | application automatique et idempotente des migrations |
| `app/Core/Access.php` | `homeUrl()` vise le tableau de bord, avec repli si la migration manque |
| `app/Controllers/PageController.php` | méthode `dashboard()` et sous-titre propre à chaque page |
| `app/Views/layouts/header.php` | navigation regroupée, sous-titre contextuel |
| `app/Views/layouts/footer.php`, `app/Views/pages/role.php` | versions d'assets `?v=7.9` |
| `assets/js/page-bootstrap.js` | pastille « À valider » sur toutes les pages |
| `assets/style.css` | styles de la navigation groupée et du tableau de bord |
Les jauges de quota utilisent l'élément natif `<progress>` : la CSP interdit l'attribut `style`, une
largeur ne peut donc pas être calculée en JavaScript sur une simple `div`.