study-dashboard/docs/architecture.md

36 lines
2.5 KiB
Markdown

# Study Dashboard Architecture
## Goals
- Embrace MVVM to keep views (Qt widgets) dumb and push logic into view models.
- Use dependency injection for explicit wiring of repositories, services and view models.
- Keep persistence simple with a local SQLite file that the app can create and seed automatically.
- Maintain TDD-friendly seams so repositories and view models stay unit-testable without the GUI.
## Layers
| Layer | Responsibilities |
|--------------|--------------------------------------------------------------------------------------------------|
| View (PySide6)| Defines widgets/layouts, binds to view-model signals/slots, contains German UI text. |
| ViewModel | Exposes observable properties and commands (Qt signals/slots), orchestrates services asynchronously if needed. |
| Services | Aggregate domain operations (e.g., progress tracking, calendar queries) built on repositories. |
| Repositories | Talk to SQLite using `sqlite3`, handle schema migrations/bootstrap and raw queries. |
| Infrastructure | Dependency injection container, configuration (paths, environment), logging, bootstrap. |
## Dependency Injection Flow
1. `ApplicationContainer` defines providers for configuration (DB path), SQLite connections, repositories, services and view models.
2. `main.py` initialises the container, triggers database bootstrap (create file, apply schema, seed demo data), then builds the QApplication + `MainView`.
3. The view receives its view model via DI so it can subscribe to signals and send commands without knowing about repositories.
## Database Bootstrap
- Database file: `study.db` at repo root (configurable via container if needed).
- Tables: `modules`, `exams`, `appointments` (calendar tile).
- On first launch the bootstrapper:
1. Creates the file and tables if they do not exist.
2. Inserts demo data (e.g., three modules with credits/status, two upcoming exams, two appointments).
- Seeding runs idempotently: existing rows are left intact to avoid wiping user data.
## Testing Approach
- Repository tests use a temporary SQLite database (in-memory or tmp directory) to validate schema + CRUD logic.
- View model tests stub repositories/services via dependency injection to simulate responses and assert emitted signals.
- GUI level tests stay minimal for now; focus on logic-heavy layers for fast feedback.
- Aim for “test-first” when touching new behavior, mirroring a TDD workflow.