# 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