- security: add mealie_base_url / mealie_api_token vault keys and
write/read/deleteMealieCredentials() to CryptoManager; the pairing
persists only in the platform keystore (Keychain / EncryptedSharedPreferences /
DPAPI) and never enters controller state
- data: add MealieApiClient - testConnection probes GET /api/app/about with
GET /api/recipes?perPage=1 fallback (200 = connected); fetchAllRecipes lists
GET /api/recipes?perPage=-1 and enriches each summary with
GET /api/recipes/{slug}, mapping recipeIngredient (structured maps + strings),
recipeInstructions (section flattening), nutrition display strings, ISO-8601
prep/cook times, yield, image + source URLs; Mealie UUID reused as Recipe.id
- data: add AppDatabase.upsertRecipe (insertOnConflictUpdate) and
DriftRecipeRepository.syncFromMealie preserving createdAt on re-sync
- presentation: add MealieIntegrationController (async credential load,
connectivity-gated Test & Save, Sync Now with spinner state, Disconnect,
isMealieRecipe badge/filter helper) plus api/sync providers
- settings: add Private Recipe Integrations card - Connect Mealie modal with
server URL hint, obscured API token field, Test & Save before persistence;
connected state shows endpoint, Sync Now and Disconnect
- recipes: add All / Web Scraped / Mealie source filter chips, subtle Mealie
badge on synced cards, and AppBar Sync Private Recipes action when configured
- fix _SettingsCard title Row overflow at 390dp (Expanded wrap) caught by the
mobile navigation widget test; add mealie_parser_test.dart (14 tests), suite
green at 184/184, flutter analyze clean
- docs: add architecture 4.9 Mealie design and multiplatform UX adaptation
spec; BUILD_STATE marks Phase 4B complete
Specifies the L1-L4 ingestion resolution ladder (encrypted local cache, Open Food Facts branded/barcode lookups, USDA FoodData Central fallback for whole/unbranded foods, manual entry), the FoodProduct domain model and FoodProductsTable schema, the OFF/USDA nutrient mapping table, and network resiliency rules (mandatory custom User-Agent, 4-second circuit timeout with automatic fallback, write-through SQLCipher caching).
Implements architecture section 4.7: IHealthGateway now exposes the Phase 3B contract (HealthProviderType, HealthConnectionStatus, HealthDataPayload, checkStatus/requestAuthorization/fetchLatestBiometrics/disconnect) with defaults derived from the existing primitives. Drivers and test fakes switch from implements to extends so Dart inherits the default bodies.
- Mobile driver: BLOOD_GLUCOSE added to iOS/Android read sets (mmol/L to mg/dL normalization); checkStatus probes hasPermissions plus Health Connect SDK readiness; samsungHealth aliases the Health Connect binding on Android (federated Samsung/Pixel feeds); disconnect clears the cached SDK probe.
- Fallback driver: safe dummy states on Windows/Web/macOS (manualFallback connected, enterpriseFhir notConfigured, native unsupportedPlatform); fetchLatestBiometrics serves the encrypted drift cache; zero platform-channel calls.
- Settings: IntegrationsController rewritten from toggles to status orchestration (refreshStatuses, connect/disconnect round-trips, denial to permissionDenied plus snackbar); SettingsScreen gains a Health Integrations card with Apple Health, Health Connect (Samsung & Pixel), and SMART on FHIR rows showing live status badges and Connect/Disconnect buttons with desktop-safe disabled states.
- Manifests: Android adds READ_BLOOD_GLUCOSE, healthdata package query, ACTION_SHOW_PERMISSIONS_RATIONALE intent, and ViewPermissionUsageActivity alias; iOS adds NSHealthShareUsageDescription and NSHealthUpdateUsageDescription.
- Tests: +13 (fallback dummy-state matrix, integrations controller transitions, Settings desktop disabled-states and mobile connect/disconnect round trip); existing fake switched to extends; navigation test updated for the renamed card title.
Verified: build_runner 191 outputs; flutter analyze clean; flutter test 148/148; flutter build windows debug succeeded.