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>
357 lines
18 KiB
Markdown
357 lines
18 KiB
Markdown
# 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 web` passe sans erreur
|
||
- [ ] `flutter analyze` ne remonte que les 3 problèmes connus de `test/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 s` au-delà de 60 s, `45 s` en 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 `order` des 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-Type` servi 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'avant
|
||
- [ ] `lib/api/openApiTest.dart` a 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-app` compile toujours avec ce client
|
||
- [ ] `mymuseum-visitapp` compile toujours avec ce client
|
||
- [ ] Le mapping `isGood` → `isCorrect` des 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 `guideIaXxx` ou `auditXxx` affiché 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é |
|
||
|---|---|---|
|
||
| | | |
|
||
| | | |
|