142 lines
4.9 KiB
Markdown
142 lines
4.9 KiB
Markdown
# 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<T>()`.
|
|
|
|
### 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 |
|