4 bugs de production — module Enfants et authentification¶
Contexte¶
Investigation du 2026-06-25 suite à un signalement : un enfant saisi pour la commune de Kandi disparaissait de la liste après fermeture/ réouverture de session. Le symptôme initial était transitoire (auto-résolu), mais l'investigation a révélé 4 bugs structurels réels, tous corrigés et déployés le jour même.
Contenu¶
Bug 1 — Audit connexion planté silencieusement¶
AuditLogRepositoryPrisma.creer() passait ressourceId comme champ
scalaire direct, alors que dans le client Prisma compilé, ressourceId
est une FK relationnelle vers RessourceAudit — le vrai champ
scalaire est cibleId. Erreur PrismaClientValidationError loguée à
chaque connexion, absorbée silencieusement par le try/catch non
bloquant de l'étape audit — l'audit de connexion était donc perdu à
chaque fois, sans jamais remonter d'erreur visible à l'utilisateur.
Fix : cibleId: donnees.ressourceId au lieu de ressourceId: ....
Bug 2 — communeCode absent du profil après connexion¶
Chaîne de propagation cassée en 4 endroits différents entre le
backend et le frontend : ConnexionHandler.formatSuccessResponse(),
ConnexionUseCase.construireResultat() (3 branches : connexion directe,
2FA configuré, 2FA non configuré), l'interface IConnexionUseCase, et
côté frontend l'entité User (constructeur, fromLoginResult(),
toProfile()) — aucun de ces points ne transportait communeCode.
Conséquence : tout composant frontend filtrant par commune de
l'utilisateur travaillait avec undefined. Fix : ajout du champ à
chaque maillon de la chaîne.
Bug 3 — Mode hors-ligne : liste des enfants vide¶
Deux erreurs dans EnfantsRepository.lister() (voir aussi
ProjetESM/debug/tests-terrain-pwa-offline) : la fonction extraire
lisait data.items alors que le backend retourne data.donnees.enfants
(structure jamais trouvée → cache jamais alimenté) ; et la fonction
construire renvoyait { items, total } au lieu de
{ donnees: { enfants, total, page, ... } } attendu par useEnfants.
Fix : aligner les deux fonctions sur la structure réelle de la
réponse backend, sans toucher au type TypeScript ListeEnfantsResult
(qui reste en décalage documenté, géré ailleurs par un select de hook).
Bug 4 — Listing filtré par créateur au lieu de par commune (le plus grave)¶
EnfantRepositoryPrisma.lister() initialisait le WHERE avec
{ idUtilisateur } (le créateur de la fiche) au lieu d'un scope par
commune. Conséquence concrète : un agent PSYCHOLOGUE de Kandi ne
voyait que les enfants qu'il avait lui-même saisis, pas ceux saisis
par ses collègues de la même commune — et même un ADMIN ne voyait que
ses propres créations. Cause racine plus profonde : ListerEnfantsHandler
ne transmettait pas le scope commune au use case, et
EnfantsModuleController.createContext() (construit à la main) ne
définissait pas getCommuneCode(), pourtant déclarée dans IHttpContext
— contrairement à ExpressHttpContext qui l'implémentait déjà
correctement ailleurs dans le projet.
Logique corrigée : agent terrain → getCommuneCode() retourne son
code commune → WHERE communeCode = 'KANDI' ; admin/accès global →
getCommuneCode() retourne null → aucun filtre, accès à tous les
enfants. Validation : agent Kandi voit 2 enfants (sa commune), admin en
voit 6 (toutes communes).
Décision / Conclusion¶
Bugs corrigés et déployés (backend ×3, frontend ×1 avec PWA v1.3.0).
Le bug 4 est le plus significatif structurellement : un contrôleur
qui construit son propre IHttpContext à la main (au lieu d'utiliser
ExpressHttpContext standard) peut silencieusement omettre des méthodes
de l'interface sans qu'aucune erreur de compilation ne le signale — le
même risque existe potentiellement dans d'autres modules avec un
createContext() maison.
À faire (points de vigilance identifiés)¶
- Vérifier si d'autres contrôleurs ont un
createContext()maison sansgetCommuneCode()/getRole(). - Nettoyer le type
ListeEnfantsResult({ items, total }) en décalage avec la vraie réponse backend ({ donnees: {...} }), actuellement masqué par desas any. obtenirParId()filtre toujours paridUtilisateur(pas par commune) — même incohérence que le bug 4, pas encore corrigée pour cette méthode.
Liens connexes¶
- ProjetESM/debug/tests-terrain-pwa-offline — mode offline concerné par le bug 3
- ProjetESM/architecture/systeme-rbac-permissions — logique de scope par commune dont ce bug révèle une faille d'implémentation
- ProjetESM/index — index du projet