# 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.