Files
recipe-app/teknisk_beskrivning_flutter.md
T

118 lines
5.9 KiB
Markdown

# Teknisk Beskrivning - Flutter Frontend
Detta dokument beskriver vad som ar byggt, arkitekturval och teknisk kontext for Flutter-frontenden.
Malgrupp: utvecklare och AI-assistent i denna chat.
Relaterade dokument:
- [next_steps_flutter.md](next_steps_flutter.md)
- [flutter/README.md](flutter/README.md)
- [teknisk_beskrivning.md](teknisk_beskrivning.md) (for backend-kontekst)
## Syfte
- Isolerad Flutter-baserad frontend i separat Docker-service.
- Web forst, men med arkitektur som kan ateranvandas for Android/iOS.
- Stegvis migrering av funktioner fran befintlig Next.js-frontend.
## Vad som ar gjort
- Ny compose override: [compose.flutter.yml](compose.flutter.yml).
- Ny Flutter-service: `recipe-flutter`.
- Service ansluten till natverk:
- `recipe-internal` (backend access)
- `proxy` (external Caddy reachability)
- Flutter-container serverar web build via intern Caddy.
- Exponering via extern Caddy med site `test.gynther.se` -> `recipe-flutter:5000`.
- API anrop gar same-origin via `/api` och proxas internt till `recipe-api:8080`.
## Arkitektur
### Lager
- Presentation: skarmar och widgets i `flutter/lib/features/*/presentation`.
- State/Application: Riverpod providers/notifiers i `flutter/lib/features/*/data`.
- Data/API: `ApiClient` i `flutter/lib/core/api`.
- Platform abstraction: token storage interface i `flutter/lib/core/platform`.
### Routing
- GoRouter i [flutter/lib/core/router/app_router.dart](flutter/lib/core/router/app_router.dart).
- Nuvarande routes:
- `/login` — loginskarm
- `/recipes` — receptlista (ShellRoute med AppShell)
- `/recipes/create` — nytt recept, utanfor ShellRoute
- `/recipes/:id` — receptdetalj, utanfor ShellRoute
- `/recipes/:id/edit` — redigera recept, utanfor ShellRoute
- `/profile` — profil (ShellRoute med AppShell)
- `/recipes/create` maste vara listad fore `/recipes/:id` i routelistan for att undvika konflikt.
- Detaljsidor (detalj, skapa, redigera) ligger utanfor ShellRoute for att fa full-screen med automatisk back-knapp.
### Auth
- Login endpoint: `POST /api/auth/login`.
- Backend kontrakt anvander `username` + `password`.
- Token-falt i svar: `accessToken`.
- Token lagras via `ITokenStorage` (web implementation med SharedPreferences).
- Auth-gate i router: utloggad anvandare redirectas till `/login`, inloggad redirectas fran `/login` till `/recipes`.
- Splash-skarm (`/`) visas medan auth-state lases fran storage vid app-start.
- `guardedApiCall()` i `flutter/lib/core/api/guarded_api_call.dart` hanterar automatisk logout vid 401.
### API-lager
- `ApiClient` i `flutter/lib/core/api/api_client.dart` exponerar: `getJson`, `postJson`, `patchJson`, `putJson`, `deleteJson`.
- Centralicerad HTTP-felklassning: 401 -> `ApiErrorType.unauthorized`, 403 -> `forbidden`, 5xx -> `server`, natverksfel -> `network`.
- `ApiException` i `flutter/lib/core/api/api_exception.dart` ar den enda feltypen som propageras fran repositories.
- `mapErrorToUserMessage()` i `flutter/lib/core/api/api_error_mapper.dart` oversatter fel till svenska anvandarmedddelanden.
### Recipes
- `GET /api/recipes` — receptlista.
- `GET /api/recipes/:id` — receptdetalj inkl. ingredienser.
- `POST /api/recipes` — skapa recept.
- `PATCH /api/recipes/:id` — uppdatera recept (OBS: PATCH, inte PUT).
- `DELETE /api/recipes/:id` — ta bort recept (returnerar 204, ingen body).
- `POST /api/recipes/parse-markdown` — tolka Markdown, returnerar ParsedRecipe med ingrediensforslagslistor.
- Flutter Recipe-model: `name`-fallback till `title`, null-safe parsing av Decimal-strang till double.
### Gemensamma UI-komponenter
- `LoadingStateView`, `EmptyStateView`, `ErrorStateView` i `flutter/lib/core/ui/async_state_views.dart`.
- `AppShell` i `flutter/lib/core/ui/app_shell.dart`: responsiv NavigationRail (bred) / NavigationBar (smal), delad AppBar med logout.
## Kanda API-fallgropar (viktigt!)
> **Regel: Kontrollera alltid HTTP-metod i [TEKNISK_BESKRIVNING.md](TEKNISK_BESKRIVNING.md) innan en ny repository-metod implementeras.**
| Operation | Korrekt metod | Fel som gjorts |
|-----------|--------------|----------------|
| Uppdatera recept | `PATCH /api/recipes/:id` | `PUT` — ger 404 |
| Uppdatera inventariepost | `PATCH /api/inventory/:id` | Anvand PATCH |
| Uppdatera matplan | `POST /api/meal-plan` (upsert) | Ingen PUT/PATCH |
Generell regel: NestJS-backenden anvander `PATCH` for partiella uppdateringar, inte `PUT`. `PUT` exponeras inte pa nagra resurser i detta projekt.
## Drift och deploy
### Build/run
- Build argument i compose: `API_BASE_URL=/api`.
- Build command:
- `docker compose -f compose.yml -f compose.flutter.yml build recipe-flutter`
- Run command:
- `docker compose -f compose.yml -f compose.flutter.yml up -d --no-deps recipe-flutter`
### Viktiga verifieringar
- Compose merge valid:
- `docker compose -f compose.yml -f compose.flutter.yml config`
- Container reachable from external Caddy:
- `docker exec caddy wget -S -O- http://recipe-flutter:5000`
- Public endpoint:
- `curl -I https://test.gynther.se`
## Viktiga beslut
- `compose.yml` lamnas orord; Flutter ligger i separat override-fil.
- Flutter-web anvander same-origin API (`/api`) for att undvika mixed-content.
- Intern Caddy i Flutter-container hanterar static hosting + `/api` proxy.
- Feature migration sker stegvis enligt [next_steps_flutter.md](next_steps_flutter.md).
## Kanda fallgropar
- Om `recipe-flutter` inte ar i `proxy` natverket blir det 502 fran extern Caddy.
- Om browser visar gammal JS kan gamla API-URL:er leva kvar i cache/service worker.
- Login med email fungerar inte om backend forvantar username.
## Nasta tekniska steg
Fortsatt migrering enligt prioritering i [next_steps_flutter.md](next_steps_flutter.md):
1. Auth parity (session behavior refinements).
2. Recipes parity (list -> detail -> create/edit).
3. Inventory and meal plan pages.
4. Profile/admin parity.