App services
The service layer — the classes that talk to AI, auth, food data, devices and billing.
The app's data/services/ layer centralizes every interaction with the outside world.
Each service is a focused class; the UI never talks to an external API directly. State
is managed with BLoC (flutter_bloc), wired through get_it for dependency
injection, with go_router handling navigation.
The services
| Service | Responsibility |
|---|---|
AiService | The single entry point to Gemini. Builds the NutritionContext, sends prompts, parses action markers and runs the deterministic normaliser. See AI and automation. |
AuthService | Email/password sign-up and login, OTP verification, password reset and session persistence. |
BiometricService | Face ID / Touch ID / fingerprint unlock via local_auth. |
EmailService | Sends transactional email (OTP) through the send-email Edge Function. |
FatsecretService | Food search and barcode lookups through the secure fatsecret Edge Function. |
OpenfoodfactsService | Global barcode fallback against Open Food Facts. |
OcrService | Reads shopping receipts with ML Kit text recognition. |
NotificationService | Schedules timezone-aware local reminders (meals, hydration, weekly summary). |
SubscriptionService | Tracks Premium state, drives the paywall and talks to Stripe. |
Food data, three ways
FatsecretService, OpenfoodfactsService and the bundled
PortugueseFoodsDatabase datasource together implement the three-source strategy in
Food sources: local first for national
accuracy, FatSecret and Open Food Facts for global coverage.
Why a service layer
Keeping all I/O behind services makes the app testable and keeps secrets on the server (the Gemini, FatSecret and Stripe calls go through Edge Functions). It also means a source or provider can be swapped without touching the screens.