# ashok-a15/ai_story_buddy architecture

> Architecture diagram of the GitHub repository ashok-a15/ai_story_buddy, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ashok-a15/ai_story_buddy
- Repository: https://github.com/ashok-a15/ai_story_buddy

## Overview

1. **Overall shape**
   This is a **cross-platform Flutter app** with one primary product flow: a single story-reading screen that narrates a short story, then transitions into an interactive quiz. The business logic is concentrated in Dart under `lib/`, while `android/`, `ios/`, `macos/`, `linux/`, `windows/`, and `web/` are mostly standard Flutter host shells.

2. **Primary feature boundary**
   The app is organized as a **feature-centric mini-application** rather than a multi-module product. The core feature lives in `lib/screens/story_screen.dart`, supported by a small set of state, model, service, utility, and widget files. This makes the story/quiz experience the central architectural unit.

3. **State management spine**
   `lib/providers/story_provider.dart` is the main orchestration layer. The README indicates this uses **Riverpod** with an immutable notifier/state pair (`StoryNotifier` + `StoryStateData`) as the single source of truth. That state drives the screen’s progression through idle, loading, playing, quiz, success, and error-like conditions.

4. **Narration service boundary**
   Text-to-speech is encapsulated in `lib/services/tts_service.dart`. This is the app’s main service boundary and wraps the `flutter_tts` plugin. The service is responsible for narration lifecycle events such as start, completion, and error, while the provider reacts to those callbacks and updates UI state.

5. **Data-driven quiz layer**
   `lib/models/quiz_model.dart` defines the quiz data contract. The quiz is not hardcoded as fixed UI text; it is parsed from JSON and rendered dynamically, allowing question text and option count to vary without changing layout code. This is the main data model feeding the quiz phase.

6. **Presentation composition**
   The UI is split into small reusable widgets under `lib/widgets/`: `story_card`, `quiz_card`, `answer_option`, `primary_button`, and `buddy_character`. These form the screen’s visual building blocks and are composed by `story_screen.dart`. The `buddy_character` widget is especially important because Pip is the animated narrative companion and visual feedback anchor.

7. **Flow of control**
   The user experience follows a simple event pipeline: the child taps the story button, the provider moves into a loading/narration state, the TTS service speaks the story, and on completion the UI switches to the quiz card. Selecting an answer updates the provider again, which drives either a success celebration or a retry path.

8. **Visual and interaction styling**
   `lib/utils/theme.dart` and `lib/utils/constants.dart` centralize shared styling and app-wide values. The design is themed for children with soft gradients, rounded cards, and playful interaction cues. The architecture suggests the app relies on declarative widget state rather than imperative screen navigation.

9. **Platform integration**
   The native platform folders are mostly boilerplate Flutter runners, but they still matter architecturally because they host the plugin registrations and app entry points for each target OS. On Android and iOS, the app starts through the generated Flutter embedding and then immediately hands control to the Dart app. No custom native business logic appears in the tree.

10. **Testing and quality boundaries**
   There is a small widget test suite in `test/widget_test.dart` plus platform-specific runner tests in iOS/macOS. This indicates the app is tested primarily at the UI/widget level rather than through a large service or backend test surface. The README also calls out animation/test safeguards to avoid hanging tests.

11. **External dependencies that affect architecture**
   The only materially important external runtime dependency called out in the README is **Flutter TTS**. It directly shapes the app flow because narration completion determines when the quiz appears. Riverpod is the other key architectural dependency because it owns state transitions and UI updates.

12. **What is not present**
   There is no obvious server, database, authentication system, or multi-screen navigation structure in the repository tree. Architecturally, this is a **self-contained client app**: one screen, one state machine, one narration service, one dynamic quiz model, and a set of presentation widgets built around them.

Main entry points: [`lib/screens/story_screen.dart`](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/screens/story_screen.dart) (Story screen), [`lib/main.dart`](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/main.dart) (App entry), [`lib/providers/story_provider.dart`](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/providers/story_provider.dart) (Story provider), [`lib/widgets/quiz_card.dart`](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/quiz_card.dart) (Quiz card)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Flutter app"]
  node_main(("App entry<br/>bootstrap<br/>[main.dart]"))
  node_screen["Story screen<br/>ui screen<br/>[story_screen.dart]"]
  node_provider["Story provider<br/>riverpod state"]
  node_tts["TTS service<br/>narration service<br/>[tts_service.dart]"]
  node_quizmodel["Quiz model<br/>json model<br/>[quiz_model.dart]"]
  node_constants["Constants<br/>shared values<br/>[constants.dart]"]
  node_theme["Theme<br/>styling system<br/>[theme.dart]"]
  node_storycard["Story card<br/>presentation widget<br/>[story_card.dart]"]
  node_quizcard["Quiz card<br/>presentation widget<br/>[quiz_card.dart]"]
  node_answeroption["Answer option<br/>presentation widget<br/>[answer_option.dart]"]
  node_primarybutton["Primary button<br/>ui control"]
  node_buddy(("Buddy character<br/>character widget"))
