# Besoin d'évolution — Module de pilotage / analytics (logué le 05/08/2026)

**Origine** : demande du DG (Pierre) d'un état d'utilisation par module et nominatif de
l'Académie depuis sa création — classement des modules consultés, profils de consultation
(one-shot vs récurrent), téléchargements de documents. Audit réalisé les 04-05/08/2026
(lecture seule, prod + code).

## Constat (état actuel de la plateforme)

Le LMS enregistre des **états**, pas des **événements** :

| Donnée | État actuel |
|---|---|
| Consultation d'une leçon (« vue ») | ❌ Non enregistrée. Seule la validation manuelle « Terminer la leçon » crée une ligne `learner_lessons` (1 max par couple apprenant×leçon, horodatée). |
| Temps passé | ❌ Non enregistré. |
| Connexions | ⚠️ Indirect : `personal_access_tokens` (1 token/login, supprimés au logout) — plancher, non exposé. |
| Tentatives de quiz | ⚠️ Dernière tentative uniquement — `LearnerCourseController` **supprime** les scores précédents à chaque soumission/retake. |
| Date de complétion | ⚠️ En base (`completed_courses.completed_at`) mais **jamais exposée** par l'API admin ni l'export. |
| Téléchargements de ressources (`course_files`) | ❌ Servis en lien statique public (`VITE_APP_MEDIA_URL + stored_path`), sans passer par Laravel → aucune journalisation applicative. Seuls les access logs Apache en gardent trace (rétention limitée). |
| Téléchargements de certificats | ⚠️ Passent par l'API (`/learner/certificates/download/{id}`) mais aucune écriture en base. |

Conséquence : impossible de répondre proprement à « qui consulte quoi, à quelle fréquence,
qui télécharge quoi ». Reconstitution partielle possible (cf. pack SQL/logs transmis au
porteur du besoin), mais sans pérennité.

## Besoin cible (à intégrer au cahier des charges d'évolution globale)

1. **Journal d'événements d'usage** (socle) : ouverture de leçon, durée, téléchargement de
   ressource, téléchargement de certificat, connexion — nominatif, horodaté, rattaché au
   module/parcours.
2. **Historisation des tentatives de quiz** (ne plus écraser).
3. **Exposition des dates de complétion** dans l'API admin et les exports.
4. **Dashboards de pilotage** : par module (funnel inscrits → démarrés → terminés, vues,
   apprenants uniques, temps moyen), par apprenant (timeline, récurrence one-shot/récurrent),
   par organisation/périmètre managérial ; exports XLSX/CSV ; filtres par période.
5. **Conformité RGPD** : minimisation (IP tronquée/hashée), durées de rétention, information
   des utilisateurs, périmètre d'accès par rôle.

Bugs de reporting relevés au passage (à corriger dans la même vague) :
- `DashBoardController::index` mode cours unique : le périmètre managérial (`$assignedLearners`)
  n'est pas transmis à `getSingleCourseStats` (signature à 1 paramètre) → chiffres non filtrés.
- `CourseCompleRation` : `unique()` commentés → apprenants comptés N fois dans les totaux.
- `sidebarStatics` : `case 'sub_manager'`/`'manager_general'` sans `break` (fall-through).
- `EnrollmentController:328` : update d'une colonne `enrollments.is_complete` qui n'existe pas
  (écriture silencieusement perdue).
- `users.is_active` utilisé par le code mais absent des migrations (colonne créée hors migration).
- `UserController::index` pagine à 20 en dur (le paramètre `per_page` est ignoré).

## Statut

- [x] Besoin documenté (ce fichier)
- [ ] Cahier des charges global (en préparation — Enguerran)
- [ ] Chiffrage / priorisation avec l'équipe dev
- [ ] Implémentation
