docs: cadrage initial Storytime (specs par jalon, roadmap, CLAUDE.md)
Lecteur d'histoires cadenassé pour le coucher (Android/Flutter). - CLAUDE.md : principes craftsmanship/TDD/clean code/clean archi + decisions techniques - ROADMAP.md : suivi haut niveau des 7 jalons, a tenir a jour par etape - docs/specs/ : specs completes decoupees par jalon, etapes en sous-fichiers - .gitignore Flutter (pubspec.lock versionne, projet applicatif) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
# 4.1 — Liste des histoires
|
||||
|
||||
## Objectif
|
||||
Afficher les histoires disponibles (épisodes des podcasts abonnés) sous forme de
|
||||
liste de titres cliquables, et lancer la lecture au tap.
|
||||
|
||||
## Périmètre & hors-périmètre
|
||||
- Inclus : agrégation des épisodes des abonnements, contrôleur Riverpod, écran liste, tap → `PlayStoryUseCase`.
|
||||
- Exclus : verrouillage (4.2), limites (J6).
|
||||
|
||||
## Dépendances
|
||||
2.x (lecture + `Episode`), 3.x (abonnements + `fetchEpisodes`).
|
||||
|
||||
## Conception
|
||||
- **Application** (`features/podcasts/application/` ou écran enfant) :
|
||||
- `LoadChildLibraryUseCase` : pour chaque abonnement, récupère les épisodes (`LoadEpisodesUseCase`) et construit la liste affichable. Stratégie d'erreur par flux : un flux KO n'empêche pas d'afficher les autres (dégradation gracieuse).
|
||||
- **Presentation** (`features/.../presentation/`) :
|
||||
- `ChildLibraryController` (Riverpod `AsyncNotifier`) : charge la bibliothèque, expose `loading/data/error`.
|
||||
- `ChildLibraryView` : liste de cartes (vignette + titre, grande zone tactile). Regroupement par podcast optionnel (titre de section).
|
||||
- Tap sur un épisode → `PlayStoryUseCase(queue, startIndex)` puis navigation vers/ouverture du `PlayerView` (J2).
|
||||
- États vides/erreur : messages **enfant** rassurants (« Aucune histoire pour l'instant », « Oups, réessaie »), jamais d'erreur technique.
|
||||
|
||||
## Plan TDD
|
||||
1. **Red** : `child_library_controller_test.dart` — avec use cases mockés : agrège les épisodes de 2 abonnements ; un abonnement en `Err` est ignoré sans faire échouer l'ensemble ; expose l'état attendu.
|
||||
2. **Green** : implémenter le use case d'agrégation + contrôleur.
|
||||
3. **Red** : `child_library_view_test.dart` (widget) — affiche les titres ; tap sur un titre appelle `PlayStoryUseCase` (provider mocké) avec le bon index ; état vide affiche le message enfant.
|
||||
4. **Green** : implémenter le widget.
|
||||
5. **Refactor**.
|
||||
|
||||
## Definition of Done
|
||||
- Tests contrôleur + widget verts (dont dégradation gracieuse).
|
||||
- Démo : la liste s'affiche, un tap lit l'histoire.
|
||||
- `tool/check.sh` passe ; étape 4.1 cochée dans `ROADMAP.md`.
|
||||
|
||||
## Risques / notes
|
||||
- Récupérer les épisodes de plusieurs flux peut être lent : charger en parallèle, afficher au fur et à mesure si pertinent. Rester simple en v1.
|
||||
@@ -0,0 +1,37 @@
|
||||
# 4.2 — Navigation verrouillée
|
||||
|
||||
## Objectif
|
||||
Faire en sorte que l'espace enfant s'épingle automatiquement et qu'aucune action
|
||||
de l'interface ne permette de sortir de l'app ou d'atteindre le système.
|
||||
|
||||
## Périmètre & hors-périmètre
|
||||
- Inclus : déclenchement auto de l'épinglage à l'entrée de l'espace enfant, audit des sorties UI possibles, gestion du bouton retour.
|
||||
- Exclus : la porte parentale (J5) ; les limites (J6).
|
||||
|
||||
## Dépendances
|
||||
1.2 (use cases de verrouillage), 4.1 (espace enfant existant).
|
||||
|
||||
## Conception
|
||||
- À l'entrée de l'espace enfant : `StartLockUseCase` appelé (via le contrôleur ou un observateur de cycle de vie). Gérer `LockUnsupportedFailure` → message parent au moment de la config, pas de crash.
|
||||
- **Audit des échappatoires UI** :
|
||||
- Pas de lien hypertexte ouvrant un navigateur, pas d'`intent` externe, pas de partage.
|
||||
- Bouton retour Android : intercepté (`PopScope`/`WillPopScope`) pour ne pas quitter l'app.
|
||||
- L'icône ⚙️ d'accès parent (posée ici) mène à la **porte parentale** (J5) ; sans le code, on ne sort pas de l'app.
|
||||
- Réafficher/relancer l'épinglage si l'app revient au premier plan (cycle de vie `resumed`).
|
||||
- **Honnêteté UI** : ne pas afficher de message laissant croire à un verrouillage inviolable.
|
||||
|
||||
## Plan TDD
|
||||
1. **Red** : `child_shell_locking_test.dart` (widget/contrôleur) — à l'affichage de l'espace enfant, `StartLockUseCase` est appelé (provider mocké). En `unsupported`, pas de crash et état dégradé documenté.
|
||||
2. **Green** : brancher l'appel d'épinglage au cycle de vie de l'écran.
|
||||
3. **Red** : `child_shell_back_button_test.dart` — le `PopScope` empêche la fermeture (callback de pop non déclenché / app non quittée).
|
||||
4. **Green** : implémenter l'interception.
|
||||
5. **Validation manuelle** : sur appareil, parcourir l'écran enfant et tenter toutes les sorties (retour, accueil, multitâche) → bloquées ; consigner.
|
||||
6. **Refactor**.
|
||||
|
||||
## Definition of Done
|
||||
- Tests d'épinglage auto + interception retour verts.
|
||||
- Audit manuel des sorties UI réalisé sur appareil, résultats consignés.
|
||||
- `tool/check.sh` passe ; étape 4.2 cochée dans `ROADMAP.md`.
|
||||
|
||||
## Risques / notes
|
||||
- Le re-épinglage au `resumed` doit éviter les boucles/flickers : tester le comportement de reprise.
|
||||
@@ -0,0 +1,26 @@
|
||||
# Jalon 4 — Espace enfant
|
||||
|
||||
## Objectif
|
||||
Assembler l'écran que l'enfant utilise : liste des histoires disponibles (titres
|
||||
cliquables) + lecteur, le tout dans une coquille **verrouillée** (épinglage auto,
|
||||
aucune échappatoire via l'UI).
|
||||
|
||||
## Périmètre
|
||||
- Liste des épisodes de tous les abonnements (ou par podcast), avec titre + vignette.
|
||||
- Sélection d'un titre → lecture (réutilise le lecteur de J2).
|
||||
- Épinglage déclenché automatiquement à l'entrée dans l'espace enfant (J1).
|
||||
- Aucune action UI ne permet de quitter l'app ou d'accéder au système.
|
||||
|
||||
## Hors-périmètre
|
||||
- Limites/avertissements (J6).
|
||||
- L'accès à l'espace parent (icône) est posé ici mais la **porte** (code) vient en J5 ; en attendant, accès dev temporaire.
|
||||
|
||||
## Étapes
|
||||
1. [4.1 — Liste des histoires](01-liste-histoires.md)
|
||||
2. [4.2 — Navigation verrouillée](02-navigation-verrouillee.md)
|
||||
|
||||
## Definition of Done (jalon)
|
||||
- L'enfant voit la liste, tape un titre, l'histoire se lit.
|
||||
- À l'ouverture de l'espace enfant, l'app s'épingle automatiquement.
|
||||
- Aucun bouton/geste UI ne sort de l'app (hors mécanisme système + PIN).
|
||||
- `tool/check.sh` passe ; `ROADMAP.md` 4.1→4.2 cochées.
|
||||
Reference in New Issue
Block a user