docs(qa-261): ajoute documents conformité et scripts QA pour release Android
- 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
This commit is contained in:
91
docs/legal/privacy-policy-v1.md
Normal file
91
docs/legal/privacy-policy-v1.md
Normal file
@ -0,0 +1,91 @@
|
||||
# GameTime Privacy Policy
|
||||
|
||||
Version: 1.0
|
||||
Effective date: 2026-08-22
|
||||
Status: repo reference draft for release preparation
|
||||
|
||||
## Scope
|
||||
|
||||
This policy covers the GameTime mobile app, including the Android phone app,
|
||||
the optional Wear OS companion, account features, sharing, synchronization,
|
||||
purchase entitlement checks, and optional Health Connect integration.
|
||||
|
||||
## Data We Handle
|
||||
|
||||
GameTime is designed as an offline-first workout tracker. Depending on the
|
||||
features used, the app may handle:
|
||||
|
||||
- workout library content created by the user, including exercises, programs,
|
||||
workout templates, timers, scores, repetitions, session history, and local
|
||||
media selected for exercises
|
||||
- account identifiers such as email address and authentication tokens when the
|
||||
user creates an account or signs in
|
||||
- shared workout resources and recipient email addresses when the sharing
|
||||
feature is used
|
||||
- purchase entitlement status needed to determine whether the account is on the
|
||||
Free or Pro plan
|
||||
- optional workout telemetry such as heart rate, distance, calories, and
|
||||
exercise records when the user explicitly enables Health Connect integration
|
||||
- optional live workout state and commands exchanged with the Wear OS companion
|
||||
|
||||
## Free and Pro Features
|
||||
|
||||
Sharing remains free. The Free plan limits the editable workout library, not
|
||||
basic workout execution. Imported or shared resources count toward the
|
||||
receiving account's quota when accepted. Pro provides unlimited library capacity
|
||||
and synchronization.
|
||||
|
||||
The Wear OS companion and Health Connect integration are free features and are
|
||||
not paywalled.
|
||||
|
||||
## Local Storage and Offline Use
|
||||
|
||||
Workout data is stored locally on the device first. The app is intended to keep
|
||||
working without network access, including before any server synchronization has
|
||||
been configured.
|
||||
|
||||
## Synchronization and Sharing
|
||||
|
||||
When synchronization is enabled, workout library and account data may be sent to
|
||||
the GameTime server so the account can restore or synchronize data. When sharing
|
||||
is used, the selected resources and recipient identifiers are sent to the server
|
||||
so recipients can receive, accept, decline, or revoke shares.
|
||||
|
||||
## Health Connect
|
||||
|
||||
Health Connect access is optional. GameTime requests only the health permissions
|
||||
needed for the enabled workout features. Health data is used to support workout
|
||||
tracking and export flows shown in the app. The user can revoke Health Connect
|
||||
permissions from Android settings.
|
||||
|
||||
## Wear OS Companion
|
||||
|
||||
The Wear OS companion exchanges live session state, commands, and available
|
||||
metrics with the phone app. The companion is optional and depends on the Android
|
||||
Wear Data Layer between paired devices.
|
||||
|
||||
## Purchases and Entitlements
|
||||
|
||||
Purchase and entitlement data is used to unlock Pro functionality such as
|
||||
unlimited library capacity and synchronization. GameTime does not use purchase
|
||||
state to restrict sharing, the Wear OS companion, Health Connect, or basic
|
||||
workout execution.
|
||||
|
||||
## Data Retention and Deletion
|
||||
|
||||
Local workout data remains on the device until the user deletes it or removes
|
||||
the app. Server-side account, synchronization, sharing, and entitlement data
|
||||
requires an operational account management process before public release.
|
||||
|
||||
## Security
|
||||
|
||||
Release Android builds must use HTTPS for remote GameTime server traffic.
|
||||
Cleartext HTTP is permitted only for local debug/profile development builds.
|
||||
Authentication tokens are treated as sensitive credentials and should be stored
|
||||
through the platform secure storage adapter.
|
||||
|
||||
## Contact
|
||||
|
||||
Before public distribution, replace this section with the legal support contact
|
||||
and the public URL that will be submitted to the Play Console.
|
||||
|
||||
629
docs/qa-functional-test-plan-238.md
Normal file
629
docs/qa-functional-test-plan-238.md
Normal file
@ -0,0 +1,629 @@
|
||||
# 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
|
||||
63
docs/qa-gate-239-functional-flutter.md
Normal file
63
docs/qa-gate-239-functional-flutter.md
Normal file
@ -0,0 +1,63 @@
|
||||
# QA Gate #239 — Suite fonctionnelle Flutter transverse
|
||||
|
||||
## But
|
||||
|
||||
Cette gate sert de socle rapide de non-régression Flutter pour la reprise TDD.
|
||||
Elle couvre le parcours transverse minimal suivant :
|
||||
|
||||
- création via formulaires réels
|
||||
- exécution complète d'une séance
|
||||
- reprise de séance
|
||||
- séquences, skip et correction
|
||||
|
||||
## Fichier source
|
||||
|
||||
- `test/functional/functional_coverage_test.dart`
|
||||
|
||||
## Pré-requis
|
||||
|
||||
Utiliser un environnement writable pour Flutter :
|
||||
|
||||
```bash
|
||||
export HOME=/tmp
|
||||
export XDG_CONFIG_HOME=/tmp
|
||||
export FLUTTER_SUPPRESS_ANALYTICS=true
|
||||
export DART_SUPPRESS_ANALYTICS=true
|
||||
```
|
||||
|
||||
## Commande gate complète
|
||||
|
||||
```bash
|
||||
./.ideai/flutter-sdk-1785572580/bin/flutter test test/functional/functional_coverage_test.dart
|
||||
```
|
||||
|
||||
## Commandes ciblées utiles
|
||||
|
||||
Scénario de référence transverse :
|
||||
|
||||
```bash
|
||||
./.ideai/flutter-sdk-1785572580/bin/flutter test test/functional/functional_coverage_test.dart --plain-name "complete execution covers manual score, stopwatch, rests, skips, history and replay"
|
||||
```
|
||||
|
||||
Scénario reprise :
|
||||
|
||||
```bash
|
||||
./.ideai/flutter-sdk-1785572580/bin/flutter test test/functional/functional_coverage_test.dart --plain-name "saved exit sessions resume from the execution UI without showing completion"
|
||||
```
|
||||
|
||||
## Verdict attendu
|
||||
|
||||
- vert si la base Flutter transverse est prête pour une boucle TDD rapide
|
||||
- rouge si un parcours nominal majeur est cassé
|
||||
|
||||
## Preuve réelle du 22 août 2026
|
||||
|
||||
Exécution rapportée verte sur `/tmp/gametime-src-1787384228`.
|
||||
|
||||
Cette gate devient la référence rapide de non-régression Flutter transverse.
|
||||
|
||||
## Usage dans la boucle TDD
|
||||
|
||||
- avant implémentation d'une feature transverse touchant exécution/navigation
|
||||
- après chaque lot modifiant les formulaires, l'exécution, l'historique ou la reprise
|
||||
- comme gate rapide avant d'élargir vers les suites widget plus détaillées
|
||||
57
docs/qa-gate-240-drift-core-offline.md
Normal file
57
docs/qa-gate-240-drift-core-offline.md
Normal file
@ -0,0 +1,57 @@
|
||||
# QA Gate #240 — Suite coeur offline Drift
|
||||
|
||||
## But
|
||||
|
||||
Cette gate sécurise le coeur offline local avant reprise intensive du développement.
|
||||
Le point d'entrée recommandé est le parcours intégré :
|
||||
|
||||
- exercice
|
||||
- programme
|
||||
- séance-template
|
||||
- session active
|
||||
- clôture en historique
|
||||
- progression minimale
|
||||
|
||||
## Fichier source
|
||||
|
||||
- `test/infrastructure/drift_repositories_test.dart`
|
||||
|
||||
## Pré-requis
|
||||
|
||||
Utiliser le runner Flutter/Dart avec un environnement writable :
|
||||
|
||||
```bash
|
||||
export HOME=/tmp
|
||||
export XDG_CONFIG_HOME=/tmp
|
||||
export FLUTTER_SUPPRESS_ANALYTICS=true
|
||||
export DART_SUPPRESS_ANALYTICS=true
|
||||
```
|
||||
|
||||
## Commande gate complète
|
||||
|
||||
```bash
|
||||
./.ideai/flutter-sdk-1785572580/bin/flutter test test/infrastructure/drift_repositories_test.dart
|
||||
```
|
||||
|
||||
## Point d'entrée coeur offline recommandé
|
||||
|
||||
```bash
|
||||
./.ideai/flutter-sdk-1785572580/bin/flutter test test/infrastructure/drift_repositories_test.dart --plain-name "QA core offline journey persists exercise to progression through local repositories"
|
||||
```
|
||||
|
||||
## Verdict attendu
|
||||
|
||||
- vert si la chaîne locale principale reste cohérente de la création jusqu'à la progression
|
||||
- rouge si le domaine local ou la persistance Drift régressent sur le flux principal
|
||||
|
||||
## Preuve réelle du 22 août 2026
|
||||
|
||||
Exécution rapportée verte sur `/tmp/gametime-src-1787384228`.
|
||||
|
||||
Cette gate devient la référence coeur offline avant toute validation device ou release.
|
||||
|
||||
## Usage dans la boucle TDD
|
||||
|
||||
- à lancer avant et après chaque lot touchant les use cases offline
|
||||
- à utiliser comme première preuve exécutable avant les suites écran par écran
|
||||
- à compléter ensuite par les tests fonctionnels Flutter et, plus tard, les validations device
|
||||
73
docs/qa-gate-241-critical-screens-smoke.md
Normal file
73
docs/qa-gate-241-critical-screens-smoke.md
Normal file
@ -0,0 +1,73 @@
|
||||
# QA Gate #241 — Smoke écrans critiques Flutter
|
||||
|
||||
## But
|
||||
|
||||
Cette gate sert de détection rapide des régressions visibles majeures pendant la boucle TDD Flutter.
|
||||
|
||||
Écrans couverts :
|
||||
|
||||
- `home`
|
||||
- `exercise library`
|
||||
- `program`
|
||||
- `workout template`
|
||||
- `workout execution`
|
||||
- `history`
|
||||
- `progression`
|
||||
- `profile`
|
||||
|
||||
## Fichiers sources
|
||||
|
||||
- `test/presentation/home_screen_test.dart`
|
||||
- `test/presentation/exercise_library_screen_test.dart`
|
||||
- `test/presentation/program_screen_test.dart`
|
||||
- `test/presentation/workout_template_screen_test.dart`
|
||||
- `test/presentation/workout_execution_screen_test.dart`
|
||||
- `test/presentation/history_screen_test.dart`
|
||||
- `test/presentation/progression_screen_test.dart`
|
||||
- `test/presentation/profile_screen_test.dart`
|
||||
|
||||
## Pré-requis
|
||||
|
||||
```bash
|
||||
export HOME=/tmp
|
||||
export XDG_CONFIG_HOME=/tmp
|
||||
export FLUTTER_SUPPRESS_ANALYTICS=true
|
||||
export DART_SUPPRESS_ANALYTICS=true
|
||||
```
|
||||
|
||||
## Point d'entrée recommandé
|
||||
|
||||
```bash
|
||||
./tool/qa_gate_241_critical_screens_smoke.sh
|
||||
```
|
||||
|
||||
## Commande directe équivalente
|
||||
|
||||
```bash
|
||||
./.ideai/flutter-sdk-1785572580/bin/flutter test \
|
||||
test/presentation/home_screen_test.dart \
|
||||
test/presentation/exercise_library_screen_test.dart \
|
||||
test/presentation/program_screen_test.dart \
|
||||
test/presentation/workout_template_screen_test.dart \
|
||||
test/presentation/workout_execution_screen_test.dart \
|
||||
test/presentation/history_screen_test.dart \
|
||||
test/presentation/progression_screen_test.dart \
|
||||
test/presentation/profile_screen_test.dart
|
||||
```
|
||||
|
||||
## Verdict attendu
|
||||
|
||||
- vert si les écrans critiques restent fonctionnels sur les parcours nominaux majeurs
|
||||
- rouge si une régression UI majeure casse la boucle TDD Flutter
|
||||
|
||||
## Preuve réelle du 22 août 2026
|
||||
|
||||
Exécution rapportée verte sur `/tmp/gametime-src-1787384228`.
|
||||
|
||||
Le script `./tool/qa_gate_241_critical_screens_smoke.sh` devient l'entrée de référence pour ce smoke.
|
||||
|
||||
## Usage
|
||||
|
||||
- avant merge d'un lot Flutter transverse
|
||||
- après toute modification navigation/formulaires/exécution/historique/profil
|
||||
- en complément de la gate `#239`
|
||||
80
docs/qa-gate-242-monetization-free-pro.md
Normal file
80
docs/qa-gate-242-monetization-free-pro.md
Normal file
@ -0,0 +1,80 @@
|
||||
# QA Gate #242 — Monétisation Free/Pro et partage/quota
|
||||
|
||||
## But
|
||||
|
||||
Matérialiser une première gate runnable autour de ce qui est déjà testable aujourd'hui, tout en isolant les blockers réels pour les règles Free/Pro non encore implémentées.
|
||||
|
||||
## Ce qui est runnable maintenant
|
||||
|
||||
Couverture partielle déjà testable :
|
||||
|
||||
- profil et synchronisation côté Flutter
|
||||
- partage / inbox / acceptation locale
|
||||
- Health Connect gratuit
|
||||
- companion montre gratuit
|
||||
|
||||
Fichiers déjà exploitables :
|
||||
|
||||
- `test/presentation/profile_screen_test.dart`
|
||||
- `test/presentation/share_inbox_screen_test.dart`
|
||||
- `test/presentation/settings_screen_test.dart`
|
||||
- `test/application/health_connect_use_cases_test.dart`
|
||||
- `test/application/watch_companion_projection_test.dart`
|
||||
|
||||
## Point d'entrée recommandé
|
||||
|
||||
```bash
|
||||
./tool/qa_gate_242_monetization_partial.sh
|
||||
```
|
||||
|
||||
## Pré-requis
|
||||
|
||||
```bash
|
||||
export HOME=/tmp
|
||||
export XDG_CONFIG_HOME=/tmp
|
||||
export FLUTTER_SUPPRESS_ANALYTICS=true
|
||||
export DART_SUPPRESS_ANALYTICS=true
|
||||
```
|
||||
|
||||
## Commande directe équivalente
|
||||
|
||||
```bash
|
||||
./.ideai/flutter-sdk-1785572580/bin/flutter test \
|
||||
test/presentation/profile_screen_test.dart \
|
||||
test/presentation/share_inbox_screen_test.dart \
|
||||
test/presentation/settings_screen_test.dart \
|
||||
test/application/health_connect_use_cases_test.dart \
|
||||
test/application/watch_companion_projection_test.dart
|
||||
```
|
||||
|
||||
## Blockers réels
|
||||
|
||||
Les contrats suivants ne sont pas encore testables proprement contre du code produit, car la surface métier n'existe pas encore clairement dans le repo :
|
||||
|
||||
- quota `Free/Pro`
|
||||
- refus création/édition quand quota plein
|
||||
- import de partage chez receveur plein
|
||||
- restauration d'achat
|
||||
- statut `Pro`
|
||||
- sync `Pro`
|
||||
- multi-comptes monétisation
|
||||
|
||||
## Recommandation de suite
|
||||
|
||||
Avant d'écrire une vraie suite verte sur ces règles, il faut introduire un contrat métier testable, par exemple :
|
||||
|
||||
- une policy `LibraryEntitlementPolicy`
|
||||
- un use case `QuotaGuard`
|
||||
- un état de compte distinguant `Free` et `Pro`
|
||||
- une règle explicite d'acceptation de partage sous quota
|
||||
|
||||
## Verdict attendu
|
||||
|
||||
- vert aujourd'hui sur la gate partielle gratuite / partage
|
||||
- rouge ou non applicable sur Free/Pro tant que la couche métier quota/billing n'existe pas
|
||||
|
||||
## Preuve réelle du 22 août 2026
|
||||
|
||||
Exécution rapportée verte sur `/tmp/gametime-src-1787384228`.
|
||||
|
||||
Cette gate valide la surface monétisation actuellement testable en local, sans fermer la QA release Android Play Store.
|
||||
105
docs/qa-gate-243-device-runbooks.md
Normal file
105
docs/qa-gate-243-device-runbooks.md
Normal file
@ -0,0 +1,105 @@
|
||||
# QA Gate #243 — Runbooks manuels device
|
||||
|
||||
## But
|
||||
|
||||
Standardiser les validations device non encore raisonnablement automatisables, avec des scripts réexécutables de collecte d'artefacts et un déroulé manuel stable.
|
||||
|
||||
Périmètre couvert :
|
||||
|
||||
- Health Connect téléphone Android
|
||||
- watch companion téléphone + Wear
|
||||
- import/export réel sur téléphone
|
||||
|
||||
## Références officielles
|
||||
|
||||
### Health Connect
|
||||
|
||||
Préparer la collecte :
|
||||
|
||||
```bash
|
||||
./tool/qa_device_health_connect.sh start
|
||||
```
|
||||
|
||||
Finaliser la collecte :
|
||||
|
||||
```bash
|
||||
./tool/qa_device_health_connect.sh stop <artifact_dir>
|
||||
```
|
||||
|
||||
### Watch companion
|
||||
|
||||
Préparer la collecte :
|
||||
|
||||
```bash
|
||||
WATCH_SERIAL=<watch-adb-serial> ./tool/qa_device_watch_companion.sh start
|
||||
```
|
||||
|
||||
Finaliser la collecte :
|
||||
|
||||
```bash
|
||||
WATCH_SERIAL=<watch-adb-serial> ./tool/qa_device_watch_companion.sh stop <artifact_dir>
|
||||
```
|
||||
|
||||
### Import / export réel
|
||||
|
||||
Préparer la collecte :
|
||||
|
||||
```bash
|
||||
./tool/qa_device_import_export_real.sh start
|
||||
```
|
||||
|
||||
Finaliser la collecte :
|
||||
|
||||
```bash
|
||||
./tool/qa_device_import_export_real.sh stop <artifact_dir>
|
||||
```
|
||||
|
||||
## Pré-requis communs
|
||||
|
||||
- `adb` disponible dans le `PATH`
|
||||
- appareil téléphone connecté et autorisé
|
||||
- pour la montre : `WATCH_SERIAL` renseigné et montre visible via `adb devices -l`
|
||||
- build GameTime fraîche installée sur le ou les appareils sous test
|
||||
|
||||
## Artefacts attendus
|
||||
|
||||
Chaque script crée un dossier sous :
|
||||
|
||||
```bash
|
||||
.ideai/artifacts/qa-device/
|
||||
```
|
||||
|
||||
Le dossier produit doit contenir au minimum :
|
||||
|
||||
- `adb-devices.txt`
|
||||
- fingerprint build device
|
||||
- `logcat.txt` téléphone et/ou montre
|
||||
- `steps.md` avec le scénario manuel joué
|
||||
- `package-dumpsys-before.txt` et `package-dumpsys-after.txt` quand applicable
|
||||
|
||||
## Verdict attendu par runbook
|
||||
|
||||
### Health Connect
|
||||
|
||||
- ouverture propre du flux permission ou fallback réglages
|
||||
- retour propre dans GameTime
|
||||
- état UI cohérent avant/après
|
||||
- export fin de séance vérifiable si exercé
|
||||
|
||||
### Watch companion
|
||||
|
||||
- projection de séance visible sur montre
|
||||
- actions montre répercutées sur téléphone
|
||||
- métriques montre lisibles, dont les pas si disponibles
|
||||
- clôture de séance cohérente côté téléphone et montre
|
||||
|
||||
### Import / export réel
|
||||
|
||||
- export de fichier réussi
|
||||
- réimport `merge` cohérent
|
||||
- réimport `replaceAll` cohérent sur dataset jetable
|
||||
- refus attendu si une séance active bloque l'import
|
||||
|
||||
## Limite actuelle au 22 août 2026
|
||||
|
||||
Ces runbooks rendent `#243` matérialisable et rejouable, mais la clôture QA device reste dépendante de la disponibilité réelle d'un appareil `adb`.
|
||||
73
docs/release-compliance-checklist.md
Normal file
73
docs/release-compliance-checklist.md
Normal file
@ -0,0 +1,73 @@
|
||||
# GameTime Release and Compliance Checklist
|
||||
|
||||
This checklist tracks the repo-owned release/compliance work that can be closed
|
||||
without Play Console access or physical devices.
|
||||
|
||||
## Privacy Policy
|
||||
|
||||
- Canonical repo draft: `docs/legal/privacy-policy-v1.md`
|
||||
- Version: `1.0`
|
||||
- Effective date: `2026-08-22`
|
||||
- Before Play submission, publish the exact approved policy at a stable HTTPS
|
||||
URL and enter that URL in Play Console.
|
||||
- Keep future policy changes versioned in `docs/legal/`.
|
||||
|
||||
## Product Entitlements
|
||||
|
||||
The release surface must preserve these product invariants:
|
||||
|
||||
- sharing is free
|
||||
- Free limits the editable workout library, not basic workout execution
|
||||
- imported/shared resources count against the receiver quota on acceptance
|
||||
- Pro means unlimited library plus sync
|
||||
- Wear OS companion is free
|
||||
- Health Connect is free
|
||||
|
||||
## Android Network Policy
|
||||
|
||||
Phone app release builds:
|
||||
|
||||
- keep `android.permission.INTERNET` in `android/app/src/main/AndroidManifest.xml`
|
||||
- do not enable `android:usesCleartextTraffic` in the main manifest
|
||||
- use HTTPS for `GAMETIME_API_BASE_URL` in release builds
|
||||
|
||||
Phone app debug/profile builds:
|
||||
|
||||
- may keep cleartext enabled through the debug/profile manifest overlays
|
||||
- may use LAN HTTP URLs for local API development
|
||||
|
||||
Wear OS companion:
|
||||
|
||||
- keep release cleartext disabled
|
||||
- keep companion functionality free and independent from Pro entitlement
|
||||
|
||||
## Repo-Only Validation
|
||||
|
||||
Run these checks before handing off to Play/device validation:
|
||||
|
||||
```bash
|
||||
rg -n 'usesCleartextTraffic="true"' android/app/src/main watch_app/android/app/src/main
|
||||
rg -n 'usesCleartextTraffic="true"' android/app/src/debug android/app/src/profile
|
||||
rg -n 'android.permission.INTERNET' android/app/src/main/AndroidManifest.xml
|
||||
rg -n 'Health Connect|Wear OS|sharing is free|Pro means unlimited' docs/legal docs
|
||||
```
|
||||
|
||||
Expected result:
|
||||
|
||||
- no `usesCleartextTraffic="true"` in release/main manifests
|
||||
- debug/profile overlays explicitly allow local cleartext
|
||||
- phone release manifest still declares `INTERNET`
|
||||
- privacy and release docs preserve the Free/Pro invariants
|
||||
|
||||
## External Blockers
|
||||
|
||||
These items cannot be closed from the repository alone:
|
||||
|
||||
- Play Console app content forms
|
||||
- public privacy-policy hosting URL
|
||||
- production support/contact address approval
|
||||
- Play Health Connect declaration/review, if required by the final release track
|
||||
- validation on a real Android phone
|
||||
- validation on a real Wear OS device
|
||||
- production HTTPS endpoint and certificate verification
|
||||
|
||||
138
tool/qa_device_health_connect.sh
Executable file
138
tool/qa_device_health_connect.sh
Executable file
@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_ROOT="/home/anthony/Documents/Projects/GameTime"
|
||||
ARTIFACT_BASE="${ARTIFACT_BASE:-$PROJECT_ROOT/.ideai/artifacts/qa-device}"
|
||||
PHONE_SERIAL="${PHONE_SERIAL:-}"
|
||||
PACKAGE_NAME="${PACKAGE_NAME:-com.idea.gametime}"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./tool/qa_device_health_connect.sh start
|
||||
./tool/qa_device_health_connect.sh stop <artifact_dir>
|
||||
|
||||
Environment:
|
||||
PHONE_SERIAL Optional adb serial for the phone under test
|
||||
ARTIFACT_BASE Optional artifact root
|
||||
PACKAGE_NAME Optional Android package name (default: com.idea.gametime)
|
||||
EOF
|
||||
}
|
||||
|
||||
adb_cmd() {
|
||||
if [[ -n "$PHONE_SERIAL" ]]; then
|
||||
adb -s "$PHONE_SERIAL" "$@"
|
||||
else
|
||||
adb "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
require_adb() {
|
||||
command -v adb >/dev/null 2>&1 || {
|
||||
echo "adb not found in PATH." >&2
|
||||
exit 1
|
||||
}
|
||||
adb start-server >/dev/null
|
||||
adb_cmd get-state >/dev/null 2>&1 || {
|
||||
echo "No adb device available. Connect the phone or set PHONE_SERIAL." >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
timestamp() {
|
||||
date -u +"%Y%m%dT%H%M%SZ"
|
||||
}
|
||||
|
||||
start_capture() {
|
||||
require_adb
|
||||
local dir="$ARTIFACT_BASE/health-connect-$(timestamp)"
|
||||
mkdir -p "$dir"
|
||||
|
||||
adb devices -l >"$dir/adb-devices.txt"
|
||||
adb_cmd shell getprop ro.build.fingerprint >"$dir/phone-build-fingerprint.txt"
|
||||
adb_cmd shell dumpsys package "$PACKAGE_NAME" >"$dir/package-dumpsys-before.txt" || true
|
||||
adb_cmd logcat -c
|
||||
adb_cmd logcat -v threadtime >"$dir/logcat.txt" 2>&1 &
|
||||
local pid=$!
|
||||
echo "$pid" >"$dir/logcat.pid"
|
||||
|
||||
cat >"$dir/steps.md" <<EOF
|
||||
# Health Connect manual QA
|
||||
|
||||
Date: $(date -u +"%Y-%m-%d %H:%M:%SZ")
|
||||
Package: $PACKAGE_NAME
|
||||
|
||||
## Preconditions
|
||||
- Fresh GameTime phone build installed on the connected Android device.
|
||||
- Health Connect available on device.
|
||||
- Device unlocked.
|
||||
|
||||
## Manual flow
|
||||
1. Open GameTime.
|
||||
2. Go to Paramètres > Intégrations > Health Connect.
|
||||
3. Validate the visible initial status.
|
||||
4. Tap "Autoriser l'accès" or "Gérer les autorisations".
|
||||
5. Validate the expected path:
|
||||
- permission sheet opens, or
|
||||
- settings fallback opens cleanly.
|
||||
6. Grant or deny permissions according to the scenario under test.
|
||||
7. Return to GameTime and validate the refreshed status.
|
||||
8. Start and finish a workout if export-after-workout must be checked.
|
||||
9. Confirm the final Health Connect export outcome shown by the app.
|
||||
|
||||
## Evidence to collect
|
||||
- Screenshot(s) of the visible status before and after permission handling.
|
||||
- Screenshot(s) of Health Connect permission/settings UI if opened.
|
||||
- Notes on whether the path used the permission contract or settings fallback.
|
||||
- Result of export-after-workout if exercised.
|
||||
EOF
|
||||
|
||||
echo "$dir"
|
||||
}
|
||||
|
||||
stop_capture() {
|
||||
local dir="${1:-}"
|
||||
[[ -n "$dir" ]] || {
|
||||
usage >&2
|
||||
exit 2
|
||||
}
|
||||
require_adb
|
||||
[[ -d "$dir" ]] || {
|
||||
echo "Artifact directory not found: $dir" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ -f "$dir/logcat.pid" ]]; then
|
||||
kill "$(cat "$dir/logcat.pid")" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
adb_cmd shell dumpsys package "$PACKAGE_NAME" >"$dir/package-dumpsys-after.txt" || true
|
||||
adb_cmd shell settings list secure >"$dir/settings-secure.txt" || true
|
||||
|
||||
cat <<EOF
|
||||
Health Connect manual QA artifacts finalized in:
|
||||
$dir
|
||||
|
||||
Archive expected:
|
||||
- adb-devices.txt
|
||||
- phone-build-fingerprint.txt
|
||||
- package-dumpsys-before.txt
|
||||
- package-dumpsys-after.txt
|
||||
- logcat.txt
|
||||
- steps.md
|
||||
EOF
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
start)
|
||||
start_capture
|
||||
;;
|
||||
stop)
|
||||
shift
|
||||
stop_capture "${1:-}"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
129
tool/qa_device_import_export_real.sh
Executable file
129
tool/qa_device_import_export_real.sh
Executable file
@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_ROOT="/home/anthony/Documents/Projects/GameTime"
|
||||
ARTIFACT_BASE="${ARTIFACT_BASE:-$PROJECT_ROOT/.ideai/artifacts/qa-device}"
|
||||
PHONE_SERIAL="${PHONE_SERIAL:-}"
|
||||
PACKAGE_NAME="${PACKAGE_NAME:-com.idea.gametime}"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./tool/qa_device_import_export_real.sh start
|
||||
./tool/qa_device_import_export_real.sh stop <artifact_dir>
|
||||
|
||||
Environment:
|
||||
PHONE_SERIAL Optional adb serial for the phone under test
|
||||
ARTIFACT_BASE Optional artifact root
|
||||
PACKAGE_NAME Optional Android package name (default: com.idea.gametime)
|
||||
EOF
|
||||
}
|
||||
|
||||
adb_cmd() {
|
||||
if [[ -n "$PHONE_SERIAL" ]]; then
|
||||
adb -s "$PHONE_SERIAL" "$@"
|
||||
else
|
||||
adb "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
require_adb() {
|
||||
command -v adb >/dev/null 2>&1 || {
|
||||
echo "adb not found in PATH." >&2
|
||||
exit 1
|
||||
}
|
||||
adb start-server >/dev/null
|
||||
adb_cmd get-state >/dev/null 2>&1 || {
|
||||
echo "No adb device available. Connect the phone or set PHONE_SERIAL." >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
timestamp() {
|
||||
date -u +"%Y%m%dT%H%M%SZ"
|
||||
}
|
||||
|
||||
start_capture() {
|
||||
require_adb
|
||||
local dir="$ARTIFACT_BASE/import-export-real-$(timestamp)"
|
||||
mkdir -p "$dir"
|
||||
|
||||
adb devices -l >"$dir/adb-devices.txt"
|
||||
adb_cmd shell getprop ro.build.fingerprint >"$dir/phone-build-fingerprint.txt"
|
||||
adb_cmd shell dumpsys package "$PACKAGE_NAME" >"$dir/package-dumpsys-before.txt" || true
|
||||
adb_cmd logcat -c
|
||||
adb_cmd logcat -v threadtime >"$dir/logcat.txt" 2>&1 &
|
||||
echo "$!" >"$dir/logcat.pid"
|
||||
|
||||
cat >"$dir/steps.md" <<EOF
|
||||
# Import / export real-device QA
|
||||
|
||||
Date: $(date -u +"%Y-%m-%d %H:%M:%SZ")
|
||||
Package: $PACKAGE_NAME
|
||||
|
||||
## Preconditions
|
||||
- Fresh GameTime phone build installed on the connected Android device.
|
||||
- At least one exercise, one program and one workout template available locally.
|
||||
- File picker available on device.
|
||||
|
||||
## Manual flow
|
||||
1. Open GameTime.
|
||||
2. Go to the profile/settings surface exposing import/export.
|
||||
3. Export local data and confirm a file is produced.
|
||||
4. Record the exported filename and storage location.
|
||||
5. Re-import the same file in merge mode and validate the expected result.
|
||||
6. Re-import in replace-all mode only on a disposable dataset.
|
||||
7. If relevant, try importing while an active workout exists and validate the expected refusal.
|
||||
|
||||
## Evidence to collect
|
||||
- Screenshot(s) before export and after export confirmation.
|
||||
- Exported filename and location.
|
||||
- Screenshot(s) after merge import and replace-all import.
|
||||
- Notes on any refusal caused by active workout protection.
|
||||
EOF
|
||||
|
||||
echo "$dir"
|
||||
}
|
||||
|
||||
stop_capture() {
|
||||
local dir="${1:-}"
|
||||
[[ -n "$dir" ]] || {
|
||||
usage >&2
|
||||
exit 2
|
||||
}
|
||||
require_adb
|
||||
[[ -d "$dir" ]] || {
|
||||
echo "Artifact directory not found: $dir" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[[ -f "$dir/logcat.pid" ]] && kill "$(cat "$dir/logcat.pid")" >/dev/null 2>&1 || true
|
||||
adb_cmd shell dumpsys package "$PACKAGE_NAME" >"$dir/package-dumpsys-after.txt" || true
|
||||
|
||||
cat <<EOF
|
||||
Import/export manual QA artifacts finalized in:
|
||||
$dir
|
||||
|
||||
Archive expected:
|
||||
- adb-devices.txt
|
||||
- phone-build-fingerprint.txt
|
||||
- package-dumpsys-before.txt
|
||||
- package-dumpsys-after.txt
|
||||
- logcat.txt
|
||||
- steps.md
|
||||
EOF
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
start)
|
||||
start_capture
|
||||
;;
|
||||
stop)
|
||||
shift
|
||||
stop_capture "${1:-}"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
154
tool/qa_device_watch_companion.sh
Executable file
154
tool/qa_device_watch_companion.sh
Executable file
@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_ROOT="/home/anthony/Documents/Projects/GameTime"
|
||||
ARTIFACT_BASE="${ARTIFACT_BASE:-$PROJECT_ROOT/.ideai/artifacts/qa-device}"
|
||||
PHONE_SERIAL="${PHONE_SERIAL:-}"
|
||||
WATCH_SERIAL="${WATCH_SERIAL:-}"
|
||||
PACKAGE_NAME="${PACKAGE_NAME:-com.idea.gametime}"
|
||||
WATCH_PACKAGE_NAME="${WATCH_PACKAGE_NAME:-com.idea.gametime}"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./tool/qa_device_watch_companion.sh start
|
||||
./tool/qa_device_watch_companion.sh stop <artifact_dir>
|
||||
|
||||
Environment:
|
||||
PHONE_SERIAL Optional adb serial for the phone under test
|
||||
WATCH_SERIAL Optional adb serial for the Wear device under test
|
||||
ARTIFACT_BASE Optional artifact root
|
||||
PACKAGE_NAME Optional phone package name
|
||||
WATCH_PACKAGE_NAME Optional watch package name
|
||||
EOF
|
||||
}
|
||||
|
||||
adb_phone() {
|
||||
if [[ -n "$PHONE_SERIAL" ]]; then
|
||||
adb -s "$PHONE_SERIAL" "$@"
|
||||
else
|
||||
adb "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
adb_watch() {
|
||||
[[ -n "$WATCH_SERIAL" ]] || {
|
||||
echo "WATCH_SERIAL is required for watch companion QA." >&2
|
||||
exit 1
|
||||
}
|
||||
adb -s "$WATCH_SERIAL" "$@"
|
||||
}
|
||||
|
||||
require_adb() {
|
||||
command -v adb >/dev/null 2>&1 || {
|
||||
echo "adb not found in PATH." >&2
|
||||
exit 1
|
||||
}
|
||||
adb start-server >/dev/null
|
||||
adb_phone get-state >/dev/null 2>&1 || {
|
||||
echo "No phone adb device available." >&2
|
||||
exit 1
|
||||
}
|
||||
adb_watch get-state >/dev/null 2>&1 || {
|
||||
echo "No watch adb device available." >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
timestamp() {
|
||||
date -u +"%Y%m%dT%H%M%SZ"
|
||||
}
|
||||
|
||||
start_capture() {
|
||||
require_adb
|
||||
local dir="$ARTIFACT_BASE/watch-companion-$(timestamp)"
|
||||
mkdir -p "$dir"
|
||||
|
||||
adb devices -l >"$dir/adb-devices.txt"
|
||||
adb_phone shell getprop ro.build.fingerprint >"$dir/phone-build-fingerprint.txt"
|
||||
adb_watch shell getprop ro.build.fingerprint >"$dir/watch-build-fingerprint.txt"
|
||||
adb_phone shell dumpsys package "$PACKAGE_NAME" >"$dir/phone-package-dumpsys-before.txt" || true
|
||||
adb_watch shell dumpsys package "$WATCH_PACKAGE_NAME" >"$dir/watch-package-dumpsys-before.txt" || true
|
||||
adb_phone logcat -c
|
||||
adb_watch logcat -c
|
||||
adb_phone logcat -v threadtime >"$dir/phone-logcat.txt" 2>&1 &
|
||||
echo "$!" >"$dir/phone-logcat.pid"
|
||||
adb_watch logcat -v threadtime >"$dir/watch-logcat.txt" 2>&1 &
|
||||
echo "$!" >"$dir/watch-logcat.pid"
|
||||
|
||||
cat >"$dir/steps.md" <<EOF
|
||||
# Watch companion manual QA
|
||||
|
||||
Date: $(date -u +"%Y-%m-%d %H:%M:%SZ")
|
||||
Phone package: $PACKAGE_NAME
|
||||
Watch package: $WATCH_PACKAGE_NAME
|
||||
|
||||
## Preconditions
|
||||
- Phone and watch connected through adb.
|
||||
- Same GameTime app version installed on both.
|
||||
- Watch paired to the phone and reachable.
|
||||
|
||||
## Manual flow
|
||||
1. Launch GameTime on the phone.
|
||||
2. Start a workout from the phone.
|
||||
3. Validate that the active session is projected to the watch.
|
||||
4. Validate visible metrics on watch, including steps if available.
|
||||
5. Trigger at least one action from the watch that must affect the phone session.
|
||||
6. Validate phone UI updates correctly after the watch action.
|
||||
7. Finish the workout and validate the watch teardown / final state.
|
||||
|
||||
## Evidence to collect
|
||||
- Screenshot(s) on phone and watch while a session is active.
|
||||
- Notes on connection status and any visible lag.
|
||||
- Notes on step visibility if data is present.
|
||||
- Final verdict on session projection and round-trip actions.
|
||||
EOF
|
||||
|
||||
echo "$dir"
|
||||
}
|
||||
|
||||
stop_capture() {
|
||||
local dir="${1:-}"
|
||||
[[ -n "$dir" ]] || {
|
||||
usage >&2
|
||||
exit 2
|
||||
}
|
||||
require_adb
|
||||
[[ -d "$dir" ]] || {
|
||||
echo "Artifact directory not found: $dir" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[[ -f "$dir/phone-logcat.pid" ]] && kill "$(cat "$dir/phone-logcat.pid")" >/dev/null 2>&1 || true
|
||||
[[ -f "$dir/watch-logcat.pid" ]] && kill "$(cat "$dir/watch-logcat.pid")" >/dev/null 2>&1 || true
|
||||
|
||||
adb_phone shell dumpsys package "$PACKAGE_NAME" >"$dir/phone-package-dumpsys-after.txt" || true
|
||||
adb_watch shell dumpsys package "$WATCH_PACKAGE_NAME" >"$dir/watch-package-dumpsys-after.txt" || true
|
||||
|
||||
cat <<EOF
|
||||
Watch companion manual QA artifacts finalized in:
|
||||
$dir
|
||||
|
||||
Archive expected:
|
||||
- adb-devices.txt
|
||||
- phone-build-fingerprint.txt
|
||||
- watch-build-fingerprint.txt
|
||||
- phone-logcat.txt
|
||||
- watch-logcat.txt
|
||||
- steps.md
|
||||
EOF
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
start)
|
||||
start_capture
|
||||
;;
|
||||
stop)
|
||||
shift
|
||||
stop_capture "${1:-}"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
17
tool/qa_gate_241_critical_screens_smoke.sh
Executable file
17
tool/qa_gate_241_critical_screens_smoke.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
export HOME=/tmp
|
||||
export XDG_CONFIG_HOME=/tmp
|
||||
export FLUTTER_SUPPRESS_ANALYTICS=true
|
||||
export DART_SUPPRESS_ANALYTICS=true
|
||||
|
||||
exec ./.ideai/flutter-sdk-1785572580/bin/flutter test \
|
||||
test/presentation/home_screen_test.dart \
|
||||
test/presentation/exercise_library_screen_test.dart \
|
||||
test/presentation/program_screen_test.dart \
|
||||
test/presentation/workout_template_screen_test.dart \
|
||||
test/presentation/workout_execution_screen_test.dart \
|
||||
test/presentation/history_screen_test.dart \
|
||||
test/presentation/progression_screen_test.dart \
|
||||
test/presentation/profile_screen_test.dart
|
||||
14
tool/qa_gate_242_monetization_partial.sh
Executable file
14
tool/qa_gate_242_monetization_partial.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
export HOME=/tmp
|
||||
export XDG_CONFIG_HOME=/tmp
|
||||
export FLUTTER_SUPPRESS_ANALYTICS=true
|
||||
export DART_SUPPRESS_ANALYTICS=true
|
||||
|
||||
exec ./.ideai/flutter-sdk-1785572580/bin/flutter test \
|
||||
test/presentation/profile_screen_test.dart \
|
||||
test/presentation/share_inbox_screen_test.dart \
|
||||
test/presentation/settings_screen_test.dart \
|
||||
test/application/health_connect_use_cases_test.dart \
|
||||
test/application/watch_companion_projection_test.dart
|
||||
Reference in New Issue
Block a user