Files
storytime/docs/specs/00-vision-architecture.md
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

3.5 KiB

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