timetracker/.ai/architecture.md
2026-08-03 21:51:48 +02:00

2.3 KiB

Architecture — Decisions & Rationale

ADR-001: Flutter as framework

Decision: Flutter (not React Native or native). Reason: Single codebase for Android + iOS + Web; Dart type safety; strong Material 3 support; flet-managed Flutter SDK already present.

ADR-002: Riverpod for state management

Decision: Riverpod with code generation (riverpod_annotation). Reason: Compile-time safety; no BuildContext required for providers; excellent async support (AsyncNotifier); easy testing via ProviderContainer overrides. Rejected: Bloc (too verbose), Provider (deprecated patterns), GetX (opinionated anti-patterns).

ADR-003: Drift (formerly Moor) for local database

Decision: Drift + sqlite3_flutter_libs. Reason: Type-safe SQL in Dart; reactive streams out of the box; strong migration support; works on all Flutter platforms incl. Web (via WASM). Rejected: Hive (no relations), Isar (less mature migration story).

ADR-004: Offline-first, no backend

Decision: All data stored locally on device. Reason: Privacy, no auth complexity, works without internet. Future: optional cloud sync (Supabase/Firebase) can be added as a separate sync feature without touching existing data layer.

ADR-005: go_router for navigation

Decision: go_router with StatefulShellRoute. Reason: Official Flutter navigation package; deep link support; URL-based routing works for Web target; StatefulShellRoute preserves bottom-nav state.

ADR-006: Feature-first directory structure

Decision: lib/features/<name>/{data,domain,presentation}/ Reason: Features can be developed and reviewed in isolation; clear ownership; easier to add/remove features without touching unrelated code. Each feature's data/ holds repositories and DAOs, domain/ holds models and providers, presentation/ holds screens and widgets.

ADR-007: freezed for domain models

Decision: All domain models use freezed. Reason: Immutability enforced at compile time; copyWith generated; == and hashCode correct; union types for state (e.g. TimerState).

ADR-008: Multilingual from day one

Decision: flutter_localizations + ARB files, no hardcoded strings. Reason: Avoids costly retro-fitting; supports en + de initially; easily extensible by adding new ARB files.