end

subgraph group_platforms["Platform shells"]
  node_android["Android runner<br/>host shell<br/>[MainActivity.kt]"]
  node_ios["iOS runner<br/>host shell<br/>[AppDelegate.swift]"]
  node_macos["macOS runner<br/>host shell"]
  node_linux["Linux runner<br/>host shell<br/>[main.cc]"]
  node_windows["Windows runner<br/>host shell<br/>[main.cpp]"]
  node_web["Web shell<br/>host shell<br/>[index.html]"]
end

subgraph group_tests["Tests"]
  node_widgettest["Widget test<br/>ui test<br/>[widget_test.dart]"]
  node_ios_tests["iOS tests<br/>runner test<br/>[RunnerTests.swift]"]
  node_macos_tests["macOS tests<br/>runner test<br/>[RunnerTests.swift]"]
end

node_main -->|"launches"| node_screen
node_screen -->|"reads state"| node_provider
node_provider -->|"controls narration"| node_tts
node_provider -->|"loads quiz"| node_quizmodel
node_provider -->|"uses values"| node_constants
node_screen -->|"styles with"| node_theme
node_screen -->|"composes"| node_storycard
node_screen -->|"composes"| node_quizcard
node_screen -->|"shows"| node_buddy
node_quizcard -->|"renders"| node_answeroption
node_screen -->|"uses"| node_primarybutton
node_provider -->|"drives flow"| node_screen
node_tts -->|"callbacks"| node_provider
node_quizmodel -->|"feeds"| node_quizcard
node_android -->|"boots app"| node_main
node_ios -->|"boots app"| node_main
node_macos -->|"boots app"| node_main
node_linux -->|"boots app"| node_main
node_windows -->|"boots app"| node_main
node_web -->|"loads app"| node_main
node_widgettest -->|"covers"| node_screen
node_ios_tests -->|"covers"| node_ios
node_macos_tests -->|"covers"| node_macos

