- Added localization support for Swedish and English languages. - Integrated localized strings for user messages in the API error mapper. - Updated UI components to use localized strings for labels and messages. - Ensured all error messages are context-aware and utilize the localization framework. - Created regression test to prevent common ASCII fallbacks in Swedish UI text.
7.4 KiB
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
- flutter/README.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.
- 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
/apioch proxas internt tillrecipe-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:
ApiClientiflutter/lib/core/api. - Platform abstraction: token storage interface i
flutter/lib/core/platform.
Routing
- GoRouter i 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/createmaste vara listad fore/recipes/:idi 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/logintill/recipes. - Splash-skarm (
/) visas medan auth-state lases fran storage vid app-start. guardedApiCall()iflutter/lib/core/api/guarded_api_call.darthanterar automatisk logout vid 401.
API-lager
ApiClientiflutter/lib/core/api/api_client.dartexponerar:getJson,postJson,patchJson,putJson,deleteJson.- Centralicerad HTTP-felklassning: 401 ->
ApiErrorType.unauthorized, 403 ->forbidden, 5xx ->server, natverksfel ->network. ApiExceptioniflutter/lib/core/api/api_exception.dartar den enda feltypen som propageras fran repositories.mapErrorToUserMessage()iflutter/lib/core/api/api_error_mapper.dartoversatter 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 tilltitle, null-safe parsing av Decimal-strang till double.
Gemensamma UI-komponenter
LoadingStateView,EmptyStateView,ErrorStateViewiflutter/lib/core/ui/async_state_views.dart.AppShelliflutter/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 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
Rekommenderat kommandomonster
For att minska risken for fel startordning eller missforstand mellan huvudappen och Flutter-sparet:
Nar huvudappen ska vara uppe:
docker compose up -d recipe-db recipe-api recipe-frontend
Nar Flutter-klienten ska vara uppe:
docker compose -f compose.yml -f compose.flutter.yml up -d --no-deps recipe-flutter
Nar bade huvudappen och Flutter testas parallellt:
- Starta huvudappen med
compose.yml. - Starta sedan Flutter med override-filen
compose.flutter.yml.
Viktigt:
docker compose build ...bygger bara image.docker compose up -d ...kravs alltid for att containern faktiskt ska starta.
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.ymllamnas 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 +
/apiproxy. - Feature migration sker stegvis enligt next_steps_flutter.md.
Kanda fallgropar
- Om
recipe-flutterinte ar iproxynatverket 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.
recipe-flutterkan stoppas avdocker compose down --remove-orphansom kommandot kors utan override-filen och Flutter-sparat tidigare varit uppe.- En orphan-varning for
recipe-flutterar normalt forvantad nar man kor huvudappen med baracompose.yml; det betyder inte att backend eller Prisma ar trasiga.
Orphan-varning i praktiken
Om du ser en varning om orphan-containers under arbete med huvudappen betyder det oftast att recipe-flutter tidigare startats via:
docker compose -f compose.yml -f compose.flutter.yml up -d recipe-flutter
och att du nu kor ett kommando som bara anvander compose.yml.
Detta ar normalt och ofarligt sa lange du vet vilken stack du avser att kora.
Om test.gynther.se slutar svara efter städning med --remove-orphans, starta om Flutter-sparet med:
docker compose -f compose.yml -f compose.flutter.yml up -d --no-deps recipe-flutter
Nasta tekniska steg
Fortsatt migrering enligt prioritering i next_steps_flutter.md:
- Auth parity (session behavior refinements).
- Recipes parity (list -> detail -> create/edit).
- Inventory and meal plan pages.
- Profile/admin parity.