- Ajoute privacy-policy-v1.md et release-compliance-checklist.md - Ajoute documents QA gates #238-#243 - Ajoute scripts de validation repo-only et device runbooks - Prépare checklists exécutables avant upload Play fermé Ticket #261
630 lines
18 KiB
Markdown
630 lines
18 KiB
Markdown
# Ticket #238 — Cadrage QA runnable des features principales
|
|
|
|
## Objectif
|
|
|
|
Ce document sert de base opérationnelle au nouveau process TDD GameTime.
|
|
Il fixe :
|
|
|
|
- l'ordre recommandé de couverture des features majeures
|
|
- les suites attendues par niveau de test
|
|
- la stratégie d'implémentation runnable
|
|
- les commandes cibles à exécuter
|
|
- le backlog initial d'automatisation prioritaire
|
|
|
|
Le principe directeur est simple : verrouiller d'abord les parcours qui portent la valeur produit et les régressions les plus coûteuses, avant d'étendre la couverture device et infra.
|
|
|
|
## Preuves réelles ajoutées le 22 août 2026
|
|
|
|
Preuves exécutées sur `/tmp/gametime-src-1787384228` :
|
|
|
|
- gate `#239` verte
|
|
- gate `#240` verte
|
|
- smoke `#241` vert
|
|
- gate `#242` verte
|
|
- `dart test` serveur vert
|
|
|
|
Conséquence :
|
|
|
|
- le socle QA Flutter transverse est désormais prouvé exécutable
|
|
- le coeur offline Drift est prouvé exécutable
|
|
- la gate monétisation actuellement cadrée est prouvée exécutable
|
|
- la validation device reste distincte et passe par `#243`
|
|
|
|
## Constat repo au 21 août 2026
|
|
|
|
Le dépôt contient déjà une base exploitable :
|
|
|
|
- tests Flutter domaine/application/infrastructure dans `test/application`, `test/infrastructure`, `test/domain_import_boundaries_test.dart`
|
|
- nombreux tests widget écran par écran dans `test/presentation`
|
|
- premier harnais fonctionnel mémoire dans `test/support/functional_harness.dart`
|
|
- première suite fonctionnelle transverse dans `test/functional/functional_coverage_test.dart`
|
|
- suite montre dédiée dans `watch_app/test/presentation`
|
|
- suite serveur Dart dans `server/test`
|
|
- checklist d'intégration réelle infra dans `server/docs/integration-checklist.md`
|
|
|
|
Ce qui manque pour relancer le delivery vers la prod n'est pas une base de tests, mais une hiérarchie claire :
|
|
|
|
- quels parcours servent de gate de non-régression
|
|
- quels niveaux de tests portent chaque feature
|
|
- quelles suites doivent tourner en local, en CI rapide, en CI complète et en validation manuelle scriptée
|
|
|
|
## Convention d'exécution runnable
|
|
|
|
Dans l'environnement actuel, les commandes Flutter et Dart passent en forçant un `HOME` writable et en coupant l'analytics.
|
|
|
|
Convention à utiliser pour les runners locaux et CI :
|
|
|
|
```bash
|
|
export HOME=/tmp
|
|
export XDG_CONFIG_HOME=/tmp
|
|
export FLUTTER_SUPPRESS_ANALYTICS=true
|
|
export DART_SUPPRESS_ANALYTICS=true
|
|
```
|
|
|
|
Preuve minimale vérifiée dans ce ticket :
|
|
|
|
- `flutter test test/functional/functional_coverage_test.dart --plain-name 'builders create readable exercise, program and template scenarios'`
|
|
- `dart test test/health_test.dart` depuis `server/`
|
|
|
|
Ces deux commandes passent avec la convention ci-dessus.
|
|
|
|
## Ordre de couverture recommandé
|
|
|
|
### Lot 1 — Gate prod minimale téléphone offline-first
|
|
|
|
But : garantir que l'app principale remplit sa promesse cœur sans compte ni sync.
|
|
|
|
Features incluses :
|
|
|
|
- bibliothèque d'exercices
|
|
- composition de programmes
|
|
- composition de séances
|
|
- exécution d'une séance
|
|
- enregistrement d'historique
|
|
- reprise d'une séance en cours
|
|
- progression issue de l'historique
|
|
|
|
Pourquoi en premier :
|
|
|
|
- c'est le cœur de la valeur GameTime
|
|
- la plupart des invariants sont déjà testables en mémoire
|
|
- ce lot permet de relancer le développement produit sans attendre l'infra distante
|
|
|
|
### Lot 2 — Variantes métier à fort risque de régression
|
|
|
|
Features incluses :
|
|
|
|
- score manuel
|
|
- score chrono
|
|
- timers de série et de repos
|
|
- séquences d'étapes
|
|
- correction d'une série passée
|
|
- import/export local
|
|
|
|
Pourquoi ensuite :
|
|
|
|
- ces variantes cassent facilement les écrans et les use cases
|
|
- elles demandent des suites de comportement plus transverses que du simple widget isolé
|
|
|
|
### Lot 3 — Compte, sync et partage
|
|
|
|
Features incluses :
|
|
|
|
- profil connecté/déconnecté
|
|
- auth
|
|
- sync
|
|
- boîte de réception des partages
|
|
- partage de programme et de séance
|
|
- import de partage accepté
|
|
|
|
Pourquoi après le lot 1 :
|
|
|
|
- forte dépendance à l'API et à des fixtures serveur
|
|
- besoin de distinguer clairement tests clients mockés, tests serveur réels et smoke end-to-end
|
|
|
|
### Lot 4 — Intégrations gratuites device
|
|
|
|
Features incluses :
|
|
|
|
- Health Connect
|
|
- compagnon montre Android/Wear
|
|
- projection de séance vers la montre
|
|
- télémétrie live montre
|
|
|
|
Pourquoi en quatrième :
|
|
|
|
- important produit, mais plus coûteux à rendre deterministic
|
|
- nécessite émulateurs / devices / bridge natif
|
|
|
|
### Lot 5 — Validation déploiement et packaging
|
|
|
|
Features incluses :
|
|
|
|
- build Android
|
|
- build watch
|
|
- bootstrap serveur Docker/PostgreSQL
|
|
- smoke API réelle
|
|
|
|
Pourquoi en dernier :
|
|
|
|
- ce lot doit s'appuyer sur des fondations fonctionnelles déjà stables
|
|
|
|
## Matrice feature -> suites attendues
|
|
|
|
### 1. Exercices
|
|
|
|
Parcours nominaux :
|
|
|
|
- créer un exercice simple
|
|
- créer un exercice avec reps, temps et score
|
|
- ajouter tags et médias
|
|
- définir une icône média
|
|
- configurer des étapes
|
|
- modifier puis supprimer un exercice
|
|
|
|
Cas limites :
|
|
|
|
- aucune mesure active
|
|
- neuvième étape refusée
|
|
- sixième image refusée
|
|
- étape invalide
|
|
- exercice seedé modifié
|
|
|
|
Suites attendues :
|
|
|
|
- unitaires : validations métier et normalisation
|
|
- intégration : persistance Drift des exercices, tags, médias, étapes
|
|
- widget : formulaire réel et liste filtrable
|
|
- end-to-end/manuel scripté : ajout complet avec média réel sur device
|
|
|
|
Base existante :
|
|
|
|
- `test/presentation/exercise_library_screen_test.dart`
|
|
- `test/infrastructure/drift_repositories_test.dart`
|
|
|
|
### 2. Programmes
|
|
|
|
Parcours nominaux :
|
|
|
|
- créer un programme depuis des exercices existants
|
|
- configurer séries, cibles, repos
|
|
- dupliquer
|
|
- filtrer
|
|
- partager
|
|
|
|
Cas limites :
|
|
|
|
- programme sans exercice
|
|
- exercice snapshot incomplet
|
|
- partage sans compte
|
|
|
|
Suites attendues :
|
|
|
|
- unitaires : construction snapshot et validations de configuration
|
|
- intégration : lecture/écriture repository
|
|
- widget : formulaire, liste, duplication, partage
|
|
- end-to-end/manuel scripté : création puis partage depuis un compte réel
|
|
|
|
Base existante :
|
|
|
|
- `test/presentation/program_screen_test.dart`
|
|
|
|
### 3. Séances / templates
|
|
|
|
Parcours nominaux :
|
|
|
|
- créer une séance avec un ou plusieurs programmes
|
|
- configurer overrides
|
|
- dupliquer
|
|
- lancer depuis la liste
|
|
|
|
Cas limites :
|
|
|
|
- séance sans programme
|
|
- aucune exécution possible
|
|
- legacy invalide non bloquante
|
|
|
|
Suites attendues :
|
|
|
|
- unitaires : résolution des snapshots et overrides
|
|
- intégration : persistance template + programme snapshot
|
|
- widget : création/édition/lancement
|
|
- end-to-end/manuel scripté : création complète puis lancement
|
|
|
|
Base existante :
|
|
|
|
- `test/presentation/workout_template_screen_test.dart`
|
|
- `test/functional/functional_coverage_test.dart`
|
|
|
|
### 4. Exécution de séance
|
|
|
|
Parcours nominaux :
|
|
|
|
- démarrer depuis une séance
|
|
- exécuter score manuel
|
|
- exécuter chrono score
|
|
- gérer repos
|
|
- pause/reprise
|
|
- terminer une série
|
|
- quitter et reprendre
|
|
- compléter la séance
|
|
- enregistrer l'historique
|
|
- relancer depuis l'historique
|
|
|
|
Cas limites :
|
|
|
|
- séance invalide
|
|
- repos resynchronisé
|
|
- chrono jamais démarré
|
|
- dernière série sans repos
|
|
- série passée corrigée
|
|
- skip de série
|
|
- skip de séquence
|
|
|
|
Suites attendues :
|
|
|
|
- unitaires : transitions d'état de session, repos, chrono, score, steps
|
|
- intégration : persistance session active -> historique
|
|
- widget : écran d'exécution, plan, édition de série passée, reprise
|
|
- end-to-end/manuel scripté : parcours complet réel sur téléphone
|
|
|
|
Base existante :
|
|
|
|
- `test/application/use_cases_test.dart`
|
|
- `test/application/session_notification_use_cases_test.dart`
|
|
- `test/presentation/workout_execution_screen_test.dart`
|
|
- `test/functional/functional_coverage_test.dart`
|
|
|
|
### 5. Historique et progression
|
|
|
|
Parcours nominaux :
|
|
|
|
- consulter les séances passées
|
|
- ouvrir le détail
|
|
- supprimer
|
|
- relancer
|
|
- visualiser la progression globale
|
|
- visualiser la progression par exercice
|
|
|
|
Cas limites :
|
|
|
|
- historique vide
|
|
- historique legacy invalide
|
|
- score chrono affiché comme temps
|
|
- ouverture de détail depuis point de graphe
|
|
|
|
Suites attendues :
|
|
|
|
- unitaires : agrégations progression et mapping métriques
|
|
- intégration : repository historique
|
|
- widget : écrans Historique et Progression
|
|
- end-to-end/manuel scripté : séance jouée puis visible dans progression
|
|
|
|
Base existante :
|
|
|
|
- `test/presentation/history_screen_test.dart`
|
|
- `test/presentation/progression_screen_test.dart`
|
|
|
|
### 6. Compte, auth, sync et partage
|
|
|
|
Parcours nominaux :
|
|
|
|
- créer un compte
|
|
- se connecter
|
|
- se déconnecter
|
|
- synchroniser
|
|
- partager un programme
|
|
- partager une séance
|
|
- recevoir un partage
|
|
- accepter et importer
|
|
- décliner
|
|
|
|
Cas limites :
|
|
|
|
- erreur login inline
|
|
- erreur serveur dédiée
|
|
- token invalide
|
|
- conflit LWW sync
|
|
- partage déjà répondu
|
|
- email inconnu
|
|
- quota receveur plein
|
|
|
|
Suites attendues :
|
|
|
|
- unitaires : use cases auth/sync/share, règles quota/import
|
|
- intégration : client HTTP, API serveur, repositories serveur
|
|
- widget : Profil, Inbox, formulaires de partage
|
|
- end-to-end/manuel scripté : 2 comptes réels, partage puis sync
|
|
|
|
Base existante :
|
|
|
|
- client Flutter : `test/presentation/profile_screen_test.dart`, `test/presentation/share_inbox_screen_test.dart`, `test/infrastructure/remote/*.dart`
|
|
- serveur Dart : `server/test/auth_*`, `server/test/sync_*`, `server/test/share_*`
|
|
|
|
Note monétisation :
|
|
|
|
- le partage reste gratuit
|
|
- le quota free limite la bibliothèque éditable, pas l'exécution
|
|
- les objets importés/partagés comptent côté receveur à l'acceptation
|
|
- le backlog QA devra explicitement ajouter les cas quota multi-comptes et restauration
|
|
|
|
### 7. Import / export local
|
|
|
|
Parcours nominaux :
|
|
|
|
- exporter ses données
|
|
- importer en fusion
|
|
- importer en remplacement total
|
|
|
|
Cas limites :
|
|
|
|
- fichier invalide
|
|
- annulation silencieuse
|
|
- séance active qui bloque l'import
|
|
- double confirmation destructive
|
|
|
|
Suites attendues :
|
|
|
|
- unitaires : parsing et règles de fusion/remplacement
|
|
- intégration : repositories et frontières d'import
|
|
- widget : flux import/export depuis Profil
|
|
- end-to-end/manuel scripté : vrai fichier sur device
|
|
|
|
Base existante :
|
|
|
|
- `test/presentation/profile_screen_test.dart`
|
|
- `test/domain_import_boundaries_test.dart`
|
|
|
|
### 8. Health Connect
|
|
|
|
Parcours nominaux :
|
|
|
|
- afficher l'état d'intégration
|
|
- demander les permissions
|
|
- rafraîchir le statut
|
|
|
|
Cas limites :
|
|
|
|
- permissions partielles
|
|
- refus explicite
|
|
- fallback vers réglages
|
|
- accès bloqué sans action
|
|
- échec d'appel natif
|
|
|
|
Suites attendues :
|
|
|
|
- unitaires : mapping des statuts natifs
|
|
- intégration : gateway Health Connect mockée
|
|
- widget : écran Paramètres / Intégrations
|
|
- manuel scripté : device Android compatible Health Connect
|
|
|
|
Base existante :
|
|
|
|
- `test/application/health_connect_use_cases_test.dart`
|
|
- `test/presentation/settings_screen_test.dart`
|
|
|
|
### 9. Watch companion
|
|
|
|
Parcours nominaux :
|
|
|
|
- projeter une séance active vers la montre
|
|
- piloter score / timer / pause depuis la montre
|
|
- remonter la fréquence cardiaque et la télémétrie
|
|
- gérer reconnexion et fraîcheur de projection
|
|
|
|
Cas limites :
|
|
|
|
- téléphone absent
|
|
- projection stale
|
|
- actions bloquées en reconnexion
|
|
- timer visible en pause
|
|
- TTL dépassé
|
|
|
|
Suites attendues :
|
|
|
|
- unitaires : contrat de projection, commandes, policy de retry
|
|
- intégration : bridge natif téléphone <-> montre
|
|
- widget : UI montre
|
|
- manuel scripté : téléphone Android + émulateur/device Wear
|
|
|
|
Base existante :
|
|
|
|
- `test/application/watch_companion_projection_test.dart`
|
|
- `test/application/watch_companion_command_handler_test.dart`
|
|
- `test/infrastructure/watch_bridge/wear_data_layer_adapter_test.dart`
|
|
- `watch_app/test/presentation/watch_session_screen_test.dart`
|
|
- `watch_app/android/app/src/test/kotlin/com/gametime/watch/bridge/WatchExerciseMetricsRetryPolicyTest.kt`
|
|
|
|
## Stratégie runnable par niveau de suite
|
|
|
|
### 1. Suites rapides obligatoires sur chaque lot
|
|
|
|
Objectif : feedback en quelques minutes, sans device réel.
|
|
|
|
Contenu :
|
|
|
|
- unitaires domaine/application
|
|
- intégration repository mémoire ou Drift locale
|
|
- widget ciblés
|
|
- fonctionnels mémoire via `FunctionalTestHarness`
|
|
|
|
Règle :
|
|
|
|
- toute nouvelle feature/correction doit d'abord produire ou enrichir une suite de ce niveau
|
|
|
|
### 2. Suites de référence transverses
|
|
|
|
Objectif : prouver que les briques s'assemblent sur des parcours principaux.
|
|
|
|
Contenu :
|
|
|
|
- un petit nombre de scénarios fonctionnels end-to-end en mémoire côté Flutter
|
|
- un petit nombre de scénarios API serveur de bout en bout en local
|
|
|
|
Règle :
|
|
|
|
- garder ces scénarios courts, lisibles et déterministes
|
|
- ne pas y mettre toutes les permutations écran par écran
|
|
|
|
### 3. Suites device / infra scriptées
|
|
|
|
Objectif : couvrir les frontières impossibles à prouver en sandbox mémoire.
|
|
|
|
Contenu :
|
|
|
|
- import/export réel
|
|
- Health Connect réel
|
|
- compagnon montre réel
|
|
- Docker/PostgreSQL/smoke API réel
|
|
|
|
Règle :
|
|
|
|
- documenter chaque parcours sous forme de script de validation réexécutable
|
|
- promouvoir en automatisation seulement après stabilisation du protocole et des fixtures
|
|
|
|
## Commandes cibles
|
|
|
|
### Flutter app
|
|
|
|
Installer les dépendances :
|
|
|
|
```bash
|
|
export HOME=/tmp
|
|
export XDG_CONFIG_HOME=/tmp
|
|
export FLUTTER_SUPPRESS_ANALYTICS=true
|
|
export DART_SUPPRESS_ANALYTICS=true
|
|
./.ideai/flutter-sdk-1785572580/bin/flutter pub get
|
|
```
|
|
|
|
Smoke domaine/widget/functional :
|
|
|
|
```bash
|
|
./.ideai/flutter-sdk-1785572580/bin/flutter test
|
|
./.ideai/flutter-sdk-1785572580/bin/flutter test test/functional/functional_coverage_test.dart
|
|
./.ideai/flutter-sdk-1785572580/bin/flutter test test/presentation/workout_execution_screen_test.dart
|
|
./.ideai/flutter-sdk-1785572580/bin/flutter test test/presentation/profile_screen_test.dart
|
|
```
|
|
|
|
### Watch app
|
|
|
|
```bash
|
|
cd watch_app
|
|
export HOME=/tmp
|
|
export XDG_CONFIG_HOME=/tmp
|
|
export FLUTTER_SUPPRESS_ANALYTICS=true
|
|
export DART_SUPPRESS_ANALYTICS=true
|
|
../.ideai/flutter-sdk-1785572580/bin/flutter pub get
|
|
../.ideai/flutter-sdk-1785572580/bin/flutter test
|
|
```
|
|
|
|
### Serveur
|
|
|
|
```bash
|
|
cd server
|
|
export HOME=/tmp
|
|
export XDG_CONFIG_HOME=/tmp
|
|
export DART_SUPPRESS_ANALYTICS=true
|
|
/home/anthony/Documents/Projects/GameTime/.ideai/flutter-sdk-1785572580/bin/dart pub get
|
|
/home/anthony/Documents/Projects/GameTime/.ideai/flutter-sdk-1785572580/bin/dart test
|
|
```
|
|
|
|
### Intégration PostgreSQL réelle
|
|
|
|
```bash
|
|
cd server
|
|
TEST_DATABASE_URL=postgres://gametime:gametime@localhost:5432/gametime \
|
|
/home/anthony/Documents/Projects/GameTime/.ideai/flutter-sdk-1785572580/bin/dart test
|
|
```
|
|
|
|
### Build / smoke Android manuel scripté
|
|
|
|
```bash
|
|
export HOME=/tmp
|
|
export XDG_CONFIG_HOME=/tmp
|
|
export FLUTTER_SUPPRESS_ANALYTICS=true
|
|
export DART_SUPPRESS_ANALYTICS=true
|
|
./.ideai/flutter-sdk-1785572580/bin/flutter build apk --debug
|
|
./.ideai/flutter-sdk-1785572580/bin/flutter run
|
|
```
|
|
|
|
## Backlog initial d'automatisation
|
|
|
|
### Priorité P0 — à garder verte en permanence
|
|
|
|
- stabiliser `test/functional/functional_coverage_test.dart` comme gate Flutter transverse
|
|
- y conserver au moins 4 scénarios de référence :
|
|
- création exercice/programme/séance via formulaires réels
|
|
- exécution complète avec score manuel + chrono + repos + historique + replay
|
|
- reprise de séance sauvegardée
|
|
- séquences d'étapes avec skip et correction de résultat
|
|
- définir une commande CI rapide `flutter test test/functional/functional_coverage_test.dart`
|
|
- définir une commande CI serveur `dart test` dans `server/`
|
|
|
|
### Priorité P1 — verrouiller le cœur prod offline
|
|
|
|
- compléter une suite intégration Drift dédiée au cycle exercice -> programme -> template -> session -> historique
|
|
- ajouter une suite application dédiée aux invariants de progression à partir d'historiques réels
|
|
- ajouter une suite widget de navigation nominale accueil -> séance -> historique -> progression
|
|
- isoler un groupe "smoke critical screens" pour `home`, `exercise_library`, `program`, `workout_template`, `workout_execution`, `history`, `progression`
|
|
|
|
### Priorité P2 — verrouiller les frontières produit payantes et multi-comptes
|
|
|
|
- ajouter tests use case et serveur pour quota free/pro
|
|
- couvrir import de partage quand quota receveur est plein
|
|
- couvrir multi-comptes, restauration et sync Pro
|
|
- couvrir offline puis resync après reconnexion
|
|
|
|
### Priorité P3 — transformer les checklists device en scripts réexécutables
|
|
|
|
- écrire un script manuel standardisé Health Connect
|
|
- écrire un script manuel standardisé watch companion
|
|
- écrire un script manuel standardisé partage entre deux comptes réels
|
|
- écrire un script manuel standardisé import/export fichier réel
|
|
|
|
## Première découpe TDD recommandée pour relancer le delivery
|
|
|
|
### Sprint QA-A — gate rapide commune
|
|
|
|
- figer la convention d'environnement de test
|
|
- garder vert :
|
|
- `test/functional/functional_coverage_test.dart`
|
|
- `server/test`
|
|
- `watch_app/test`
|
|
|
|
### Sprint QA-B — cœur offline téléphone
|
|
|
|
- enrichir le functional harness pour couvrir navigation nominale complète
|
|
- compléter les invariants manquants exercice -> programme -> template -> exécution -> historique -> progression
|
|
|
|
### Sprint QA-C — compte/sync/partage
|
|
|
|
- préparer fixtures API et scénarios 2 comptes
|
|
- séparer clairement :
|
|
- tests client mockés
|
|
- tests serveur réels
|
|
- smoke manuels API + client
|
|
|
|
### Sprint QA-D — device integrations
|
|
|
|
- formaliser scripts de validation montre et Health Connect
|
|
- décider ensuite ce qui mérite une automatisation instrumentée
|
|
|
|
## Critères de sortie pour qu'une feature soit "finie"
|
|
|
|
Une feature n'est pas considérée terminée tant que :
|
|
|
|
- le plan fonctionnel du lot existe
|
|
- les tests unitaires / intégration / widget prévus pour le lot existent
|
|
- les commandes de suites rapides ont réellement tourné
|
|
- les éventuels scripts manuels device/infra ont réellement été exécutés si la feature touche ces frontières
|
|
- les régressions critiques correspondantes sont absorbées dans les suites P0/P1
|
|
|
|
## Recommandation immédiate
|
|
|
|
Pour redémarrer vers la prod sans disperser l'équipe :
|
|
|
|
1. utiliser `test/functional/functional_coverage_test.dart` comme colonne vertébrale Flutter
|
|
2. considérer `server/test` comme gate du scope compte/sync/partage
|
|
3. ne pas lancer de nouvelle feature transverse sans ajouter son scénario dans le harnais fonctionnel ou dans une suite serveur équivalente
|
|
4. traiter Health Connect et watch companion comme checklists scriptées tant que le setup device n'est pas stabilisé en CI
|