# Vagues de formation — design

Date : 2026-09-25. Validé section par section en conversation avec le porteur de projet, relecture écrite dispensée (« passe directement à l'implémentation »).

## 1. But

Une formation peut avoir trop d'apprenants pour un seul groupe : on les divise en **vagues** qui suivent la formation **en parallèle** (même période), chacune avec **son formateur attitré**. Un formateur qui a plusieurs vagues fait **une séance par vague**, donc parfois plusieurs dans la journée. Séances, appel, présence et suivi doivent être distingués par vague.

Décisions actées (questions posées une par une) :

| Question | Décision |
|---|---|
| Vagues dans le temps | En parallèle, même période |
| Planning des leçons | Commun à toutes les vagues (Programme inchangé) |
| Formateur | Un formateur attitré par vague |
| Obligatoire ? | Toujours une vague ; « Vague 1 » créée automatiquement |
| Qui gère | Admin partout, gestionnaire dans son centre, formateur pour ses formations (il devient formateur de la vague qu'il crée) |
| Approche | A : la vague organise le travail, la visibilité par formation ne change pas |
| Inscription | Choix de la vague à l'inscription, ou « + Nouvelle vague » créée dans la foulée |

Hors périmètre, volontairement : planning par vague, horaires, capacité, répartition automatique, restriction de visibilité par vague (approche B). C'est ce qui avait rendu « Groupe » trop lourd (supprimé le 2026-08-07).

## 2. Données

- **`vagues`** : `id`, `formation_id`, `centre_id`, `formateur_id` (users), `nom` (string 100), timestamps, softDeletes. Unique `(formation_id, centre_id, nom)`.
- **`apprenants.vague_id`** (nullable en base, FK `vagues`) : la vague **actuelle**. Invariant applicatif : même `formation_id` et `centre_id` que l'apprenant.
- **`presences.vague_id`** (nullable) : la vague de l'apprenant **au moment où la présence est notée** (instantané). Les présents d'une séance sont lus par `(vague_id, date)` : changer un apprenant de vague ne réécrit pas les séances passées.
- **`seances.vague_id`** (nullable en base, toujours renseigné par l'application). L'unicité `(formateur_id, formation_id, date)` est remplacée par `(vague_id, date)`.

Les colonnes sont nullables en base pour ne pas imposer une vague aux données de test et aux lignes historiques ; l'application garantit la vague à toute nouvelle inscription, présence et séance.

## 3. Règles

- **Création d'une vague** : admin (tout centre), gestionnaire (son centre), formateur (une formation qu'il enseigne, dans son centre, et il en est le formateur). Le formateur attitré doit enseigner la formation et appartenir au centre.
- **Modification** : renommer (admin, gestionnaire du centre, formateur attitré) ; changer de formateur (admin, gestionnaire du centre).
- **Retrait** (soft delete) : seulement si aucun apprenant n'y est rattaché.
- **Inscription** : `vague_id` (existante, même formation et même centre) **ou** `nouvelle_vague_nom` (+ `nouvelle_vague_formateur_id` pour admin/gestionnaire ; le formateur est lui-même). Si aucun des deux n'est fourni et que la formation n'a aucune vague dans ce centre, « Vague 1 » est créée automatiquement avec l'unique formateur possible ; s'il y en a plusieurs, ou aucun, erreur explicite. S'il existe déjà des vagues, le choix est obligatoire. La secrétaire ne crée pas de vague (hors création automatique de « Vague 1 »).
- **Changement de vague** (Modifier l'apprenant) : `vague_id` de la même formation et du même centre. Progression et leçons conservées. Un changement de formation exige une vague de la nouvelle formation (mêmes règles qu'à l'inscription).
- **Séance** : ouverte pour une vague dont on est le formateur attitré ; une par vague et par jour ; une seule séance ouverte à la fois par formateur ; dans la période de la formation. `formation_id` et `centre_id` de la séance sont ceux de la vague.
- **Appel** : apprenants à inscription active dont la vague actuelle est celle de la séance. `nb_inscrits` = leur nombre.
- **Présents d'une séance** : présences à vrai ce jour-là avec `vague_id` = vague de la séance.
- **Leçons d'une séance** : inchangé (formation, centre, date).
- **Jours sans séance** : couples (vague du formateur, jour jusqu'à la veille) avec une leçon planifiée pour la formation et le centre de la vague, sans séance de cette vague.

## 4. Écrans

- **Inscription / Modifier l'apprenant** : champ Vague sous Formation (vagues de la formation et du centre, présélectionnée s'il n'y en a qu'une), bouton « + Nouvelle vague » (nom proposé « Vague N », formateur à choisir pour admin/gestionnaire).
- **Tableau de bord formateur** : chaque carte formation liste ses vagues avec effectif et un bouton « + Nouvelle vague ».
- **Carte « Ma séance du jour »** : propose ses vagues pas encore pointées aujourd'hui ; libellés « Commencer la séance · Vague 1 » ; « Séance du jour terminée » quand toutes ses vagues sont faites. Rattrapage : choix de la vague.
- **Page Programme** : bloc « Vagues » (nom, formateur, effectif ; renommer, changer de formateur, retirer si vide, nouvelle vague).
- **Apprenants** : colonne Vague, filtre Vague (quand une formation est choisie) ; exports avec colonne Vague.
- **Présence** : filtre Vague, colonne Vague.
- **Séances** : colonne Vague (liste et détail).
- **Rapports** : colonne Vague ; rapport de formation PDF/CSV : vague par séance et par apprenant.
- **Espace apprenant** : « Formation · Vague ».

## 5. Reprise de l'existant

Migration : une « Vague 1 » par couple (formation, centre) ayant des apprenants. Formateur : celui qui a des séances sur ce couple, sinon l'unique formateur rattaché à la formation dans ce centre, sinon le premier par id. Apprenants rangés dans leur Vague 1, présences et séances existantes renseignées avec la vague de l'apprenant / du couple. Chez le porteur de projet : ALPHABETISATION × Goz Beida → NICOLAS (19) ; ALPHABETISATION × Gerreda → nick (16).

## 6. Vérification

Tests écrits d'abord (vagues, inscription avec la forme réelle du payload, séances, présence, reprise), suite complète verte, puis vérification réelle : migration sur MySQL, parcours rejoué avec les vrais comptes dans une transaction annulée, rendu Edge desktop + mobile, données temporaires retirées.
