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,39 @@
|
||||
# 5.1 — Création du code au premier lancement
|
||||
|
||||
## Objectif
|
||||
Au tout premier lancement, obliger le parent à créer un code à 4 chiffres (saisi
|
||||
deux fois pour confirmation) avant d'accéder à l'app.
|
||||
|
||||
## Périmètre & hors-périmètre
|
||||
- Inclus : détection « pas de code défini », écran de création (double saisie + validation), enregistrement.
|
||||
- Exclus : stockage technique détaillé (5.2), porte d'accès (5.3).
|
||||
|
||||
## Dépendances
|
||||
Jalon 0. (Le stockage de 5.2 peut être développé en parallèle/avant ; ici on consomme son interface.)
|
||||
|
||||
## Conception
|
||||
- **Domain** (`features/parental/domain/`) :
|
||||
- `ParentalCode` (value object) : exactement 4 chiffres ; invariant validé à la construction (sinon `Err(InvalidCodeFormat)`).
|
||||
- `ParentalCodeRepository` (interface) : `Future<bool> isConfigured()`, `Future<Result<Unit>> setCode(ParentalCode code)`, `Future<bool> verify(ParentalCode code)`. (Impl. en 5.2.)
|
||||
- **Application** :
|
||||
- `IsCodeConfiguredUseCase`, `SetParentalCodeUseCase` (refuse si déjà configuré, ou autorise via flux dédié — documenter).
|
||||
- **Presentation** :
|
||||
- Au démarrage, `IsCodeConfiguredUseCase` décide : non configuré → `CreateCodeView` bloquant ; configuré → espace enfant.
|
||||
- `CreateCodeView` : saisie 1 + saisie 2, contrôle d'égalité, format 4 chiffres, gros pavé numérique adapté.
|
||||
|
||||
## Plan TDD
|
||||
1. **Red** : `parental_code_test.dart` — `ParentalCode('1234')` OK ; `'12'`, `'12a4'`, `''` → invalides.
|
||||
2. **Green** : implémenter le value object.
|
||||
3. **Red** : `set_parental_code_use_case_test.dart` — délègue à `setCode` ; refuse si déjà configuré (selon règle documentée).
|
||||
4. **Green** : implémenter.
|
||||
5. **Red** : `create_code_view_test.dart` (widget) — deux saisies différentes → erreur affichée, pas d'enregistrement ; deux saisies égales valides → `SetParentalCodeUseCase` appelé.
|
||||
6. **Green** : implémenter l'écran.
|
||||
7. **Refactor**.
|
||||
|
||||
## Definition of Done
|
||||
- Tests value object + use case + widget verts.
|
||||
- Premier lancement impose la création ; lancement ultérieur ne la redemande pas.
|
||||
- `tool/check.sh` passe ; étape 5.1 cochée dans `ROADMAP.md`.
|
||||
|
||||
## Risques / notes
|
||||
- Ne jamais logguer le code. Le value object ne doit pas exposer la valeur en clair dans `toString`.
|
||||
@@ -0,0 +1,36 @@
|
||||
# 5.2 — Stockage sécurisé & vérification
|
||||
|
||||
## Objectif
|
||||
Implémenter `ParentalCodeRepository` : stocker le code de façon sûre (haché, jamais
|
||||
en clair) et vérifier une saisie.
|
||||
|
||||
## Périmètre & hors-périmètre
|
||||
- Inclus : hachage du code, stockage via `flutter_secure_storage`, vérification.
|
||||
- Exclus : écrans (5.1/5.3).
|
||||
|
||||
## Dépendances
|
||||
5.1 (interface + `ParentalCode`).
|
||||
|
||||
## Conception
|
||||
- **Data** (`features/parental/data/`) :
|
||||
- `SecureParentalCodeRepository implements ParentalCodeRepository`.
|
||||
- Stocke un **hachage** du code (+ sel) dans `flutter_secure_storage` — jamais la valeur en clair.
|
||||
- Pour 4 chiffres, l'espace est petit (10 000 combinaisons) : le hachage protège contre la lecture directe du stockage, sans prétendre à une résistance forte au brute-force hors-ligne. C'est cohérent avec le modèle de menace (garde-fou enfant, cf. CLAUDE.md §1). Documenter ce choix.
|
||||
- `isConfigured()` = présence de la clé ; `verify(code)` = comparaison des hachages (comparaison à temps constant si simple à faire).
|
||||
- **DI** : `parentalCodeRepositoryProvider`.
|
||||
|
||||
## Plan TDD
|
||||
1. **Red** : `secure_parental_code_repository_test.dart` — avec un `flutter_secure_storage` mocké :
|
||||
- `setCode` écrit une valeur **différente** du code en clair (hachée).
|
||||
- `verify` renvoie `true` pour le bon code, `false` sinon.
|
||||
- `isConfigured` reflète la présence de la clé.
|
||||
2. **Green** : implémenter hachage + repository.
|
||||
3. **Refactor**.
|
||||
|
||||
## Definition of Done
|
||||
- Tests verts ; aucune écriture du code en clair (vérifié par le test).
|
||||
- `tool/check.sh` passe ; étape 5.2 cochée dans `ROADMAP.md` ; choix du modèle de menace consigné.
|
||||
|
||||
## Risques / notes
|
||||
- `flutter_secure_storage` s'appuie sur le Keystore Android : tester aussi le cas « valeur absente » au premier lancement.
|
||||
- Ne pas réinventer de crypto : utiliser une fonction de hachage standard de `crypto`.
|
||||
@@ -0,0 +1,37 @@
|
||||
# 5.3 — Accès à l'espace parent & abritage de la gestion podcasts
|
||||
|
||||
## Objectif
|
||||
Relier l'icône discrète de l'écran enfant à une porte parentale (saisie du code)
|
||||
qui ouvre l'espace parent, et y intégrer la gestion des abonnements (J3).
|
||||
|
||||
## Périmètre & hors-périmètre
|
||||
- Inclus : porte parentale (saisie + vérification), espace parent, déplacement de la gestion podcasts (J3) derrière cette porte.
|
||||
- Exclus : réglages de limites (J6, qui s'ajouteront à l'espace parent).
|
||||
|
||||
## Dépendances
|
||||
5.1, 5.2 (code + vérification), 3.x (gestion podcasts), 4.2 (icône posée).
|
||||
|
||||
## Conception
|
||||
- **Application** : `VerifyParentalCodeUseCase` (utilise `ParentalCodeRepository.verify`).
|
||||
- **Presentation** (`features/parental/presentation/`) :
|
||||
- `ParentGateView` : pavé numérique, saisie 4 chiffres → `VerifyParentalCodeUseCase`. Bon code → navigation espace parent ; mauvais → message + reset saisie. Anti-spam simple (léger délai après N échecs) optionnel, documenté.
|
||||
- `ParentHomeView` : menu de l'espace parent → « Mes podcasts » (écrans de J3), « Réglages » (changer le code), placeholder « Limites » (rempli en J6).
|
||||
- Brancher les écrans de gestion podcasts de J3 ici, et **retirer l'accès dev temporaire** mis en place au J3.
|
||||
- Sortie de l'espace parent → retour à l'écran enfant (qui réactive l'épinglage, J4).
|
||||
|
||||
## Plan TDD
|
||||
1. **Red** : `verify_parental_code_use_case_test.dart` — bon code → `true` ; mauvais → `false` (repo mocké).
|
||||
2. **Green** : implémenter.
|
||||
3. **Red** : `parent_gate_view_test.dart` (widget) — saisie correcte → navigation vers l'espace parent (provider mocké) ; incorrecte → message d'erreur, pas de navigation.
|
||||
4. **Green** : implémenter la porte.
|
||||
5. **Red** : `parent_home_view_test.dart` — les entrées de menu mènent aux écrans attendus (podcasts, réglages).
|
||||
6. **Green** : implémenter l'espace parent + câbler la gestion podcasts.
|
||||
7. **Refactor** : supprimer l'accès dev temporaire de J3 ; vérifier qu'on n'atteint plus la gestion podcasts sans code.
|
||||
|
||||
## Definition of Done
|
||||
- Tests use case + porte + accueil parent verts.
|
||||
- Depuis l'écran enfant : ⚙️ → code correct → gestion des podcasts ; code incorrect → refus ; aucun accès à la gestion sans code.
|
||||
- `tool/check.sh` passe ; étape 5.3 cochée dans `ROADMAP.md`.
|
||||
|
||||
## Risques / notes
|
||||
- Vérifier qu'aucune route résiduelle (dev J3) ne contourne la porte parentale.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Jalon 5 — Code parental & espace parent
|
||||
|
||||
## Objectif
|
||||
Mettre en place le code parental (création au premier lancement, vérification) et
|
||||
l'espace parent protégé qui abrite la gestion des podcasts (J3) et, plus tard, les
|
||||
limites (J6).
|
||||
|
||||
## Périmètre
|
||||
- Création du code à 4 chiffres au premier lancement (double saisie).
|
||||
- Stockage sécurisé du code (haché, jamais en clair).
|
||||
- Porte parentale : icône discrète → saisie du code → espace parent.
|
||||
- Espace parent abritant la gestion des abonnements (déplacée depuis l'accès dev de J3).
|
||||
|
||||
## Hors-périmètre
|
||||
- Récupération de code oublié : **exclu v1** (réinstaller réinitialise tout — décision actée).
|
||||
- Réglages de limites : posés en J6 (l'espace parent les accueillera).
|
||||
|
||||
## Étapes
|
||||
1. [5.1 — Création du code au premier lancement](01-creation-code.md)
|
||||
2. [5.2 — Stockage sécurisé & vérification](02-stockage-securise.md)
|
||||
3. [5.3 — Accès à l'espace parent & abritage gestion podcasts](03-acces-espace-parent.md)
|
||||
|
||||
## Definition of Done (jalon)
|
||||
- Premier lancement → création du code obligatoire ; relances suivantes → pas redemandé.
|
||||
- Code stocké haché ; vérification correcte/incorrecte gérée.
|
||||
- L'icône ⚙️ ouvre la porte parentale ; bon code → espace parent (gestion podcasts) ; mauvais code → refus.
|
||||
- `tool/check.sh` passe ; `ROADMAP.md` 5.1→5.3 cochées.
|
||||
Reference in New Issue
Block a user