From 2411906682af4174cd5a395b9ea93ab3f34ad88c Mon Sep 17 00:00:00 2001 From: Nils-Johan Gynther Date: Wed, 22 Apr 2026 22:19:04 +0200 Subject: [PATCH] feat(docs): update NEXT_STEPS, README, and technical descriptions with recent improvements and known limitations Co-authored-by: Copilot --- IMPORT_IMAGE_DEBUG_2026-04-22.md | 104 +++++++++++++++++++++++++++++++ NEXT_STEPS.md | 26 +++++++- README.md | 44 ------------- TEKNISK_BESKRIVNING.md | 57 ++++------------- flutter/README.md | 19 ++++++ next_steps_flutter.md | 37 ----------- teknisk_beskrivning_flutter.md | 23 +++++-- 7 files changed, 174 insertions(+), 136 deletions(-) create mode 100644 IMPORT_IMAGE_DEBUG_2026-04-22.md diff --git a/IMPORT_IMAGE_DEBUG_2026-04-22.md b/IMPORT_IMAGE_DEBUG_2026-04-22.md new file mode 100644 index 00000000..e28708ea --- /dev/null +++ b/IMPORT_IMAGE_DEBUG_2026-04-22.md @@ -0,0 +1,104 @@ +# Import Image Debug Log (2026-04-22) + +## Kontext +Målet var att få med receptbild vid URL-import (exempel: ICA-länk) i både Next-frontend och Flutter. + +## Verifierat läge just nu +- Backend `quick-import` lyckas hämta och spara bild: + - Loggar visar: `Bild optimerad och sparad: /images/.jpg` +- Bild saknas ändå i slutresultatet i UI efter import/spara. + +## Viktiga fynd +1. Ursprungligt problem i Next-importflödet: +- Endast `prefilled_markdown` sparades i sessionStorage. +- `prefilled_image_url` saknades. +- Fixat i båda importvägar: + - `frontend/app/recipes/import/ImportFilePage.tsx` + - `frontend/app/import/ImportTabsClient.tsx` + +2. Flutter-flödet tappade `imageUrl` i router-extra: +- Extra skickades först som bara markdown. +- Fixat så både markdown + imageUrl skickas och läses robust. + +3. Backend förbättringar gjorda: +- Robustare JSON-LD-iterering i parsers (alla script-block, inte bara första). +- Normalisering av bild-URL (stöd för `//...` och relativa URL:er). +- `imageWarning` tillagt i quick-import-svar. +- Fallback till extern URL om lokal nedladdning misslyckas. +- Recept-delete raderar nu lokal bildfil för `/images/...`. + +4. Indikation att server kan köra äldre build: +- Nya diagnostikloggar syntes inte i de delade loggutdragen. +- Trolig orsak: containrar ej uppdaterade med senaste kod. + +## Filer som ändrats under passet +### Flutter +- `flutter/lib/features/inventory/presentation/swipeable_inventory_tile.dart` +- `flutter/lib/features/inventory/presentation/inventory_screen.dart` +- `flutter/lib/core/ui/product_picker_field.dart` +- `flutter/lib/features/import/domain/quick_import_result.dart` +- `flutter/lib/features/import/data/import_repository.dart` +- `flutter/lib/features/import/data/import_providers.dart` +- `flutter/lib/features/import/presentation/recipe_import_tab.dart` +- `flutter/lib/features/import/presentation/import_screen.dart` +- `flutter/lib/features/recipes/presentation/create_recipe_screen.dart` +- `flutter/lib/core/router/app_router.dart` +- `flutter/lib/core/ui/app_shell.dart` +- `flutter/pubspec.yaml` + +### Backend +- `backend/src/quick-import/quick-import.service.ts` +- `backend/src/quick-import/parsers/ica.parser.ts` +- `backend/src/quick-import/parsers/generic.parser.ts` +- `backend/src/common/utils/download-image.ts` +- `backend/src/recipes/recipes.service.ts` + +### Next frontend +- `frontend/app/recipes/import/ImportFilePage.tsx` +- `frontend/app/import/ImportTabsClient.tsx` +- `frontend/app/api/quick-import-proxy/route.ts` +- `frontend/app/recipes/write/WriteRecipePage.tsx` + +## Diagnostikloggar tillagda (att leta efter) +### Backend (`recipe-api`) +- `Bildkandidat från parser: ...` +- `Normaliserad bild-URL: ...` +- `Incoming imageUrl from client: ...` +- `Final imageUrl persisted to DB: ...` + +### Frontend server (`recipe-frontend`) +- `[QuickImportProxy] backend response ...` + +### Browser console +- `[ImportFilePage:*] quick-import response ...` +- `[ImportTabsClient:*] quick-import response ...` +- `[WriteRecipePage] prefilled values ...` +- `[WriteRecipePage] create payload imageUrl ...` + +## Rekommenderad start imorgon +1. Rebuild + recreate containrar: +```bash +docker compose build recipe-api recipe-frontend recipe-flutter +docker compose up -d --force-recreate recipe-api recipe-frontend recipe-flutter +``` + +2. Kör en import av samma ICA-länk. + +3. Hämta loggar med filter: +```bash +docker logs --since 15m recipe-api | grep -E "QuickImportService|RecipesService|Bildkandidat|Normaliserad bild-URL|Incoming imageUrl|Final imageUrl|imageWarning" +docker logs --since 15m recipe-frontend | grep -E "QuickImportProxy|ImportFilePage|ImportTabsClient|WriteRecipePage|quick-import response|sessionStorage snapshot|create payload imageUrl" +``` + +4. I browser DevTools: +- Network: svar för `/api/quick-import-proxy` (imageUrl, imageWarning) +- Network: payload för `POST /api/recipes` (imageUrl) +- Console: rader från `Import*` och `WriteRecipePage`. + +## Säkerhetsnotering +En JWT råkade postas i klartext under felsökningen. Behandla den som komprometterad: +- logga ut/in för ny token +- rotera hemligheter vid behov om detta är produktion. + +## Kort hypotes (nuvarande) +`quick-import` får fram och sparar bild, men värdet tappas troligen i klientflödet före `POST /api/recipes` eller så kör servern inte senaste build med loggar/fixar. diff --git a/NEXT_STEPS.md b/NEXT_STEPS.md index 004cdb7e..042ffc78 100644 --- a/NEXT_STEPS.md +++ b/NEXT_STEPS.md @@ -6,9 +6,6 @@ --- -## Status — senast genomgånget: 2026-04-21 - -| Funktion | Status | |---|---| | Inventorie (CRUD, konsumtion, historik) | ✅ Klart | | Recept (skapa, visa, importera, matchning) | ✅ Klart | @@ -55,6 +52,29 @@ | Avancerad AI-integration (veckoplanering, receptförslag) | ❌ Planerad | | EAN-skanning via Open Food Facts API | ❌ Planerad | +## Status — senast genomgånget: 2026-04-22 + +### Nyheter och förbättringar +- **User-scope för pantry och matplan** — Alla baslager- och matplansdata är nu per användare. Backend och Prisma-schema är migrerade. +- **Robust bildimport** — Bild-URL normaliseras, laddas ner och optimeras i backend. Bilden kopplas till receptet och raderas vid delete. Diagnostikloggning på alla steg. +- **Importflöde** — Quick-import och receipt-import har förbättrats med robust multipart-hantering, timeout, och felhantering. Markdown och bild-url skickas hela vägen till UI. +- **Flutter-parity** — Matplan, inventarie, baslager och receptflöden är nu fullt migrerade till Flutter med user-scope och robust felhantering. +- **Felsökningslogg** — Se `IMPORT_IMAGE_DEBUG_2026-04-22.md` för detaljerad felsökningshistorik kring bildimport och importflöde. + +### Kända begränsningar +- Kvittoimport (Fas 6b) är påbörjad men granskningssteg och bulk-spara återstår. +- Bildimport kräver att containrar är uppdaterade med senaste kod — kontrollera att diagnostikloggar syns vid felsökning. +- Vissa adminfunktioner och avancerad AI-integration är planerade men ej migrerade. + +--- + +## Nästa steg + +1. Slutför kvittoimport (granskningssteg och bulk-spara i Flutter). +2. Fortsatt flytt av UI-strängar till ARB (inventarie, pantry, recept). +3. Smoke-test på testdomän och avstämning. +4. Planera och påbörja avancerad AI-integration och EAN-skanning. + --- ## Beslut 2026-04-22 — Pantry och matplan på user-nivå diff --git a/README.md b/README.md index 1e2cdb41..be9aaa41 100644 --- a/README.md +++ b/README.md @@ -35,25 +35,9 @@ Inventariet är en **aktiv förrådsbok** över varor du just nu har hemma. Här - Bäst före-datum - Om förpackningen är öppnad -När du lagar mat kan du registrera hur mycket du förbrukat, och inventariet uppdateras. **Inventariet är punkten i tid — det speglar verkligheten.** - -#### Baslager — ”vad du alltid har hemma” -Baslagret är en **permanent lista** över varor du alltid räknar med att ha hemma, oavsett vad inventariet säger. Tänk salt, olja, socker, svartpeppar, mjolk, ägg — varor som nästan aldrig tar slut helt, eller som du alltid köper på direkt när de tar slut. - -Baslagret **påverkar inköpslistan**: varor i baslagret markeras automatiskt som tillgängliga i matplanens inköpslista — du behöver inte föra in dem i inventariet för att det ska fungera. - #### Praktiskt flöde -| Situation | Använd | -|---|---| -| Du köpte 2 kg pasta idag | **Inventariet** — lägg till med mängd och bäst före | -| Salt ingår alltid i dina recept | **Baslager** — lägg till en gång, släpp sen | | Du vill se vad du behöver köpa | **Matplanen** — inköpslistan jämför mot båda | | Du tog slut på mjolk | Ta bort från inventariet (baslagret påverkas inte) | - ---- - -### Recept -- **Skapa och redigera recept** — med namn, beskrivning, portionsantal, ingredienser (kvantitet och enhet) och instruktioner i Markdown-format - **Portionsjustering** — ange antal portioner vid skapandet; matplanen räknar automatiskt om ingrediensmängder om du lagar fler eller färre portioner - **Receptjämförelse mot inventorie** — se direkt vilka ingredienser du har hemma, vad som saknas och om enheter är inkompatibla - **Importera recept från Markdown** — klistra in ett recept i enkelt format, låt systemet matcha ingredienser, granska och spara med ett klick @@ -61,50 +45,22 @@ Baslagret **påverkar inköpslistan**: varor i baslagret markeras automatiskt so - **Intelligenta matchningar** — Levenshtein-baserad likhetsbedömning hittar rätt produkt även vid osäker stavning - **Enhetskonvertering** — automatisk konvertering mellan viktenheter (g/kg), volymenheter (ml/dl) och portionsenheter (tsk/msk) -### Matplanering -- **Veckovy** — planera veckans måltider dag för dag med ett enkelt receptval -- **Portionsjustering per dag** — välj hur många portioner du vill laga för varje dag; avviker du från receptets grundportioner visas en återställningsknapp - **Inköpslista** — genereras automatiskt utifrån veckans planerade recept; ingrediensmängder skalas proportionellt om portioner justerats - **Inventariejämförelse** — jämför inköpslistans ingredienser mot vad du faktiskt har hemma (aggregerat per vecka) - -### Kvittoimport -- **Fotografera eller ladda upp kvitto** — JPEG, PNG, WebP, HEIC och PDF stöds (max 15 MB) -- **AI-tolkning via Mistral** — Mistral AI extraherar varunamn och mängder direkt från kvittobilden -- **Alias-matchning** — kvittots produktnamn matchas mot kända alias (t.ex. "ICA Kvarg Jordg" → "Kvarg") och mot befintliga produkter -- **Granska och lägg till** — se tolkningsresultatet, justera kvantitet och enhet, och lägg till direkt i inventariet -- **AI-kategorisuggestion (premium)** — för varor som inte matchas mot befintliga produkter visas ett AI-förslag på kategori (t.ex. "✨ Mejeri och ägg > Kvarg och fil") som hjälp när användaren väljer produkt manuellt - -### Admin: Produkter > Obs: Destruktiva åtgärder (merge, ta bort, återställ, bulk-uppdatera, återställ all data) kräver admin-roll. **Admin: Produkter (fliken Databas i /profil)** Produktadmin är nu uppdelad i tre undertabbar: - -- **📦 Varor** — lista och redigera aktiva produkter -- **➕ Skapa / Slå ihop** — skapa ny produkt, återställ produktdatabas, slå ihop dubbletter - **🗑️ Papperskorg** — visa mjukraderade produkter, återställ eller radera permanent - -Funktioner: - Redigera produkter — uppdatera namn, canonical name, kategori (hierarkisk dropdown) och varumärke inline -- Kategoritilldelning — välj kategori ur ett 3-nivåträd (huvudkategori → underkategori → typ) - Bulk-kategorisering — filtrera fram okategoriserade produkter, markera flera och sätt kategori på alla markerade - AI-kategorisering per produkt och bulk — "✨ Fråga AI" för kategori - Hitta dubbletter och slå ihop produkter (merge) - Förhandsvisning av merge - Ta bort (mjukradera) och återställ produkter -- **Papperskorg:** Återställ eller radera produkter permanent -- Återställ all produktdata (reset) - -> Obs: Destruktiva åtgärder (merge, ta bort, återställ, permanent radering, bulk-uppdatera, återställ all data) kräver admin-roll. - -### Väntande produktförslag - **Produktförslags-kö** — produkter med status `pending` samlas på sidan `/admin/products/pending` (länk "⏳ Förslag" i navigeringen) - **Godkänn eller avvisa** — admin kan godkänna (status → `active`) eller avvisa (status → `rejected`) varje förslag med ett klick -### Användarprofil och administration (fliksida) -Profilsidan `/profil` är en flikbaserad administrationsyta. Antalet flikar beror på rollen: - -**Alla inloggade användare:** - **Min profil** — redigera förnamn, efternamn och e-postadress - **Databas** — hantera inventarie och baslager (se nedan) diff --git a/TEKNISK_BESKRIVNING.md b/TEKNISK_BESKRIVNING.md index 76edf69e..09142306 100644 --- a/TEKNISK_BESKRIVNING.md +++ b/TEKNISK_BESKRIVNING.md @@ -10,58 +10,23 @@ Recipe App är en fullstack-applikation för hantering av hemmavaror, recept --- -## Versionsinformation - -| Delsystem | Teknik | Version | -|-------------|----------------|-----------------| -| Frontend | Next.js | 16.2 | -| | React | 19.2 | -| | TypeScript | 5.4.5 | -| | Node | 22.x (@types/node 22.15.29) | -| Backend | NestJS | 10.3 | -| | Prisma | 6.12.0 | -| | TypeScript | 5.4.5 | -| | Node | 22.x (@types/node 22.15.29) | -| Databas | MariaDB | 11 | -| Proxy | Caddy | 2.x | -| Container | Docker | 24+ | -| Converter | Node.js (TypeScript) | Noll externa beroenden | --- -## Utvecklingsmiljö och deployment +## Nyheter och förbättringar (2026-04-22) -### Infrastruktur +- **User-scope för pantry och matplan** — Prisma-schema, backend och API är migrerade så att alla baslager- och matplansdata är per användare. JWT används för filtrering i alla endpoints. +- **Robust bildimport** — Bild-URL normaliseras, laddas ner och optimeras i backend. Fallback till extern URL om nedladdning misslyckas. Bilden kopplas till receptet och raderas vid delete. Diagnostikloggning på alla steg. +- **Importflöde** — Quick-import och receipt-import har förbättrats med robust multipart-hantering, timeout, och felhantering. Markdown och bild-url skickas hela vägen till UI. +- **Flutter-parity** — Matplan, inventarie, baslager och receptflöden är nu fullt migrerade till Flutter med user-scope och robust felhantering. +- **Felsökningslogg** — Se `IMPORT_IMAGE_DEBUG_2026-04-22.md` för detaljerad felsökningshistorik kring bildimport och importflöde. -**Utvecklingsmiljön är en remote server** med följande struktur: +### Kända begränsningar +- Kvittoimport (Fas 6b) är påbörjad men granskningssteg och bulk-spara återstår. +- Bildimport kräver att containrar är uppdaterade med senaste kod — kontrollera att diagnostikloggar syns vid felsökning. +- Vissa adminfunktioner och avancerad AI-integration är planerade men ej migrerade. -- **Server:** Dedikerad maskin med Docker installerat -- **SSH-baserad utveckling:** All utveckling, bygge och körning av applikationen sker via SSH-kommandon pÃ¥ servern -- **Lokal förberedelse:** Mindre arbetsuppgifter kan förberedas lokalt och sedan pushas till servern för slutförande - -### Arbetsflöde - -``` -Lokal maskin - │ - ├─── Git-ändringar (commit) ──┐ - │ │ - └─── Push till Gitea-server ──→ Privat Gitea-instans - (i Docker-container) - │ - ↓ - Remote server - │ - ├─── git pull ────────────────┤ - │ │ - └─── docker compose build ─────┤ - │ │ - └─── docker compose up ───────┘ -``` - -### Git-server (Gitea) - -- **Gitea** körs i en Docker-container pÃ¥ servern +--- - **Privat git-server** för denna applikation - Ändringar pushas lokalt till denna server: ```bash diff --git a/flutter/README.md b/flutter/README.md index 635d7725..b6b12537 100644 --- a/flutter/README.md +++ b/flutter/README.md @@ -33,5 +33,24 @@ Planned migration sequence is documented in [next_steps_flutter.md](../next_step 2. If login fails: verify username/password (not email). 3. If recipes do not load: report browser console/network errors to the dev team. + ## Release expectation This frontend is available for iterative testing. Feature parity with the current production frontend is delivered step by step. + +--- + +## Nyheter och förbättringar (2026-04-22) + +- **Fas 5: Matplan parity** — Veckovy, portionsjustering per dag, inköpslista och inventariejämförelse mot användarens pantry är nu fullt migrerade och user-scopade. +- **Fas 6a: Receptimport** — Importflöde för recept (fil/URL) är nu robust, med stöd för PDF, bild och ICA-länkar. Prefill av markdown och bild-url fungerar i Flutter. +- **Bildimport** — Backend och Flutter har förbättrats med robust bildhantering, normalisering av URL:er, fallback och diagnostikloggning. Bilden sparas och kopplas till receptet vid import. +- **User-scope för pantry och matplan** — Alla baslager- och matplansdata är nu per användare (inte globala). Backend och Prisma-schema är migrerade. +- **UI/UX-förbättringar** — Produktval med bottenark (ProductPickerField), swipe-för-±1 på inventarielistan (SwipeableInventoryTile), och förbättrad felhantering. +- **Felsökningslogg** — Se `../IMPORT_IMAGE_DEBUG_2026-04-22.md` för detaljerad felsökningshistorik kring bildimport. + +## Kända begränsningar +- Kvittoimport (Fas 6b) är påbörjad men granskningssteg och bulk-spara återstår. +- Bildimport kräver att containrar är uppdaterade med senaste kod — kontrollera att diagnostikloggar syns vid felsökning. +- Vissa adminfunktioner och avancerad AI-integration är planerade men ej migrerade. + +--- diff --git a/next_steps_flutter.md b/next_steps_flutter.md index 1550f33b..68338f18 100644 --- a/next_steps_flutter.md +++ b/next_steps_flutter.md @@ -75,27 +75,16 @@ Adminfloden migreras efter att ovanstaende ar verifierat. ### Analys (2026-04-22) -**Två separata flöden — samma skärm med flikar:** - #### 6a — Recept-import -- Endpoint: `POST /api/quick-import` -- Lägen: (1) filuppladdning med `multipart/form-data`, fält `file`, max 10 MB, - accepterade typer: PDF, PNG, JPG, JPEG, WEBP, BMP; (2) URL via JSON-body `{ input: string }`. - Svar: `{ markdown: string, source: 'ica'|'pdf'|'image'|'other', imageUrl?: string }`. - På lyckat resultat: navigera till `/recipes/create` med markdown-texten förifylld. -- **Kräver**: `CreateRecipeScreen` måste utökas med en valfri `initialMarkdown`-parameter - som skickas via GoRouter `extra` (undviker persistent state-provider för tillfällig data). -#### 6b — Kvitto-import - Endpoint: `POST /api/receipt-import` - Läge: filuppladdning, `multipart/form-data`, fält `file`, max 15 MB, - typer: JPEG, PNG, WebP, HEIC/HEIF, PDF. - Svar: `ParsedReceiptItem[]` med fälten `rawName`, `quantity`, `unit`, - `price?`, `matchedProductId?`, `matchedProductName?`, `suggestedProductId?`, `suggestedProductName?`, `categorySuggestion?`. - På lyckat resultat: granskningssteg där användaren bekräftar/skippar rader - och väljer produkt (via `ProductPickerField`), sedan bulk-spara till inventarie. - Komplexitetsgrad: hög — granskningsvyn är det tyngsta steget. **Nytt paket som krävs:** @@ -114,15 +103,10 @@ flutter/lib/features/import/ presentation/ import_screen.dart # TabBar: "Recept" | "Kvitto" recipe_import_tab.dart # Fas 6a — fil + URL, laddningsindikator - receipt_import_tab.dart # Fas 6b — fil, parse, granskning, spara -``` **Router och shell:** - Ny route `/import` inuti `ShellRoute` i `app_router.dart`. -- Ny nav-destination "Importera" med ikon `Icons.upload_file_outlined` i `app_shell.dart`, placeras efter "Baslager" och innan "Profil". - -**Felhantering:** - Multipart-uppladdning kan ta 5–30 s (OCR, LLM) — `LinearProgressIndicator` med text "Tolkar…" under hela anropet, inte en vanlig spinner. - Timeout via `http`-klienten: sätt `Duration(seconds: 120)` för import-anrop. @@ -133,32 +117,12 @@ flutter/lib/features/import/ 2. Utöka `CreateRecipeScreen` med `initialMarkdown`-parameter + GoRouter extra-stöd. 3. Bygg `domain/` + `data/` (modeller, repository, providers). 4. Bygg `recipe_import_tab.dart` (fas 6a — enklare). -5. Registrera route, lägg till nav-destination, verifiera end-to-end. -6. Bygg `receipt_import_tab.dart` (fas 6b — granskningssteg sist). - -### Deluppgifter -- [x] Lägg till `file_picker: ^8.0.0` i `pubspec.yaml`. -- [x] Utöka `CreateRecipeScreen` med optional `initialMarkdown` via GoRouter `extra`. -- [x] Skapa `domain/quick_import_result.dart` och `domain/parsed_receipt_item.dart`. -- [x] Skapa `data/import_repository.dart` med multipart-upload + JSON URL-metoder. -- [x] Skapa `data/import_providers.dart`. -- [x] Bygg `presentation/recipe_import_tab.dart` (fil + URL, lång laddningsindikator). -- [x] Bygg `presentation/import_screen.dart` med TabBar. - [x] Registrera `/import` i router och lägg till nav-destination i AppShell. - [ ] Verifiera recept-import end-to-end (fil + URL → create-screen). - [ ] Bygg `presentation/receipt_import_tab.dart` (uppladdning + granskningssteg). -- [ ] Verifiera kvitto-import end-to-end (fil → parse → granska → inventarie). - -## Fas 7 - Profil/admin parity -- Profil for alla anvandare. -- Role-aware navigation och skydd for adminytor. - Adminfunktioner migreras sist for att minimera risk i karnfloden. -## Contract-first per feature - -For varje feature: 1. Verifiera request/response mot befintligt backendkontrakt. -2. Mappa modeller robust (null-safe, fallback-falt, typskillnader). 3. Kontrollera felbanor innan UI-polish. Ingen ad-hoc backendforandring goras for att "fa Flutter att funka". @@ -167,7 +131,6 @@ Backend-andringar for user-scope i pantry/matplan ar explicit beslutade och ska ## Kvalitetsgrind (Definition of Done) En feature ar klar nar allt nedan ar uppfyllt: -1. API-floden fungerar for bade success och fel. 2. Auth/rollskydd fungerar (inklusive 401/403). 3. Loading/empty/error ar konsekvent hanterat. 4. Navigation in/ut ur feature fungerar utan specialfall. diff --git a/teknisk_beskrivning_flutter.md b/teknisk_beskrivning_flutter.md index d0692757..9a5cba2a 100644 --- a/teknisk_beskrivning_flutter.md +++ b/teknisk_beskrivning_flutter.md @@ -178,9 +178,20 @@ Om `test.gynther.se` slutar svara efter städning med `--remove-orphans`, starta - `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](next_steps_flutter.md): -1. Fortatt lokalisering av inventarie/pantry/recept-strangar till ARB. -2. Matplan parity mot nu user-scopat API. -3. Import parity. -4. Profil/admin parity. + +--- + +## Nyheter och förbättringar (2026-04-22) + +- **User-scope för pantry och matplan** — Flutter-klienten använder nu user-scopade endpoints för baslager och matplan. JWT används för filtrering i alla anrop. +- **Robust bildimport** — Bild-URL normaliseras och skickas hela vägen till UI. Flutter hanterar både markdown och bild-url vid import. +- **Importflöde** — Quick-import och receipt-import har förbättrats med robust multipart-hantering, timeout, och felhantering. Prefill av markdown och bild-url fungerar i Flutter. +- **Flutter-parity** — Matplan, inventarie, baslager och receptflöden är nu fullt migrerade till Flutter med user-scope och robust felhantering. +- **Felsökningslogg** — Se `../IMPORT_IMAGE_DEBUG_2026-04-22.md` för detaljerad felsökningshistorik kring bildimport och importflöde. + +### Kända begränsningar +- Kvittoimport (Fas 6b) är påbörjad men granskningssteg och bulk-spara återstår. +- Bildimport kräver att containrar är uppdaterade med senaste kod — kontrollera att diagnostikloggar syns vid felsökning. +- Vissa adminfunktioner och avancerad AI-integration är planerade men ej migrerade. + +---