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,37 @@
|
||||
# 0.1 — Structure du projet & arborescence
|
||||
|
||||
## Objectif
|
||||
Créer le projet Flutter Android et l'arborescence clean architecture cible.
|
||||
|
||||
## Périmètre & hors-périmètre
|
||||
- Inclus : `flutter create` (Android only), arborescence `lib/core` + `lib/features/*`, `main.dart` minimal, dépendances de base au `pubspec.yaml`.
|
||||
- Exclus : toute logique métier.
|
||||
|
||||
## Dépendances
|
||||
Aucune (première étape).
|
||||
|
||||
## Conception
|
||||
- Cibler Android uniquement (`--platforms=android`).
|
||||
- Arborescence (cf. CLAUDE.md §4) :
|
||||
```
|
||||
lib/core/{error,theme,router,di}
|
||||
lib/features/{locking,playback,podcasts,parental,limits}
|
||||
```
|
||||
Chaque feature reçoit les sous-dossiers `domain/ application/ data/ presentation/` (placeholders avec un `.gitkeep` ou un fichier barrel vide).
|
||||
- `pubspec.yaml` : ajouter `flutter_riverpod`. Les autres paquets (`just_audio`, `kiosk_mode`, …) seront ajoutés **au jalon qui les utilise** (YAGNI).
|
||||
- `main.dart` : `ProviderScope` + `MaterialApp` avec un écran d'accueil placeholder.
|
||||
|
||||
## Plan TDD
|
||||
La création de squelette est surtout structurelle ; le test porte sur le démarrage :
|
||||
1. **Red** : test de widget `app_boots_test.dart` — `pumpWidget(StorytimeApp())` attend de trouver le placeholder (texte « Storytime »). Échoue tant que l'app n'existe pas.
|
||||
2. **Green** : créer `StorytimeApp` + écran placeholder.
|
||||
3. **Refactor** : extraire le thème/router si nécessaire (sera étoffé en 0.3).
|
||||
|
||||
## Definition of Done
|
||||
- `flutter run` démarre l'app.
|
||||
- `app_boots_test.dart` vert.
|
||||
- Arborescence conforme.
|
||||
- Étape 0.1 cochée dans `ROADMAP.md`.
|
||||
|
||||
## Risques / notes
|
||||
- Vérifier la version Flutter/Dart utilisée et la consigner (ex. dans le README projet) pour reproductibilité.
|
||||
@@ -0,0 +1,35 @@
|
||||
# 0.2 — Outillage qualité
|
||||
|
||||
## Objectif
|
||||
Garantir un code uniformément formaté, sans warning, et vérifiable d'une commande.
|
||||
|
||||
## Périmètre & hors-périmètre
|
||||
- Inclus : lint strict, format, script de vérification locale, conventions de test.
|
||||
- Exclus : CI distante (GitHub Actions, etc.) — peut venir plus tard, hors v1.
|
||||
|
||||
## Dépendances
|
||||
0.1 (projet existant).
|
||||
|
||||
## Conception
|
||||
- `analysis_options.yaml` : partir de `flutter_lints`, puis durcir (ex. `prefer_const_constructors`, `always_declare_return_types`, `require_trailing_commas`, interdiction de `print`). Objectif **0 warning**.
|
||||
- Ajouter `mocktail` en `dev_dependencies` (mocks pour les tests à venir).
|
||||
- **Script « CI locale »** `tool/check.sh` enchaînant :
|
||||
1. `dart format --set-exit-if-changed .`
|
||||
2. `flutter analyze`
|
||||
3. `flutter test`
|
||||
Code de sortie non nul si l'une échoue.
|
||||
- Documenter dans le README projet : « avant de cocher une étape, `tool/check.sh` doit passer ».
|
||||
|
||||
## Plan TDD
|
||||
Étape outillage : la « preuve » est l'exécution du script.
|
||||
1. Écrire `tool/check.sh`.
|
||||
2. Le lancer : il doit passer sur le squelette de 0.1 (format OK, analyze 0 issue, test 0.1 vert).
|
||||
3. Vérifier qu'il **échoue** volontairement si on introduit un fichier mal formaté (test du garde-fou), puis rétablir.
|
||||
|
||||
## Definition of Done
|
||||
- `tool/check.sh` passe intégralement.
|
||||
- `flutter analyze` : 0 issue.
|
||||
- Étape 0.2 cochée dans `ROADMAP.md`.
|
||||
|
||||
## Risques / notes
|
||||
- Garder le lint strict mais pragmatique : si une règle gêne sans valeur, la désactiver explicitement avec un commentaire justificatif plutôt que de la subir.
|
||||
@@ -0,0 +1,36 @@
|
||||
# 0.3 — Socle transverse
|
||||
|
||||
## Objectif
|
||||
Fournir les briques transverses réutilisées par toutes les features : gestion
|
||||
d'erreur typée, thème, navigation, et amorce de DI Riverpod.
|
||||
|
||||
## Périmètre & hors-périmètre
|
||||
- Inclus : `Result`/`Failure`, thème Material 3 (palette douce « coucher »), router, organisation DI.
|
||||
- Exclus : providers métier (créés par chaque feature).
|
||||
|
||||
## Dépendances
|
||||
0.1, 0.2.
|
||||
|
||||
## Conception
|
||||
- **`core/error/`** :
|
||||
- `Failure` (classe scellée/sealed) avec sous-types de base : `NetworkFailure`, `NotFoundFailure`, `UnexpectedFailure`. Les features ajouteront les leurs.
|
||||
- `Result<S>` : type `sealed` `Ok<S>(value)` / `Err(Failure)`, avec helpers (`map`, `when`, `fold`). (Ou adopter `dartz`/`fpdart` `Either` — choisir et figer dans CLAUDE.md §7.)
|
||||
- **`core/theme/`** : `AppTheme` Material 3, couleurs douces, gros composants tactiles (cible enfant), contrastes lisibles le soir.
|
||||
- **`core/router/`** : router (`go_router` ou Navigator 2 simple) avec routes nommées : `child` (défaut), `parentGate`, `parent`. Pas encore d'écrans réels.
|
||||
- **`core/di/`** : conventions d'organisation des providers (un fichier `providers.dart` par feature, agrégés). `ProviderScope` racine dans `main.dart`.
|
||||
|
||||
## Plan TDD
|
||||
1. **Red** : `result_test.dart` — `Ok(1).map((v) => v+1)` donne `Ok(2)` ; `Err(f).map(...)` reste `Err(f)` ; `fold`/`when` aiguillent correctement. Échoue (type absent).
|
||||
2. **Green** : implémenter `Result`/`Failure`.
|
||||
3. **Red** : `theme_test.dart` (widget) — un `MaterialApp` avec `AppTheme` expose `useMaterial3 == true` et la couleur primaire attendue.
|
||||
4. **Green** : implémenter `AppTheme`.
|
||||
5. **Refactor** : nettoyer, documenter les helpers.
|
||||
|
||||
## Definition of Done
|
||||
- Tests `result_test.dart` et `theme_test.dart` verts.
|
||||
- App démarre avec le thème appliqué et le router en place (route `child` placeholder).
|
||||
- `tool/check.sh` passe.
|
||||
- Étape 0.3 cochée dans `ROADMAP.md` ; choix `Result` maison vs `fpdart` consigné dans CLAUDE.md §7.
|
||||
|
||||
## Risques / notes
|
||||
- Ne pas sur-concevoir le `Result` : juste ce que les use cases consommeront. Étoffer au besoin réel.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Jalon 0 — Fondations
|
||||
|
||||
## Objectif
|
||||
Poser un projet Flutter sain : arborescence clean architecture, outillage qualité
|
||||
strict, et le socle transverse (gestion d'erreur, thème, navigation, DI) sur lequel
|
||||
tous les autres jalons s'appuient.
|
||||
|
||||
## Périmètre
|
||||
- Création du projet Flutter Android.
|
||||
- Arborescence `core/` + `features/` (dossiers vides prêts à recevoir les features).
|
||||
- Lint strict, format, script de vérification local (« CI locale »).
|
||||
- Type `Result`/`Failure`, thème Material 3, router, conteneur Riverpod.
|
||||
|
||||
## Hors-périmètre
|
||||
Aucune feature métier. Pas d'UI fonctionnelle au-delà d'un écran d'accueil placeholder.
|
||||
|
||||
## Étapes
|
||||
1. [0.1 — Structure du projet & arborescence](01-structure-projet.md)
|
||||
2. [0.2 — Outillage qualité](02-outillage-qualite.md)
|
||||
3. [0.3 — Socle transverse](03-socle-transverse.md)
|
||||
|
||||
## Definition of Done (jalon)
|
||||
- `flutter run` démarre l'app (écran placeholder) sur émulateur/appareil.
|
||||
- `flutter analyze` : 0 issue. `dart format --set-exit-if-changed` : OK.
|
||||
- Tests du socle transverse verts.
|
||||
- Arborescence conforme à CLAUDE.md §4.
|
||||
- `ROADMAP.md` : étapes 0.1→0.3 cochées.
|
||||
Reference in New Issue
Block a user