356 lignes couvrant ce qui a été livré sur manager-app et jamais ouvert dans un navigateur : écran Guide IA, éditeur de parcours refondu, écran d'audit log, compteur d'utilisateurs, compression des images. Le fichier n'était pas suivi par git — un add explicite ne l'avait jamais vu, et il serait resté sur un seul disque. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
18 KiB
Plan de test — manager-app (modifications du 2026-08-09 au 2026-08-12)
Périmètre : les 8 commits livrés entre le 9 et le 12 août 2026 sur manager-app.
Rien ici n'a été vérifié à l'œil dans un navigateur — c'est justement l'objet de ce document.
Mode d'emploi : coche la case si le comportement attendu est constaté, laisse-la vide sinon
et note l'écart sur la ligne. → = résultat attendu.
Commits couverts :
| Réf | Commit | Sujet |
|---|---|---|
| §1 | eb8e849 |
Socle visuel (constants.dart) |
| §2 | bb4d4fe eb8e849 |
Guide IA — 2 onglets |
| §3 | bb4d4fe |
Statistiques refondues + export PDF |
| §4 | bb4d4fe |
Onboarding self-service (auth, abonnement, quota IA) |
| §5 | b39854a |
DB4 — éditeur de parcours unifié |
| §6 | bb4d4fe |
Mode de progression du parcours |
| §7 | 5066b6c |
Lot E — PDF en média d'étape, QuestionType |
| §8 | 762448c |
Lot F — écran Activité + compteur d'utilisateurs |
| §9 | 608231f |
C4 — compression des images à l'upload |
| §10 | 9d9f4bc |
Nettoyage du client généré |
| §11 | — | i18n FR / EN / NL et non-régression |
§0. Porte d'entrée
flutter build webpasse sans erreurflutter analyzene remonte que les 3 problèmes connus detest/widget_test.dart- Connexion, sélection d'instance, chargement du menu latéral → aucun écran blanc
§1. Socle visuel
Le socle (11 rôles typo, 8 espacements, 5 rayons) n'est appliqué que sur les écrans neufs : Guide IA, Statistiques, Activité. Le reste de l'app garde son style d'origine — c'est voulu.
- Les écrans Guide IA / Statistiques / Activité utilisent la même palette que le reste de l'app (pas de seconde identité visuelle)
- Titres, sous-titres et cartes cohérents entre ces trois écrans
- En 1280 px de large : pas de débordement horizontal, pas de texte tronqué
- En ~900 px (fenêtre réduite) : les cartes passent en colonne au lieu de se compresser
§2. Guide IA
Menu conditionné à isAssistant (même drapeau que la garde d'AiController).
2.1 Accès
- Instance avec assistant activé → l'entrée « Guide IA » apparaît dans le menu
- Instance sans assistant → l'entrée est absente
2.2 Onglet « Configuration »
- Les deux onglets sont visibles et basculent sans rechargement
- Persona : saisie puis « Enregistrer » → message de succès, valeur retrouvée après F5
- Réponses de repli : ajout, modification, suppression d'une ligne
- Wakeword vocal affiché avec le nom configuré
- Carte « Ce que connaît votre guide » (
GET /api/Ai/knowledge/{id}) : le nombre de morceaux de contenu s'affiche - Une section désactivée puis réindexée → le compteur baisse (l'index vectoriel est la source, pas les tables de contenu)
- Bouton de réindexation : lancement, retour visible, pas de double envoi si on reclique
- Aperçu de conversation : une question envoyée reçoit une vraie réponse (
POST /api/AI/chat, pas une simulation) - Aperçu avec des modifications non enregistrées → mention « non enregistré » affichée
- Échec réseau sur l'enregistrement → snackbar rouge, la saisie n'est pas perdue
2.3 Onglet « Ce que demandent vos visiteurs »
Alimenté par GET /api/Ai/insights/{id}. L'endpoint backend n'existe peut-être pas encore :
si c'est le cas, seul le premier point ci-dessous s'applique, le reste est à rejouer après livraison.
- Aucune donnée / endpoint absent → état vide illustré (icône + texte), pas de cadre creux ni d'erreur
- Avec des données : les 4 tuiles (questions, sans réponse, thèmes, langues) affichent les bons totaux
- La tuile « sans réponse » est en ambre, les trois autres en encre normale
- Bloc ambre « questions sans réponse » listé avec le compteur
n ×à droite - Une carte dont la liste est vide (thèmes non encore regroupés) est masquée, pas affichée vide
- Barres : la plus longue correspond bien à la valeur la plus haute, une seule teinte par carte
- > 1100 px : les cartes sont côte à côte ; en dessous : empilées
- Note de confidentialité affichée en bas
§3. Statistiques — écran « Fréquentation »
⚠️ Écran réécrit (+1832 lignes) et jamais ouvert dans un navigateur avant ce test.
3.1 Chargement et filtres
- Instance sans droit statistiques → message « indisponible » explicite (pas d'écran vide)
- Erreur réseau → message d'erreur avec icône, pas de spinner infini
- Instance sans aucune donnée → message « pas de données »
- Sélecteur de période : 7 / 30 / 90 / 365 jours → la plage de dates affichée en sous-titre suit
- Filtre canal : « Tous » + un bouton par canal (Mobile / Tablette / Web / VR / Voix)
- Chaque bouton de canal affiche son volume
- Un canal sans donnée sur la période est absent ou inactif
- Filtre sur un canal unique → message « pas de données pour ce type » si le canal est vide
- Retour à « Tous » → les valeurs redeviennent celles du total
3.2 KPI et bandeau
- 4 KPI affichés : visites, durée moyenne, contenus par visite, et part vocale ou vues totales
- Chaque KPI porte sa variation vs période précédente (flèche + %)
- Variation nulle → « stable » avec l'icône neutre, pas « 0 % »
- Les variations sont cohérentes : passer de 30 à 7 jours change les chiffres ET les variations
- Bandeau « à retenir » : phrases cohérentes avec les chiffres affichés au-dessus
- Durée :
1 min 30 sau-delà de 60 s,45 sen dessous
3.3 Courbe et tableaux
- Courbe en aire des visites par jour, un point par jour de la période
- Bandes de week-end visibles et alignées sur les bons jours (vérifier un samedi précis)
- Jour de pic annoté avec la bonne date et la bonne valeur
- Barres horizontales : top contenus, canaux, langues
- Tableaux détaillés : POI, agenda, quiz, jeux, articles, menu — un tableau vide est masqué
- Les totaux des tableaux ne contredisent pas les KPI
3.4 Export PDF
- Bouton d'export → le PDF se télécharge
- Nom du fichier : nom d'instance + intitulé + date
- Les chiffres du PDF sont identiques à ceux de l'écran (KPI, pic, tops) — c'est le point critique
- La plage de dates du PDF correspond au filtre actif
- Export avec un filtre canal actif → le PDF reflète ce filtre
- Le sommaire ne promet pas de données inexistantes (parcours terminés, questions au guide IA)
- Échec de génération → snackbar rouge, l'écran reste utilisable
- Export sur une période sans données → soit bouton désactivé, soit PDF cohérent (à noter selon le constat)
§4. Onboarding self-service
⚠️ Aucun parcours joué de bout en bout avant ce test.
4.1 Mot de passe oublié
- Lien « mot de passe oublié » accessible depuis l'écran de connexion
- E-mail inconnu → message neutre (pas de fuite d'existence de compte)
- E-mail connu → confirmation d'envoi
- Le mail arrive et son lien ouvre l'écran de définition du mot de passe
4.2 Définition du mot de passe
- Lien valide → formulaire affiché
- Lien expiré ou déjà consommé → message clair, pas d'erreur technique brute
- Mot de passe trop court / confirmation différente → erreur de validation avant envoi
- Définition réussie → redirection vers la connexion, connexion effective avec le nouveau mot de passe
4.3 Écran Abonnement
- Entrée « Abonnement » présente dans le menu
- Période d'essai en cours → « essai actif » + date de fin correcte
- Essai sans date de fin → texte de repli, pas de date vide ni de
null - Plan payant actif → intitulé et description du plan
- Liste « inclus dans votre plan » cohérente avec le plan réel de l'instance
- Bouton de montée en gamme → ouvre bien la page cible dans un nouvel onglet
- Section modules complémentaires → mention « bientôt disponible »
4.4 Indicateur de quota IA
- Sous le bouton « Traduire via IA » :
Quota IA : X / Y utilisés ce mois - Plan sans plafond (quota = 0) → « Quota IA : illimité »
- ≥ 80 % → texte orange + gras + mention « partagé avec l'assistant visiteur »
- ≥ 95 % → texte rouge
- Après une traduction, le compteur se met à jour (il ne se rafraîchit que si la clé change — à vérifier)
- Endpoint quota en échec → rien ne s'affiche, la traduction reste possible
§5. Éditeur de parcours unifié (DB4)
Les trois anciennes fenêtres (showNewOrUpdateGuidedPath / GuidedStep / QuizQuestion) sont supprimées.
Profondeur maximale attendue : 2 surfaces (l'éditeur, puis la traduction).
5.1 Structure
- Ouverture d'un parcours → une seule fenêtre : rail d'étapes à gauche, détail à droite
- Ajouter une question → elle se déplie sur place, aucune fenêtre supplémentaire
- Traduire un champ → la fenêtre de traduction est la seule surface superposée
- Fenêtre large (≈ 1180 px max) et centrée, pas de barre de défilement horizontale
5.2 Sauvegarde au fil de l'eau
Il n'y a plus de bouton « Sauvegarder », et plus d'avertissement de perte de travail (garde-fou retiré volontairement).
- Saisie dans un champ → écriture partie ~700 ms après la dernière frappe (vérifier dans l'onglet Réseau)
- Frappe continue → une seule requête à la fin, pas une par caractère
- Ajout / suppression / réordonnancement d'étape → écriture immédiate, sans attendre le débounce
- Fermer la fenêtre juste après une frappe → la dernière saisie est bien enregistrée (purge à la fermeture)
- F5 après édition → tout est retrouvé
- Ouvrir une fenêtre neuve puis la refermer sans rien toucher → aucun parcours créé en base
- Première modification sur une fenêtre neuve → le parcours est créé à ce moment-là
5.3 Erreurs et fermeture
- Backend coupé pendant l'édition → la fenêtre refuse de se fermer, un « Réessayer » apparaît en pied de page
- Backend rétabli + « Réessayer » → l'écriture passe et la fermeture devient possible
- Retour arrière du navigateur pendant l'édition → passe par la même fermeture (rien n'est perdu)
- Suppression d'étape → demande de confirmation
- Confirmation refusée → l'étape reste, aucune requête partie
5.4 Pièges backend à vérifier en base
- Ajouter deux étapes d'affilée → pas de doublon en base (les étapes sans id partent par
CreateGuidedStep) - Créer une question, fermer, rouvrir → la question a le bon id et n'est pas dupliquée
- Réordonner puis ajouter une question → la question reste rattachée à la bonne étape (récupération de l'id par
order) - Supprimer une étape du milieu → les
orderdes suivantes sont recalculés
5.5 Les deux hébergements du parcours
- Parcours sous une SectionParcours : création, édition, suppression
- Parcours sous une SectionMap : mêmes opérations, même comportement
- Aucun écart de comportement entre les deux
§6. Mode de progression du parcours
3 questions au lieu des 9 booléens précédents.
- Trois modes proposés : Libre / Dans l'ordre / Étape par étape, chacun avec sa description
- Un parcours existant s'ouvre sur le mode correspondant à ses booléens actuels
- « Libre » → en base :
isLinear = false,requireSuccessToAdvance = false,hideNextStepsUntilComplete = false - « Dans l'ordre » →
isLinear = true,requireSuccessToAdvance = false - « Étape par étape » →
isLinear = true,requireSuccessToAdvance = true - Aller-retour entre deux modes puis rechargement → le mode affiché est celui choisi
- Le comportement côté visitapp correspond au mode choisi (test croisé, cf.
test-plan.md§19.13)
§7. Lot E — médias d'étape et types de question
- Média d'une étape de parcours : le sélecteur propose Image, Vidéo, Audio et PDF
- Média d'un slider : la liste est inchangée (pas de PDF)
- PDF sélectionné sur une étape → enregistré, retrouvé après rechargement
- Types de question : Simple / Choix multiple / Puzzle correctement libellés (plus de
number0/1/2) - Changer le type d'une question existante → les champs affichés suivent le type
- Une question Puzzle enregistrée se rouvre bien en Puzzle
- Champ « fournisseur de carte » toujours présent, présenté comme réglage mobile/tablette (visitapp-web reste sur Leaflet)
§8. Lot F — Activité et utilisateurs
8.1 Accès à l'écran Activité
- SuperAdmin → entrée « Activité » visible dans le menu (icône historique)
- InstanceAdmin → entrée absente
- Utilisateur standard → entrée absente
- Passer de SuperAdmin à un autre rôle sans recharger → l'entrée disparaît
8.2 Journal
- Liste chargée avec colonnes : date, instance, entité, action, utilisateur, id d'entité
- Actions traduites (Créer / Modifier / Supprimer), pas les valeurs brutes
- Entités traduites (Section, Ressource, Configuration, Device, Utilisateur)
- Ids d'instance et d'utilisateur résolus en noms
- Un id qui ne correspond plus à rien (entité supprimée) reste affiché tel quel, sans casser la ligne
- Clic sur une ligne → détail avant/après en table, pas de JSON brut
- Une création (pas de valeur « avant ») s'affiche proprement
- Journal vide → message dédié
- Erreur backend → message d'erreur, pas de spinner infini
8.3 Filtres et pagination
- Filtre instance
- Filtre type d'entité
- Filtre utilisateur
- Filtres de date « du » / « au »
- Combinaison de plusieurs filtres → résultats cohérents
- Tout changement de filtre ramène à la page 1
- « Réinitialiser les filtres » vide aussi l'affichage des listes déroulantes (c'était le bug corrigé)
- Pagination 50 : suivant / précédent, compteur « X–Y sur Z » exact
- Bouton précédent inactif en page 1, suivant inactif en dernière page
8.4 Compteur d'utilisateurs
- Écran Utilisateurs : compteur « X / 5 » affiché
- À 5 utilisateurs → bouton d'ajout désactivé
- SuperAdmin → pas de compteur ni de blocage (sa liste couvre toutes les instances)
- Création avec un e-mail déjà utilisé (409) → snackbar rouge avec le message serveur
- Création avec un rôle refusé (403) → snackbar rouge
- Création valide → utilisateur ajouté à la liste
- InstanceAdmin → le rôle SuperAdmin n'est pas proposé dans la liste des rôles
Dettes serveur connues, hors périmètre de ce test : le plafond de 5 n'est pas appliqué par
UserController(un POST direct passe), et aucune section n'est journalisée dans l'audit.
§9. C4 — compression des images à l'upload
Règle : redimensionnement à 2560 px sur le côté long, JPEG q82 — sauf PNG à canal alpha qui reste PNG.
- Upload d'un JPEG de 6000 px → l'image stockée fait 2560 px sur son côté long
- Photo en portrait → c'est bien la hauteur qui est ramenée à 2560, pas la largeur
- Le poids affiché dans la liste des ressources correspond au fichier compressé, pas à l'original
- PNG avec transparence → reste un PNG, transparence intacte (pas de fond noir)
- PNG sans transparence → ressort en JPEG, et le type MIME suit (vérifier le
Content-Typeservi par Firebase) - Petite image déjà bien encodée → l'original est conservé (pas de fichier plus lourd qu'avant)
- Fichier image corrompu → l'upload passe quand même avec l'original, pas de blocage
- Fichier non image (PDF, vidéo, audio) → aucun traitement, upload inchangé
- Les deux chemins d'upload (création de ressource et ajout de fichier) compressent identiquement
- Le quota de stockage augmente de la taille compressée, pas de la taille d'origine
- Le second chemin d'upload renseigne désormais
sizeBytes(avant : 0 octet au quota) - Upload multiple de plusieurs images → toutes compressées, aucune perdue
Les ressources créées avant ce commit par le second chemin comptent 0 octet au quota : c'est l'existant, il attend le backfill C2 — ne pas le noter comme une régression.
§10. Nettoyage du client généré
flutter analyze manager_api_new: 3 avertissements légitimes, plus les 67 d'avantlib/api/openApiTest.darta bien disparu (le déclencheur de génération est verrouillé)- Aucun écran ne casse à cause d'un modèle supprimé (statistiques, carte, utilisateurs surtout)
tablet-appcompile toujours avec ce clientmymuseum-visitappcompile toujours avec ce client- Le mapping
isGood→isCorrectdes QCM est toujours en place
§11. i18n et non-régression
11.1 Langues
- Sélecteur de langue dans le menu latéral : FR / EN / NL
- Changement de langue → l'interface bascule immédiatement, sans rechargement
- La langue est conservée après F5
- Guide IA : aucune clé manquante en EN, aucune en NL
- Statistiques : idem
- Activité : idem (40 clés ajoutées au lot F)
- Éditeur de parcours : idem (14 clés ajoutées, 3 retirées)
- Aucun texte du type
guideIaXxxouauditXxxaffiché brut à l'écran - En NL et EN, les libellés longs ne débordent pas des boutons et des cartes
11.2 Écrans non touchés (contrôle rapide)
- Configurations : ouverture, édition, enregistrement d'une section de chaque type
- Ressources : liste, filtre, suppression
- Applications / liaison configuration : aperçu bento toujours fonctionnel
- Devices kiosk
- Clés API
- Notifications push
- Déconnexion / reconnexion
Écarts constatés
| § | Ce qui a été observé | Gravité |
|---|---|---|