click node_main "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/main.dart"
click node_screen "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/screens/story_screen.dart"
click node_provider "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/providers/story_provider.dart"
click node_tts "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/services/tts_service.dart"
click node_quizmodel "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/models/quiz_model.dart"
click node_constants "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/utils/constants.dart"
click node_theme "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/utils/theme.dart"
click node_storycard "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/story_card.dart"
click node_quizcard "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/quiz_card.dart"
click node_answeroption "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/answer_option.dart"
click node_primarybutton "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/primary_button.dart"
click node_buddy "https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/buddy_character.dart"
click node_android "https://github.com/ashok-a15/ai_story_buddy/blob/main/android/app/src/main/kotlin/com/peblo/storybuddy/peblo_story_buddy/MainActivity.kt"
click node_ios "https://github.com/ashok-a15/ai_story_buddy/blob/main/ios/Runner/AppDelegate.swift"
click node_macos "https://github.com/ashok-a15/ai_story_buddy/blob/main/macos/Runner/MainFlutterWindow.swift"
click node_linux "https://github.com/ashok-a15/ai_story_buddy/blob/main/linux/runner/main.cc"
click node_windows "https://github.com/ashok-a15/ai_story_buddy/blob/main/windows/runner/main.cpp"
click node_web "https://github.com/ashok-a15/ai_story_buddy/blob/main/web/index.html"
click node_widgettest "https://github.com/ashok-a15/ai_story_buddy/blob/main/test/widget_test.dart"
click node_ios_tests "https://github.com/ashok-a15/ai_story_buddy/blob/main/ios/RunnerTests/RunnerTests.swift"
click node_macos_tests "https://github.com/ashok-a15/ai_story_buddy/blob/main/macos/RunnerTests/RunnerTests.swift"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_screen,node_provider,node_tts,node_quizmodel,node_constants,node_theme,node_storycard,node_quizcard,node_answeroption,node_primarybutton,node_buddy toneBlue
class node_android,node_ios,node_macos,node_linux,node_windows,node_web toneAmber
class node_widgettest,node_ios_tests,node_macos_tests toneMint
```

## Components

### Flutter app

Dart feature code that drives the story-to-quiz experience.

- [App entry](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/main.dart): bootstrap · Starts the Flutter app and wires the root widget. · `lib/main.dart`
- [Story screen](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/screens/story_screen.dart): ui screen · Single main screen that composes narration, quiz, and feedback states. · `lib/screens/story_screen.dart`
- [Story provider](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/providers/story_provider.dart): riverpod state · Orchestrates story playback, quiz progression, and answer outcomes. · `lib/providers/story_provider.dart`
- [TTS service](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/services/tts_service.dart): narration service · Wraps text-to-speech and reports playback lifecycle events. · `lib/services/tts_service.dart`
- [Quiz model](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/models/quiz_model.dart): json model · Defines the dynamic quiz data contract used during the quiz phase. · `lib/models/quiz_model.dart`
- [Constants](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/utils/constants.dart): shared values · Central app values and shared configuration constants. · `lib/utils/constants.dart`
- [Theme](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/utils/theme.dart): styling system · Shared colors, typography, and visual treatment for the child-friendly UI. · `lib/utils/theme.dart`
- [Story card](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/story_card.dart): presentation widget · Renders the narration prompt and story content area. · `lib/widgets/story_card.dart`
- [Quiz card](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/quiz_card.dart): presentation widget · Shows the quiz question and answer area after narration completes. · `lib/widgets/quiz_card.dart`
- [Answer option](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/answer_option.dart): presentation widget · Reusable selectable option used inside the quiz. · `lib/widgets/answer_option.dart`
- [Primary button](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/primary_button.dart): ui control · Shared call-to-action button for starting or advancing the flow. · `lib/widgets/primary_button.dart`
- [Buddy character](https://github.com/ashok-a15/ai_story_buddy/blob/main/lib/widgets/buddy_character.dart): character widget · Animated companion visual that anchors feedback and narration tone. · `lib/widgets/buddy_character.dart`

### Platform shells

Generated host runners for each supported target.

- [Android runner](https://github.com/ashok-a15/ai_story_buddy/blob/main/android/app/src/main/kotlin/com/peblo/storybuddy/peblo_story_buddy/MainActivity.kt): host shell · Android embedding and plugin entry point. · `android/app/src/main/kotlin/com/peblo/storybuddy/peblo_story_buddy/MainActivity.kt`
- [iOS runner](https://github.com/ashok-a15/ai_story_buddy/blob/main/ios/Runner/AppDelegate.swift): host shell · iOS embedding and app lifecycle entry point. · `ios/Runner/AppDelegate.swift`
- [macOS runner](https://github.com/ashok-a15/ai_story_buddy/blob/main/macos/Runner/MainFlutterWindow.swift): host shell · macOS embedding and desktop window entry point. · `macos/Runner/MainFlutterWindow.swift`
- [Linux runner](https://github.com/ashok-a15/ai_story_buddy/blob/main/linux/runner/main.cc): host shell · Linux desktop runner and generated plugin wiring. · `linux/runner/main.cc`
- [Windows runner](https://github.com/ashok-a15/ai_story_buddy/blob/main/windows/runner/main.cpp): host shell · Windows desktop runner and windowing entry point. · `windows/runner/main.cpp`
- [Web shell](https://github.com/ashok-a15/ai_story_buddy/blob/main/web/index.html): host shell · Web entry assets and manifest for browser deployment. · `web/index.html`

### Tests

UI and runner-level test coverage.

- [Widget test](https://github.com/ashok-a15/ai_story_buddy/blob/main/test/widget_test.dart): ui test · Primary automated UI coverage for the Flutter app. · `test/widget_test.dart`
- [iOS tests](https://github.com/ashok-a15/ai_story_buddy/blob/main/ios/RunnerTests/RunnerTests.swift): runner test · Native iOS test target scaffold. · `ios/RunnerTests/RunnerTests.swift`
- [macOS tests](https://github.com/ashok-a15/ai_story_buddy/blob/main/macos/RunnerTests/RunnerTests.swift): runner test · Native macOS test target scaffold. · `macos/RunnerTests/RunnerTests.swift`

## Connections

- App entry → Story screen: launches · Bootstraps the single product screen.
- Story screen → Story provider: reads state · UI reacts to the Riverpod story state machine.
- Story provider → TTS service: controls narration · Starts, observes, and reacts to TTS lifecycle events.
- Story provider → Quiz model: loads quiz · Parses and advances through dynamic quiz data.
- Story provider → Constants: uses values · Consumes shared app constants.
- Story screen → Theme: styles with · Applies the shared visual system.
- Story screen → Story card: composes · Shows narration and story content.
- Story screen → Quiz card: composes · Shows quiz interaction after narration completes.
- Story screen → Buddy character: shows · Uses the companion character for feedback and personality.
- Quiz card → Answer option: renders · Builds selectable answer choices.
- Story screen → Primary button: uses · Primary user action control for the flow.
- Story provider → Story screen: drives flow · State transitions switch the screen between story, quiz, success, and error-like conditions.
- TTS service → Story provider: callbacks · Narration completion and errors update state.
- Quiz model → Quiz card: feeds · Dynamic quiz data shapes the rendered quiz UI.
- Android runner → App entry: boots app · Native host starts the Flutter runtime.
- iOS runner → App entry: boots app · Native host starts the Flutter runtime.
- macOS runner → App entry: boots app · Native host starts the Flutter runtime.
- Linux runner → App entry: boots app · Native host starts the Flutter runtime.
- Windows runner → App entry: boots app · Native host starts the Flutter runtime.
- Web shell → App entry: loads app · Browser shell hosts the Flutter web build.
- Widget test → Story screen: covers · Primary UI-level automated coverage.
- iOS tests → iOS runner: covers · Native runner test scaffold.
- macOS tests → macOS runner: covers · Native runner test scaffold.
