Commit Graph

4 Commits

Author SHA1 Message Date
Mike Kell 51364a8f4f feat(platform,tests,ci): complete Phase 6 cross-platform hardening, integration tests, and Forgejo CI/CD
- Harden HealthGateway: kIsWeb/defaultTargetPlatform/dart:io guards, Health
  Connect SDK availability probe with graceful degradation, READ_WEIGHT/
  READ_STEPS/READ_TOTAL_CALORIES_BURNED permission validation before reads,
  HealthKit entitlement failures contained (false + debug warning), and a
  desktop/web fallback that serves locally logged biometrics through the new
  ILocalBiometricReader contract (drift-backed adapter wired in health_sync).
- Platform-safe CryptoManager vault: EncryptedSharedPreferences (Android),
  Keychain first_unlock (iOS/macOS), DPAPI-sealed file (Windows), libsecret
  (Linux); vault failures degrade to an ephemeral in-memory SQLCipher key.
- Declare the four Health Connect READ_* permissions in AndroidManifest.xml.
- Extract isAuthenticatedProvider so integration tests can simulate auth
  sessions without booting Supabase.
- Add 24 tests (99 -> 123): steady-state PK suite (Semaglutide 168h /
  Tirzepatide 120h geometric series, superposition, titration, washout),
  real-world recipe JSON-LD fixtures (BBC-style root, AllRecipes @graph),
  pantry unit-conversion group (kg/g, l/ml, dimension guard, synonyms),
  app navigation integration tests (rail + bar, authenticated + dev-bypass
  + unauthenticated), and reactive nutrition progress-bar widget tests.
- Fix NutritionScreen narrow-width overflows: Flexible protein title and
  Wrap action buttons stack cleanly on compact phones.
- Add .forgejo/workflows/ci.yml for git.kellsupport.com/mtkell/glp-companion
  (push to main + PRs, Flutter container: checkout, mock .env, pub get,
  build_runner, analyze --fatal-infos, test --coverage, build bundle + web).
- Remove dead lib/features/recipes/data/recipe_scraper.dart; rewrite
  README.md (architecture, dev setup, SQLCipher details, CI docs); add
  .env.example; allow it through .gitignore; update BUILD_STATE.md with
  Phase 6 deliverables and complete Phases 1-6 checklist.

Verified: build_runner 44 outputs, flutter analyze --fatal-infos clean,
flutter test 123/123, flutter build web and flutter build bundle succeed.
2026-10-16 14:59:15 -04:00
Mike Kell 094cf08f25 feat(nutrition,health_sync): complete Phase 3 nutrition tracking and HealthGateway sync
- Domain: FoodLogEntry/MealType, HydrationLogEntry, BiometricEntry/BiometricSource entities plus INutritionRepository and IHealthSyncRepository contracts (pure Dart).

- Data: AppDatabase schema v2 (FoodLogs/HydrationLogs/BiometricLogs tables, v1 migration, range-filtered CRUD) with drift-backed NutritionRepository and HealthSyncRepository; startOfDay/endOfDay date utils.

- Platform: HealthGateway conditional-import factory - mobile impl wires package:health (WEIGHT kg->lb, ACTIVE_ENERGY_BURNED J->kcal, permissions, write-back) with guarded fallbacks; web/desktop impl never touches platform channels (manual entry + drift cache).

- Presentation: NutritionController and BiometricController AsyncNotifiers (100g protein / 96oz water targets, meal grouping, 7/30-day weight deltas, idempotent 90-day native sync with per-day active-energy aggregation); LogFoodDialog and LogWeightDialog.

- UI: NutritionScreen progress meters, +8/+16/+24oz quick-add, meal-grouped food diary, weight tracker card with Log Weight / Sync (native sync on Android/iOS, manual dialog on Windows/Web) and status snackbars.

- Tests: 23 new tests (in-memory drift repos, controller fakes, fake health gateway covering fallback, permission denial, and duplicate-free re-sync); 60/60 passing, flutter analyze clean, flutter build web succeeds. BUILD_STATE.md updated to Phase 4.
2026-10-16 07:02:28 -04:00
Mike Kell 7682d8317a 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
2026-10-16 06:20:23 -04:00
Mike Kell 98e0d318f3 feat(init): baseline multiplatform architecture with clean arch shell, clinerules, and docs 2026-10-15 21:01:52 -04:00