glp-companion/BUILD_STATE.md

8.2 KiB
Raw Blame History

Build Execution Ledger

Active Target

  • Current Milestone: Phase 4: Recipe Web Scraper Engine & Meal Planning Calendar — COMPLETE
  • Status: Phase 4 Complete (next: Phase 5)

Phase Checklist

  • Phase 1: Foundation & Identity (Passwordless SSO & Encrypted Drift DB)
  • 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)

  • Domain: DoseEntry entity, 12-quadrant InjectionSite rotation model, Glp1Compound value object (Sema 168h / Tirze 120h / Lira 13h), IMedicationRepository contract.
  • Domain: CalculateSerumLevel use case implementing C(t) = Σ D_i · 0.5^((t − t_i)/t_half).
  • Data: injection-history CRUD on AppDatabase + drift-backed MedicationRepository (record ↔ entity mapping).
  • 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).
  • 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.
  • Regression fix: SupabaseAuthService now resolves its client lazily (baseline widget test no longer throws when Supabase is uninitialized).
  • 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

  • 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).

Phase 3 Deliverables (2026-10-16)

  • Domain: FoodLogEntry (+ MealType enum), HydrationLogEntry, BiometricEntry (+ BiometricSource enum), INutritionRepository, IHealthSyncRepository — all pure Dart.
  • Data: AppDatabase schema v2 (+ migration for v1 installs) with FoodLogsTable, HydrationLogsTable, BiometricLogsTable, range-filtered watch/get/CRUD helpers, clearSyncedRange for idempotent re-syncs; drift-backed NutritionRepository and HealthSyncRepository (record ↔ entity mapping).
  • Platform: HealthGateway rewrite — IHealthGateway + conditional-import factory; mobile impl (health_gateway_mobile.dart) wraps package:health for WEIGHT (kg→lb normalization) and ACTIVE_ENERGY_BURNED (joule→kcal) with double-guarded try/catch; fallback impl (health_gateway_fallback.dart) for Web/Windows/macOS never touches platform channels (reads served from the drift cache, writes via manual entry).
  • Presentation: NutritionController (Riverpod AsyncNotifier; today's logs, 100 g protein / 96 oz water targets, meal grouping, quick-add water) and BiometricController (weight history, 7/30-day deltas, manual entry, native sync with per-day active-energy aggregation); LogFoodDialog and LogWeightDialog.
  • Presentation: NutritionScreen upgraded — interactive protein/hydration progress meters, +8/+16/+24 oz quick-add buttons, meal-grouped food diary with delete, weight tracker card (latest weight, 7/30-day trend chips, latest active burn) whose "Log Weight / Sync" button runs HealthGateway sync on Android/iOS and opens the manual dialog on Windows/Web; status snackbars via ref.listen.
  • Tests: 23 new tests — nutrition repository (in-memory drift: CRUD, day-range filter, watch, MealType round-trip), nutrition controller (targets, grouping, validation, quick-add, delete, failure retention), biometric controller (manual entry, deltas, fallback short-circuit, permission denial, weight+energy sync idempotency).
  • Regression fix: none required — existing 37 tests untouched and green.

Phase 4 Deliverables (2026-10-16)

  • Domain: Recipe (+ MacroProfile), RecipeIngredient (quantity/unit/item parsing: decimals, ASCII + unicode + mixed fractions, known-unit vocabulary), MealPlanSlot (reuses nutrition MealType), IRecipeRepository, IMealPlanRepository — all pure Dart; core/utils/uuid.dart v4 generator (no new dependency).
  • Domain: ScrapeRecipeFromUrl use case — package:http download (injectable RecipeHtmlFetcher for tests), package:html DOM parse, JSON-LD @graph/root/array/@type-list navigation, HowToStep/HowToSection instruction flattening, ISO-8601 prepTime/cookTime, recipeYield, regex nutrition parsing (calories, proteinContent, carbohydrateContent, fatContent), image list/object unwrap, OpenGraph fallback (og:title/og:image/og:description), typed RecipeScrapeException.
  • Data: AppDatabase schema v3 (migration for v1/v2 installs) with RecipesTable (UUID PK, JSON ingredient/instruction columns, macros, createdAt) and MealPlanSlotsTable (UUID PK, plannedDate, mealType, nullable recipeId FK with ON DELETE SET NULL, customNotes, isCompleted); drift-backed DriftRecipeRepository (URL-deduplicated importRecipe, createdAt preserved on re-import) and DriftMealPlanRepository (half-open [from, to) window, upsert-by-id).
  • Presentation: RecipeImportController (Riverpod Notifier; URL submit → loading → preview modal state, live catalog watch stream, confirm-save/dismiss/delete) and MealPlanCalendarController (Monday–Sunday window, next/previous/today navigation, slot assign/upsert/clear, prepared toggle, per-day protein rollup against the nutrition 100 g target, deleted-recipe slot normalization, stale-window refresh guard).
  • Presentation: MealPlannerScreen refactor — URL import bar with spinner, RecipePreviewDialog (image, meta chips, macro tiles, ingredients, steps, save with error surface), SavedRecipesTray (draggable cards with thumbnail + protein badge + quick-assign), WeeklyCalendarView (≥900 dp: 7-column grid; below: tabbed pager) with DragTarget meal slots, prepared checkboxes, clear menu, per-day protein indicator (progress bar vs. target), AssignSlotDialog (saved-recipe dropdown or custom description), week navigation header.
  • Tests: 25 new tests — recipe_scraper_test.dart (JSON-LD @graph/root/array/list-@type extraction, macro/ingredient/instruction/duration/yield parsing, malformed-JSON fallthrough, OpenGraph fallback, execute() URL validation & error mapping) and meal_plan_repository_test.dart (startOfWeek, recipe CRUD/URL-dedup/watch, slot window filter/upsert/delete, calendar rollup/assignment/navigation/custom entries/prepared toggles/recipe-deletion normalization, import-controller empty-URL guard).
  • Regression fix: HowToSection flattening now recurses into itemListElement before using the section name (parser ordering bug caught by the new test).

Post-Phase-4 Additions

  • Desktop resize overflow fix (2026-10-16): the hatched yellow/black stripes (RenderFlex overflow) shown when shrinking the Windows window are gone — wide-mode day columns now scroll vertically (matching the compact pager), and a LayoutBuilder in MealPlannerScreen collapses the page into a single scrollable column (with a fixed-height calendar) whenever the body is shorter than ~520 dp. Covered by test/features/meal_planner/meal_planner_screen_test.dart (4 widget tests pumping the screen at short-compact, short-wide, tall, and extremely-short window sizes; overflow errors fail widget tests, so green proves no stripes).

Active Verification Gates

  • flutter pub run build_runner build --delete-conflicting-outputs
  • flutter analyze (Zero issues — No issues found!)
  • flutter test (89/89 passing)
  • flutter build web --no-tree-shake-icons (conditional import keeps package:health/dart:io out of the web bundle)