Exécution — Tests E2E profils MEAL_COMMUNAL / MEAL_NATIONAL¶
Suite de ProjetESM/debug/20260710_2225_execution-tests-e2e-assistant-social (même méthode : simulation réelle Playwright). Cette fois le périmètre inclut les indicateurs et
/pilotage/*(exclus des deux sessions précédentes) car c'est le cœur du métier MEAL, contrairement à PSYCHOLOGUE/ASSISTANT_SOCIAL.
Origine¶
Avant de commencer les tests, discussion avec Bernard sur le cas d'auto-validation (un MEAL qui crée un enregistrement peut-il le valider lui-même ?) a révélé un principe non respecté par le code : la mise en œuvre des sous-activités (et le suivi/accompagnement) est exclusivement réservée aux agents de terrain — MEAL ne fait que le contrôle qualité (validation/demande de correction).
2026-07-11 02:37 — Bug RBAC trouvé et corrigé avant de commencer¶
Audit de prisma/seeds/seed.ts : mealCommunal = [...agentTerrain, ...'_VALIDER'] — MEAL_COMMUNAL
héritait littéralement de toutes les permissions de création des agents de terrain
(ENFANT_CREER, ACCOMPAGNEMENT_CREER, SUIVI_CREER, CAS_ORIENTE_CREER, les 4 *_GERER de
volets, ACTEUR_CREER/MODIFIER, FORMATION_CREER, SUPPORT_GERER, INSERTION_CREER,
COMITE_GERER). MEAL_NATIONAL avait une variante plus légère du même problème
(*_GERER de volets, INSERTION_MODIFIER, COMITE_GERER, CONCERTATION_GERER).
Corrigé : les deux profils ne gardent que *_LIRE/*_VALIDER + les permissions propres au métier
MEAL (INDICATEUR_LIRE/CALCULER/CREER, ETUDE_*, RAPPORT_EXPORTER, EQUIPE_GERER,
ACCES_TOUTES_COMMUNES pour le national). Appliqué en base (script ciblé, seed.ts complet
actuellement cassé par un bug préexistant sans rapport — référence un modèle TypeAccompagnement
supprimé du schéma). MEAL_COMMUNAL : 32 → 18 permissions. MEAL_NATIONAL : 28 → 21 permissions.
Backend redéployé. Commit 03638be.
Conséquence : le cas d'auto-validation devient structurellement impossible (MEAL ne peut plus créer d'enregistrement d'implémentation, donc ne peut jamais en être l'auteur) — pas besoin d'un second palier de validation hiérarchique.
Comptes de test¶
| Compte | Profil | Commune |
|---|---|---|
test.meal.communal@projetesm.test |
MEAL_COMMUNAL | NDALI |
test.meal.commune@projetesm.test |
MEAL_COMMUNAL | KANDI |
test.meal.national@projetesm.test |
MEAL_NATIONAL | toutes |
Mot de passe : TestMeal2026! pour les trois.
Checklist (à confirmer avec Bernard avant de lancer les scripts)¶
- [x] Connexion + reconnaissance MEAL_COMMUNAL
- [x] Workflow de validation : agent de terrain crée, MEAL_COMMUNAL valide/demande correction (Enfants fait — Accompagnements/Formations/Insertion/Mobilisation/Acteurs restent à spot-checker si le temps le permet, le mécanisme générique étant déjà prouvé sur Enfants)
- [x] Vérification du scope commune : MEAL_COMMUNAL (NDALI) ne doit pas pouvoir valider un enregistrement de KANDI et vice-versa
- [x] Confirmation que MEAL_COMMUNAL n'a plus aucun bouton/action de création visible côté frontend (cohérent avec la suppression des permissions)
- [x] Indicateurs (
/pilotage/*) : consultation + déclenchement du calcul automatique - [x] Rapports : export
- [x] Équipe (
EQUIPE_GERER) : création d'agent terrain testée - [x] Connexion + tests MEAL_NATIONAL : mêmes vérifications + scope toutes communes +
étude diagnostique (création/validation) + comités/cadres de concertation (lecture/validation
seulement, plus de
_GERER) - [x] Mon profil (spot-check)
Explicitement exclu : aucune exclusion cette fois (indicateurs inclus, contrairement aux sessions PSYCHOLOGUE/ASSISTANT_SOCIAL).
Journal d'exécution¶
2026-07-11 02:50 — Reconnaissance MEAL_COMMUNAL + 2 bugs frontend trouvés et corrigés¶
Script 16_reconnaissance_meal_communal.mjs. Connexion test.meal.communal@projetesm.test (NDALI)
réussie, tableau de bord + 10 routes accessibles sans erreur (Enfants, Formations, Insertion,
Mobilisation, Pilotage ×4, Rapports, Mon équipe).
Conséquence directe de la correction RBAC ci-dessus, 2 bugs frontend trouvés :
- Boutons de création visibles à tort : "+ Enregistrer un enfant" (EnfantsPage.tsx) et
"+ Nouvelle formation" (FormationsPage.tsx) restaient affichés à MEAL_COMMUNAL alors qu'il n'a
plus ENFANT_CREER/FORMATION_CREER — un vrai clic aurait mené à un formulaire rempli pour rien,
rejeté au clic sur soumettre (403). Corrigé : gating par rôle (ROLES_PEUT_CREER_ENFANT/
ROLES_PEUT_CREER_FORMATION, pattern déjà utilisé ailleurs dans le code pour l'accès aux routes).
Constat plus large : le frontend n'a aucune vérification de permission fine au sein d'une page —
à surveiller sur les prochains modules testés (Accompagnements, Insertion, Acteurs, Mobilisation).
- Bruit console (403 silencieux) : FormationsPage chargeait la liste des éducateurs pairs
(useEducateurs(), requiert SUPPORT_GERER) dès l'affichage de la page, pas seulement à
l'ouverture du modal de création — 403 en console pour MEAL_COMMUNAL. Corrigé en ajoutant un
paramètre enabled à useEducateurs(), activé seulement quand le modal est réellement ouvert
(bénéfice general : évite aussi un fetch inutile pour les agents de terrain).
Vérifié : tsc --noEmit 0 erreur, script relancé après HMR — les 2 boutons ont disparu, plus
aucune erreur console ni requête en échec sur les 10 routes.
Bug additionnel du même type trouvé en marge : le sous-menu de la sidebar contenait un lien direct
"Enregistrer un enfant" (/enfants/nouveau) sans restriction de rôle — corrigé (roles:
ROLES_PEUT_CREER_ENFANT sur cette entrée), seul cas de ce genre dans toute la sidebar (vérifié :
aucune autre section n'a de raccourci de création direct en sous-menu).
2026-07-11 03:14 — Workflow de validation croisé validé (tâche phare)¶
Script 17_workflow_validation_meal.mjs, un contexte navigateur par persona (évite les collisions
de session lors des connexions successives dans un même script). test.agent@projetesm.test crée
2 enfants ; test important : son communeCode réel en base est KANDI (pas NDALI comme documenté
dans create-comptes-test.ts — a dû changer lors d'une session précédente, seed non mis à jour).
Basculé sur test.meal.commune@projetesm.test (KANDI) plutôt que test.meal.communal (NDALI) pour
matcher la commune réelle.
- Bouton "Valider" visible et fonctionnel pour MEAL_COMMUNAL →
statutValidation: VALIDE,idValidateur/dateValidationrenseignés (vérifié en base). - Bouton "Demander une correction" (modale + commentaire obligatoire) fonctionnel →
statutValidation: A_CORRIGER. - Vérification cross-agent : les 2 enfants restent visibles côté
test.agentavec leur nouveau statut.
Aucune erreur, aucune requête en échec. Le cœur du métier MEAL (contrôle qualité) fonctionne de bout en bout.
2026-07-11 03:22 — Scope commune étanche dans les deux sens¶
Script 18_scope_commune_meal.mjs. test.meal.communal@projetesm.test (NDALI) ne voit pas les
enfants créés en commune KANDI (recherche → "Aucun enfant trouvé"). Inversement,
test.meal.commune@projetesm.test (KANDI) ne voit pas un enfant créé en NDALI par
psychologue.test@esm.local. Cohérent avec ServiceAutorisationDonnees.construireScopeCommune()
(filtre au niveau du listing lui-même, pas seulement au niveau de l'action de validation) — un
MEAL_COMMUNAL d'une commune ne peut même pas voir les données d'une autre, à plus forte raison
les valider. Aucune erreur, aucune requête en échec.
2026-07-11 03:35 — Bug réel trouvé sur /pilotage/mesures : IR2.1.2 + fuite d'erreur technique¶
Script 19_indicateurs_pilotage_meal.mjs. Statistiques/Cumul/Indicateurs de suivi OK. Au clic sur
"Recalculer les indicateurs", 1 échec visible directement dans l'interface : le message d'erreur
Prisma brut ("Unknown argument accompagnement...") s'affichait tel quel dans la carte de résultat,
lisible par n'importe quel MEAL — exactement le genre de surprise que la simulation réelle doit
attraper avant la production.
Cause : comptageCasOrientes() (RegistreCalculateursIndicateurs.ts, IR2.1.2) filtrait encore via
accompagnement.enfant.communeCode — chemin obsolète depuis le retrait du module Accompagnements
générique (commit ec7447f, avant cette session). CasOriente a désormais une relation directe
enfant (prisma/schema.prisma:315). Corrigé : filtre enfant: { communeCode }.
Corrigé aussi la fuite : le use case renvoyait error.message (donc la structure Prisma interne)
telle quelle dans la réponse API. Le détail technique reste dans les logs serveur uniquement ;
l'API renvoie désormais un code générique ERREUR_CALCUL.
Vérifié après redéploiement : 37 indicateurs calculés / 0 échec (contre 36/1 avant), plus aucun texte technique affiché.
2026-07-11 03:44 — Bug bloquant trouvé sur "Mon équipe" : création d'agent impossible¶
Script 20_rapports_equipe_meal.mjs. Rapports OK. Sur "Mon équipe" (EQUIPE_GERER — MEAL crée les
comptes PSYCHOLOGUE/ASSISTANT_SOCIAL de son équipe), le formulaire "+ Ajouter un agent" refusait
systématiquement la soumission avec "Requis" sur les 4 champs (Prénom/Nom/Email/Mot de passe)
alors qu'ils étaient visiblement remplis — aucune requête réseau n'était même envoyée (bloqué
côté client). Diagnostic confirmé par script Playwright dédié : input[name="prenom"] contenait
bien "E2E" (inputValue() vérifié) mais handleSubmit de react-hook-form rejetait quand même.
Cause : MonEquipePage.tsx utilisait <Input {...register('prenom', {...})} /> — spreadant l'objet
register() (qui contient ref) directement en props sur le composant wrapper Input, qui
n'est pas enveloppé par React.forwardRef. Le ref de react-hook-form (nécessaire pour lire la
valeur réelle du DOM au submit) était donc silencieusement perdu à la frontière du composant —
seul name/onChange arrivaient jusqu'au vrai <input>, pas ref. RHF considérait donc les
champs comme jamais montés/vides, d'où "Requis" permanent. Input expose déjà une prop register
dédiée (register={register(...)}, qui elle spread correctement sur le <input> natif interne) —
jamais utilisée nulle part dans le code avant ce bug. Seul fichier concerné (vérifié par recherche
globale du pattern <Input {...register() : MonEquipePage.tsx, 4 occurrences corrigées.
Bug bloquant réel pour MEAL (et vraisemblablement ADMIN/SUPER_ADMIN, mêmes rôles sur cette page) : personne ne pouvait créer de compte agent terrain via cette page avant ce correctif. Vérifié après HMR : agent créé avec succès, visible dans la liste, aucune erreur.
2026-07-11 03:48 — Mon profil MEAL_COMMUNAL (spot-check)¶
Script 21_mon_profil_meal.mjs. Page /profil chargée sans erreur pour
test.meal.commune@projetesm.test, commune (KANDI) correctement affichée. Confirme que le bug
racine téléphone/communeCode (corrigé lors de la session PSYCHOLOGUE) tient aussi pour un profil
MEAL. Fin de la partie MEAL_COMMUNAL de cette session — bascule sur MEAL_NATIONAL.
2026-07-11 03:55 — Reconnaissance MEAL_NATIONAL¶
Script 22_reconnaissance_meal_national.mjs. Connexion test.meal.national@projetesm.test
réussie. Scope national confirmé : voit des enfants de plusieurs communes sans restriction
(ACCES_TOUTES_COMMUNES), filtre "Toutes les communes" disponible. Comme MEAL_COMMUNAL, aucun
bouton de création visible (cohérent, mêmes permissions retirées). Aucune erreur.
2026-07-11 04:05 — Étude diagnostique : 2 bugs trouvés et corrigés + boutons Mobilisation¶
Script 23_etudes_comites_meal_national.mjs. Bouton "+ Nouvelle étude" visible pour MEAL_NATIONAL
(a bien ETUDE_CREER). Premier essai de création (sans remplir "Communes") : erreur technique
brute affichée dans le modal — "Array must contain at least 1 element(s)" (message Zod par
défaut, en anglais, jamais traduit). Le champ n'avait par ailleurs aucun * alors qu'il est
réellement requis côté backend (communes: z.array(...).min(1)).
Corrigé :
- Backend (pilotage.schemas.ts) : message Zod personnalisé en français sur CreerEtudeSchema et
ModifierEtudeSchema ("Au moins une commune est requise").
- Frontend (PilotagePage.tsx) : schéma local aligné (communes devient requis côté client aussi,
pas seulement optionnel), label avec *, erreur affichée sous le champ — la validation bloque
désormais la soumission avant même d'atteindre le backend, avec un message clair.
Même passage, 2 bugs supplémentaires du même type que ceux déjà corrigés côté MEAL_COMMUNAL
trouvés par lecture de code (boutons de création non gatés par rôle) :
- OngletsEtudes : "+ Nouvelle étude" et "Supprimer" (études) visibles sans condition — hors
MEAL_NATIONAL/ADMIN/SUPER_ADMIN (seuls titulaires de ETUDE_CREER, qui gate aussi DELETE côté
backend), n'importe quel rôle avec accès à la page (dont MEAL_COMMUNAL) les voyait. Gatés avec
ROLES_PEUT_CREER_ETUDE.
- MobilisationPage.tsx : les 5 boutons de création (comités, cadres, sessions parole, activités
cohésion sociale, actions de plaidoyer) n'étaient gatés par aucun rôle — confirmé pour
MEAL_NATIONAL sur comités/cadres (count=0 après correction, count=1 avant). Gatés avec
ROLES_PEUT_GERER_MOBILISATION (= titulaires réels de COMITE_GERER/CONCERTATION_GERER en
base : PSYCHOLOGUE, ASSISTANT_SOCIAL, ADMIN, SUPER_ADMIN — vérifié en base, pas dans le seed.ts
qui s'est révélé désynchronisé sur ce point aussi, cf. note ci-dessous).
Un 6e bouton du même module ("+ Nouvelle session" pour ajouter une réunion à un comité déjà
ouvert, dans le détail d'un comité) reste non corrigé faute de variable peutGerer déjà
disponible à cet endroit imbriqué — à traiter si retesté explicitement.
Constat additionnel : prisma/seeds/seed.ts est désynchronisé de la réalité en base non
seulement sur TypeAccompagnement (déjà noté) mais aussi sur les permissions agentTerrain —
PSYCHOLOGUE/ASSISTANT_SOCIAL ont en base CONCERTATION_GERER, INSERTION_MODIFIER,
RAPPORT_EXPORTER que le tableau agentTerrain du seed ne liste pas (ajoutés lors d'une session
antérieure via script ciblé, jamais reportés dans le seed). Le seed ne doit donc plus être considéré
comme source de vérité tant qu'il n'a pas été remis à niveau — vérifier toujours la base réelle.
Vérifié après redéploiement backend + HMR frontend : création d'étude avec communes réussie, étude
visible dans la liste, boutons comités/cadres absents pour MEAL_NATIONAL, tsc --noEmit 0 erreur.
Conclusion¶
Chantier terminé pour les deux profils MEAL_COMMUNAL et MEAL_NATIONAL. Bilan :
Bug RBAC de fond (avant même de commencer)¶
MEAL héritait à tort de toutes les permissions de création des agents de terrain (seed.ts :
mealCommunal = [...agentTerrain, ...]), contredisant le principe métier : la mise en œuvre des
sous-activités appartient exclusivement aux agents de terrain, MEAL ne fait que le contrôle
qualité. Corrigé en base (MEAL_COMMUNAL 32→18 permissions, MEAL_NATIONAL 28→21).
Conséquences en cascade — 6 bugs frontend/backend trouvés et corrigés¶
- Boutons "+ Enregistrer un enfant"/"+ Nouvelle formation" visibles à tort (Enfants, Formations).
- Fetch inutile des éducateurs pairs générant un 403 silencieux en console (Formations).
- Raccourci sidebar "Enregistrer un enfant" non filtré par rôle.
- Bug de calcul IR2.1.2 (chemin Prisma obsolète post-refactor Accompagnements) + fuite du message d'erreur technique brut dans l'interface Pilotage.
- Bug bloquant : formulaire "Mon équipe" (création d'agent terrain) rejetait systématiquement
la soumission ("Requis" sur tous les champs pourtant remplis) —
<Input>non enveloppé parReact.forwardRef,refde react-hook-form perdu à la frontière du composant. Personne ne pouvait créer de compte agent avant ce correctif. - Champ "communes" de l'étude diagnostique réellement requis côté backend mais optionnel et sans astérisque côté frontend, message d'erreur Zod brut en anglais affiché à l'utilisateur + boutons de création non gatés sur Pilotage (études) et Mobilisation (5 boutons : comités, cadres, sessions parole, activités cohésion, plaidoyer).
Validé et fonctionnel de bout en bout¶
- Workflow de validation croisé (tâche phare) : agent de terrain crée, MEAL valide ou demande une correction — testé avec un vrai aller-retour cross-agent et vérifié en base.
- Scope commune étanche dans les deux sens (MEAL_COMMUNAL) et accès toutes communes fonctionnel
(MEAL_NATIONAL,
ACCES_TOUTES_COMMUNES). - Indicateurs/Pilotage : consultation + calcul automatique (37/37 après correctif IR2.1.2).
- Mon équipe : création d'agent terrain (après correctif).
- Étude diagnostique : création avec communes (après correctif).
- Mon profil : spot-check OK pour les deux profils.
Limitations connues¶
prisma/seeds/seed.tsest désynchronisé de la réalité en base sur au moins deux points (TypeAccompagnementsupprimé du schéma, permissionsagentTerrainincomplètes) — ne plus le considérer comme source de vérité sans vérification en base.
2026-07-11 07:47 — Correctif complémentaire : 4 boutons Mobilisation non gatés (pas seulement 1)¶
Bernard a demandé la correction du "6e bouton" documenté ci-dessus (relance de session) — toujours
d'actualité au moment de la demande. En le corrigeant, 3 boutons supplémentaires du même défaut
ont été trouvés par lecture de code dans les panneaux de détail (comité/cadre ouverts) : Supprimer
sur une réunion/session, + Ajouter un membre et Retirer sur les listes de membres — tous gatés
par COMITE_GERER/CONCERTATION_GERER côté backend, aucun gating côté frontend. Corrigés dans
ReunionsPanel, SessionsConcertationPanel, MembresPanel, MembresCadrePanel (ajout de
peutGerer via useAuth(), même pattern ROLES_PEUT_GERER_MOBILISATION que les 5 boutons de tab
déjà corrigés). Vérifié en conditions réelles avec test.meal.commune@projetesm.test sur un comité
KANDI existant : les 4 boutons sont bien absents (tsc --noEmit 0 erreur également).
2026-07-11 07:54 — Cases à cocher de présence corrigées + bug pré-existant découvert¶
Suite (confirmée par Bernard : "corrige aussi"). Cases "Présent"/"Invité" (PresenceReunionModal,
PresenceSessionModal) désormais disabled pour les rôles sans peutGerer (statut toujours
visible, juste non modifiable) ; le formulaire d'ajout de participant externe dans
PresenceSessionModal masqué comme les autres formulaires de création.
Vérification live incomplète : en essayant de créer une réunion réelle (agent terrain) pour
tester les cases à cocher de bout en bout, découverte d'un bug pré-existant sans rapport avec
cette session — CreerReunionSchema/CreerSessionConcertationSchema (backend) exigent
nbPresents/nbAttendus (nombres requis), mais ReunionFormInline/SessionConcertationFormInline
(frontend) ne collectent ni n'envoient ces champs. Résultat : aucune réunion ni session de
concertation n'a jamais été créée avec succès (confirmé : 0 ligne dans ReunionComite et
SessionConcertation en base). Message d'erreur brut ("Required") renvoyé au frontend, même classe
de fuite que le bug IR2.1.2/étude déjà corrigé. Signalé à Bernard, non corrigé — hors périmètre
de la demande initiale, nécessite une décision sur l'origine des nbPresents/nbAttendus (champs
manuels sur le formulaire, ou calcul automatique).
Le correctif des cases à cocher a donc été vérifié par lecture de code (pattern identique aux 9
boutons déjà prouvés fonctionnels dans cette session) plutôt que par un scénario live complet, faute
de pouvoir créer une réunion/session de test. tsc --noEmit 0 erreur.
2026-07-11 08:05 — Bug de création réunion/session corrigé (confirmé sur demande de Bernard)¶
Bernard a confirmé vouloir aussi ce correctif. Cause exacte : CreerReunionSchema/
CreerSessionConcertationSchema exigeaient nbPresents/nbAttendus (et
nbParticipantsPresents/nbParticipantsAttendus) comme champs obligatoires, alors que ces valeurs
sont recalculées automatiquement à chaque ajout/modification de présence
(ajouterPresenceAvecRecalcul) — le frontend ne les envoie jamais. Corrigé en leur donnant un défaut
de 0 (cohérent avec decisionsCount/decisionsAppliquees, déjà à 0 par défaut).
Premier test après ce correctif : toujours 500 ("Argument nbPresents is missing"). Deuxième bug
du même type que CreerSuiviUseCase déjà rencontré sur ce projet : CreerReunionUseCase et
CreerSessionConcertationUseCase appelaient executerLogique(donnees) avec les données brutes du
handler au lieu de validation.donnees (résultat Zod transformé) — les .default(0) n'avaient donc
aucun effet. Corrigé pour utiliser validation.donnees!.
Conséquence : aucune réunion de comité ni session de concertation n'avait jamais pu être créée
depuis l'existence de ces modules (0 ligne en base avant ce correctif). Vérifié de bout en bout :
réunion créée avec succès (201) sur un comité KANDI, puis sur un comité NDALI avec 1 membre inscrit
— case à cocher de présence confirmée présente et bien désactivée pour
test.meal.communal@projetesm.test. tsc --noEmit 0 erreur, backend redéployé.
2026-07-11 08:26 — Vérification côté cadre de concertation + bug supplémentaire (genre "")¶
Bernard a demandé la même vérification côté cadre de concertation (pas seulement comité). En
ajoutant un membre au cadre "COMMUNAL" (NDALI, seul cadre existant) pour le tester, nouveau bug
trouvé : Invalid enum value. Expected 'MASCULIN' | 'FEMININ', received '' — les 3 selects "Genre"
(membre de comité, membre de cadre, participant externe à une session) envoyaient une chaîne vide
"" par défaut (valeur HTML native du <option value="">) au lieu d'undefined, rejetée par les
schémas Zod backend (.optional() accepte l'absence du champ, pas une chaîne vide invalide pour un
enum). Corrigé sur les 3 points (genre || undefined avant l'appel API).
Vérifié de bout en bout : membre ajouté au cadre (201), session déjà créée plus haut, présence
ajoutée par l'agent pour ce membre (201) — côté test.meal.communal@projetesm.test, les 2 cases
"Invité"/"Présent" du membre sont bien visibles (statut lisible) mais désactivées, et le formulaire
d'ajout de participant externe est absent. tsc --noEmit 0 erreur.
8 scripts Playwright créés pour cette session (16_* à 23_*), conservés dans Test_E2E/ comme
convenu, aucun supprimé.