From 7682d8317af2c5adf3f8d6ad09d174f1c0239411 Mon Sep 17 00:00:00 2001 From: Mike Kell Date: Fri, 16 Oct 2026 06:20:23 -0400 Subject: [PATCH] feat(medication): complete Phase 2 GLP-1 tracking, reminders, and dev bypass Domain (pure Dart): - Add 12-quadrant InjectionSite anatomical model with a least-recently-used rotation policy, DoseEntry entity, and Glp1Compound value object (Semaglutide 168h, Tirzepatide 120h, Liraglutide 13h) - Add CalculateSerumLevel use case implementing C(t) = sum(D_i * 0.5^((t - t_i) / t_half)) - Define IMedicationRepository contract; retire superseded MedicationDose Data: - Add injection-history CRUD to AppDatabase (watch/get/insert/update/delete/ latest-administered), ordered newest first - Implement drift-backed MedicationRepository with record-to-entity mapping Presentation and local alerts: - Add MedicationController (StateNotifier) managing serum estimation, site rotation suggestions, and best-effort reminder scheduling - Rework MedicationScreen: serum card, suggested-site card, interactive log dialog (compound, dosage, timestamp, quadrant), history with delete, and a 60s decay ticker - Add INotificationService / PlatformNotificationService wrapping flutter_local_notifications (one-shot scheduling on Android/iOS/macOS, graceful no-op on Web/Windows/Linux), Android boot receivers for reminder restoration, and the timezone dependency Development tooling: - Add debug-only "Continue Without Signing In" bypass on the login screen, backed by an in-memory devAuthBypassProvider; the router guard honors the flag and the shell shows a dev-mode banner while active Fixes: - Resolve the Supabase client lazily in SupabaseAuthService so widget tests and pre-initialization builds no longer throw Testing: - 36 new tests covering PK decay math, rotation determinism, repository CRUD on an in-memory drift database, controller behavior with fakes, and the end-to-end dev bypass flow; full suite green (37/37) - BUILD_STATE.md: mark Phase 2 complete and record all verification gates --- .clinerules | 4 +- BUILD_STATE.md | 30 ++ android/app/src/main/AndroidManifest.xml | 15 + lib/app/router/app_router.dart | 28 +- lib/app/scaffold/adaptive_home_scaffold.dart | 117 ++++-- lib/core/database/app_database.dart | 64 +++ lib/core/platform/notification_service.dart | 195 +++++++++ lib/core/utils/date_time_utils.dart | 38 ++ .../auth/data/supabase_auth_service.dart | 11 +- .../controllers/dev_auth_bypass.dart | 14 + .../presentation/screens/login_screen.dart | 39 ++ .../repositories/medication_repository.dart | 77 ++++ .../domain/entities/dose_entry.dart | 46 +++ .../domain/entities/injection_site.dart | 130 ++++++ .../domain/entities/medication_dose.dart | 32 -- .../repositories/medication_repository.dart | 25 ++ .../usecases/calculate_serum_level.dart | 69 ++++ .../domain/value_objects/glp1_compound.dart | 80 ++++ .../controllers/medication_controller.dart | 273 ++++++++++++ .../screens/medication_screen.dart | 388 ++++++++++++++++-- .../widgets/log_injection_dialog.dart | 231 +++++++++++ pubspec.lock | 2 +- pubspec.yaml | 2 + test/features/auth/dev_auth_bypass_test.dart | 107 +++++ .../data/medication_repository_test.dart | 112 +++++ .../domain/calculate_serum_level_test.dart | 141 +++++++ .../domain/injection_site_test.dart | 90 ++++ .../medication_controller_test.dart | 277 +++++++++++++ 28 files changed, 2521 insertions(+), 116 deletions(-) create mode 100644 BUILD_STATE.md create mode 100644 lib/core/platform/notification_service.dart create mode 100644 lib/core/utils/date_time_utils.dart create mode 100644 lib/features/auth/presentation/controllers/dev_auth_bypass.dart create mode 100644 lib/features/medication/data/repositories/medication_repository.dart create mode 100644 lib/features/medication/domain/entities/dose_entry.dart create mode 100644 lib/features/medication/domain/entities/injection_site.dart delete mode 100644 lib/features/medication/domain/entities/medication_dose.dart create mode 100644 lib/features/medication/domain/repositories/medication_repository.dart create mode 100644 lib/features/medication/domain/usecases/calculate_serum_level.dart create mode 100644 lib/features/medication/domain/value_objects/glp1_compound.dart create mode 100644 lib/features/medication/presentation/controllers/medication_controller.dart create mode 100644 lib/features/medication/presentation/widgets/log_injection_dialog.dart create mode 100644 test/features/auth/dev_auth_bypass_test.dart create mode 100644 test/features/medication/data/medication_repository_test.dart create mode 100644 test/features/medication/domain/calculate_serum_level_test.dart create mode 100644 test/features/medication/domain/injection_site_test.dart create mode 100644 test/features/medication/presentation/medication_controller_test.dart diff --git a/.clinerules b/.clinerules index e3ccaea..ea9179c 100644 --- a/.clinerules +++ b/.clinerules @@ -52,4 +52,6 @@ Each feature MUST contain: - Check code quality: flutter analyze - Run test suites: - flutter test \ No newline at end of file + flutter test + +Before starting any task, read BUILD_STATE.md to determine the current milestone. Upon satisfying all implementation steps and verification commands, update the checkboxes in BUILD_STATE.md before prompting the user. \ No newline at end of file diff --git a/BUILD_STATE.md b/BUILD_STATE.md new file mode 100644 index 0000000..d4144e3 --- /dev/null +++ b/BUILD_STATE.md @@ -0,0 +1,30 @@ +# Build Execution Ledger + +## Active Target +- **Current Milestone:** Phase 3: Nutrition, Protein Target Tracking & HealthGateway Sync +- **Status:** Phase 2 Complete + +## Phase Checklist +- [x] Phase 1: Foundation & Identity (Passwordless SSO & Encrypted Drift DB) +- [x] Phase 2: Medication Domain, Injection Rotation, Serum Modeling +- [ ] Phase 3: Nutrition, Protein Target Tracking, HealthGateway Sync +- [ ] Phase 4: Recipe Web Scraper Engine & Meal Planning Calendar +- [ ] Phase 5: Pantry Delta Engine & Auto-Shopping Generator +- [ ] Phase 6: Hardening, Native Desktop/Web Polish, CI/CD + +## Phase 2 Deliverables (2026-10-16) +- [x] Domain: `DoseEntry` entity, 12-quadrant `InjectionSite` rotation model, `Glp1Compound` value object (Sema 168h / Tirze 120h / Lira 13h), `IMedicationRepository` contract. +- [x] Domain: `CalculateSerumLevel` use case implementing `C(t) = Σ D_i · 0.5^((t − t_i)/t_half)`. +- [x] Data: injection-history CRUD on `AppDatabase` + drift-backed `MedicationRepository` (record ↔ entity mapping). +- [x] Presentation: `MedicationController` (Riverpod StateNotifier) with serum estimation, least-recently-used site rotation, and reminder scheduling; refactored `MedicationScreen` (serum card, rotation suggestion, interactive log dialog, history with delete). +- [x] Platform: `INotificationService` / `PlatformNotificationService` (flutter_local_notifications 17.x; Android/iOS/macOS scheduled reminders, graceful no-op on Web/Windows/Linux); Android boot-receiver manifest entries; `timezone` dependency added. +- [x] Regression fix: `SupabaseAuthService` now resolves its client lazily (baseline widget test no longer throws when Supabase is uninitialized). +- [x] Tests: 33 new unit/widget-fake tests (PK calculator, rotation policy, repository w/ in-memory drift, controller); baseline smoke test green. + +## Post-Phase-2 Additions +- [x] Development auth bypass (2026-10-16): debug-only "Continue Without Signing In" button on the login screen (`kDebugMode`-gated, in-memory `devAuthBypassProvider`) lets reviewers enter the app without a Supabase session; the router guard honors the flag and the shell shows an orange "Development mode - not signed in" banner while active. Covered by `test/features/auth/dev_auth_bypass_test.dart` (3 tests). + +## Active Verification Gates +- [x] `flutter pub run build_runner build --delete-conflicting-outputs` +- [x] `flutter analyze` (Zero issues) +- [x] `flutter test` (37/37 passing) \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d14d7df..edd5269 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,4 +1,8 @@ + + + + + + + + + + + +