# TrainHub AI-powered training management desktop application for personal trainers. Features on-device AI chat with RAG, video analysis, program scheduling, and exercise library management. ## Architecture ``` lib/ ├── core/ # Shared constants, extensions, router, theme, utils ├── domain/ # Business entities and repository interfaces │ ├── entities/ # Freezed immutable models │ └── repositories/ # Abstract repository contracts ├── data/ # Infrastructure and data access │ ├── database/ # Drift ORM schema, DAOs │ ├── mappers/ # Entity <-> DTO conversion │ ├── repositories/ # Repository implementations │ └── services/ # External service integrations (AI, embeddings) └── presentation/ # UI layer ├── analysis/ # Video analysis feature ├── calendar/ # Program calendar ├── chat/ # AI chat with RAG ├── common/ # Shared widgets and dialogs ├── home/ # Dashboard ├── plan_editor/ # Training plan builder ├── settings/ # App settings and model management ├── shell/ # Main app layout (sidebar + tabs) ├── trainings/ # Training list management ├── welcome/ # First-launch onboarding └── workout_session/ # Active workout tracking ``` **Layers:** - **Domain** -- Pure Dart. Entities (Freezed), abstract repository interfaces. No framework imports. - **Data** -- Drift database, DAOs, mappers, repository implementations, AI services (llama.cpp, Nomic). - **Presentation** -- Flutter widgets, Riverpod controllers, Freezed UI states. ## Tech Stack | Layer | Technology | |---|---| | UI | Flutter 3.x, Material Design 3, shadcn_ui | | State | Riverpod 2.6 with code generation | | Routing | AutoRoute 9.2 | | Database | Drift 2.14 (SQLite) | | DI | get_it 8.0 | | Immutability | Freezed 2.5 | | Local AI | llama.cpp (Qwen 2.5 7B + Nomic Embed v1.5) | | Video | media_kit | ## Getting Started ### Prerequisites - Flutter SDK (stable channel) - Dart SDK >= 3.10.7 - Desktop platform toolchain (Visual Studio for Windows, Xcode for macOS) ### Setup ```bash # Install dependencies flutter pub get # Run code generation dart run build_runner build --delete-conflicting-outputs # Launch app flutter run -d windows # or macos, linux ``` ### AI Models The app uses local AI inference via llama.cpp. Models are downloaded automatically on first launch or from **Settings > AI Models**: - **llama-server** binary (llama.cpp build b8130) - **Qwen 2.5 7B Instruct Q4_K_M** (~4.7 GB) -- chat/reasoning - **Nomic Embed Text v1.5 Q4_K_M** (~300 MB) -- text embeddings for RAG Models are stored in the system documents directory. Total download: ~5 GB. AI configuration constants are centralized in `lib/core/constants/ai_constants.dart`. ## Code Generation This project relies on code generation for several packages. After modifying any annotated files, run: ```bash dart run build_runner build --delete-conflicting-outputs ``` Generated files (do not edit manually): - `*.freezed.dart` -- Freezed immutable models - `*.g.dart` -- Drift DAOs, Riverpod providers, JSON serialization - `app_router.gr.dart` -- AutoRoute generated routes ## Key Conventions ### State Management Each feature follows the controller + state pattern: ``` feature/ ├── feature_page.dart # @RoutePage widget ├── feature_controller.dart # @riverpod controller ├── feature_state.dart # @freezed state model └── widgets/ # Extracted sub-widgets ``` Controllers are `@riverpod` classes that manage async state. States are `@freezed` classes. ### Dependency Injection Services and repositories are registered in `lib/injection.dart` using get_it: - **Singletons** -- database, DAOs, AI services - **Lazy singletons** -- repositories Controllers access dependencies via `getIt()`. ### Naming - **Files/directories:** `snake_case` - **Classes:** `PascalCase` - **Variables/methods:** `camelCase` - **Constants:** `UPPER_CASE` for environment variables, `camelCase` for class constants - **Booleans:** prefix with `is`, `has`, `can` (e.g., `isLoading`, `hasError`) - **Functions:** start with a verb (e.g., `loadSession`, `createProgram`) ### Widget Extraction Keep page files under 200 lines. Extract standalone widget classes into a `widgets/` subdirectory within the feature folder. ## Project Configuration | File | Purpose | |---|---| | `lib/core/constants/app_constants.dart` | App name, version, window sizes | | `lib/core/constants/ai_constants.dart` | AI model config, ports, URLs | | `lib/core/constants/ui_constants.dart` | Spacing, border radius, animation duration | | `lib/core/theme/app_colors.dart` | Zinc palette, semantic colors | | `lib/core/theme/app_theme.dart` | Material 3 dark theme |