feat(import): implement recipe import functionality with file and URL support
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
+76
-2
@@ -72,8 +72,82 @@ Adminfloden migreras efter att ovanstaende ar verifierat.
|
||||
- [x] Swipe-för-±1 på inventarielistan (SwipeableInventoryTile med visuell ledtråd).
|
||||
|
||||
## Fas 6 - Import parity
|
||||
- URL/PDF/bild via befintliga endpoints.
|
||||
- Tydlig hantering av langkorande anrop och fel.
|
||||
|
||||
### 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:**
|
||||
- `file_picker: ^8.0.0` — hanterar filval på Flutter web (ger `Uint8List bytes`,
|
||||
ingen filsökväg). Läggs till i `pubspec.yaml`.
|
||||
|
||||
**Fil-/mappstruktur:**
|
||||
```
|
||||
flutter/lib/features/import/
|
||||
domain/
|
||||
quick_import_result.dart # { markdown, source, imageUrl? }
|
||||
parsed_receipt_item.dart # { rawName, quantity, unit, ... }
|
||||
data/
|
||||
import_repository.dart # API-anrop (multipart + JSON URL-läge)
|
||||
import_providers.dart # Riverpod-providers
|
||||
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.
|
||||
- Nätverks- och serverfel mappas via befintlig `mapErrorToUserMessage`.
|
||||
|
||||
**Genomförandeordning:**
|
||||
1. Lägg till `file_picker` i `pubspec.yaml`.
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user