Files
storytime/docs/specs/00-vision-architecture.md
T
Vincent Bourdon 16fd4c8c36 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>
2026-06-19 17:03:33 +02:00

65 lines
3.5 KiB
Markdown

# Vision & architecture
## Vision produit
Storytime transforme une tablette Android en **lecteur d'histoires du soir cadenassé**.
L'enfant choisit et écoute des histoires (épisodes de podcasts) sans pouvoir sortir
de l'application ni accéder au reste de la tablette. Le parent garde le contrôle :
il sélectionne les sources, définit un code parental et fixe des limites (temps /
nombre d'histoires) adaptées au rituel du coucher.
### Utilisateurs
- **Enfant** (sait lire, choisit par le titre) : interface minimale, gros boutons.
- **Parent** : configuration protégée par code 4 chiffres.
### Périmètre v1
Inclus : lecture en streaming, recherche annuaire + ajout RSS, liste d'histoires,
épinglage, code parental, limites (temps + nombre) avec avertissements doux.
Exclus v1 : téléchargement hors-ligne, multi-profils enfants, multi-plateforme,
récupération de code par question secrète (réinstaller réinitialise).
## Architecture cible
Clean Architecture, feature-first. Détail des couches et de la règle de dépendance
dans [`../../CLAUDE.md`](../../CLAUDE.md) §3-4. Rappel du flux :
```
Presentation (Riverpod/UI) → Application (use cases) → Domain ← Data (infra)
```
### Features et leurs responsabilités
| Feature | Responsabilité | Dépendances externes (couche data) |
|---------|----------------|-------------------------------------|
| `locking` | Épingler/désépingler l'app, état de verrouillage | plugin `kiosk_mode` / channel Kotlin |
| `playback` | Lire un épisode, pause, suivant, progression | `just_audio`, `audio_service` |
| `podcasts` | Rechercher, ajouter (RSS), persister les abonnements, lister les épisodes | iTunes Search, `dart_rss`, SQLite |
| `parental` | Créer/vérifier le code, garder l'accès parent | `flutter_secure_storage` |
| `limits` | Compter temps & histoires, avertir, arrêter, reset quotidien | `shared_preferences` |
### Flux de données type (lecture d'une histoire)
1. `presentation` (écran enfant) lit la liste via `ListEpisodesUseCase`.
2. L'enfant tape un titre → `PlayStoryUseCase` (application) demande au `PlaybackRepository` (domain) de jouer ; l'impl. (data) pilote `just_audio`.
3. `limits` observe les événements de lecture (histoire démarrée, temps écoulé) et déclenche avertissements / arrêt.
4. `locking` maintient l'épinglage tout au long.
## Principes transverses
- **Result/Failure** plutôt qu'exceptions traversantes (cf. CLAUDE.md §4).
- **Immuabilité** des entités et états.
- **DI par Riverpod** ; tout est *overridable* en test.
- **Messages enfant rassurants**, jamais d'erreur technique brute à l'écran enfant.
- **Honnêteté de l'UI sur le verrouillage** : ne pas laisser croire à une protection plus forte que ce que l'épinglage natif offre réellement.
## Ordre de construction & dépendances
- **J0** pose le squelette → prérequis de tout.
- **J1** valide l'épinglage → **bloquant** : conditionne la viabilité du produit.
- **J2** lecture audio (testable avec un flux en dur).
- **J3** podcasts (recherche + RSS + persistance).
- **J4** espace enfant : consomme J2 (lecture) + J3 (liste) + J1 (verrouillage).
- **J5** code parental + espace parent : **abrite** la gestion podcasts de J3 derrière le code.
- **J6** limites : s'appuie sur les événements de J2 et l'arrêt/reprise gérés avec J5.
> Note de dépendance J3↔J5 : J3 construit le domaine podcasts + un écran d'accès
> temporaire (dev) ; J5 déplace cet accès derrière la porte parentale. Documenté
> dans les specs concernées.