723730fd2f
Co-authored-by: Copilot <copilot@github.com>
5.7 KiB
5.7 KiB
Plan för vidareutveckling av Microservice Importer
Dokumentstatus (2026-05-03)
Detta dokument riktar sig till utvecklare och driftansvariga för microservice-importer.
Senast avklarat i angränsande flöden
- Regelbaserad kvittotolkning har stärkts för multipack/enheter och svårare radformat.
- Bröd-/rostbrödklassning har utökade guardrails för att minska felaktig kategorisering.
- Klientens granskningsflöde och sessionpersistens i Flutter är implementerat, vilket minskar avbrott mellan parse och spara.
- Kvittokategorisering: nya regler för pasta, grädde, ägg, juice, godis, och potatis samt justerad AI-guardrail.
- Testinfrastruktur: parametriserade enhetstester för kvittoimport (18 testfall) och CI/CD-pipeline med automatiserad testkörning på push.
Status (2026-05-03) — Driftsatt och integrerad med recipe-app
microservice-importer körs som intern tjänst (importer-api) i recipe-app/compose.yml. Alla importflöden är delegerade och driftsatta.
| Endpoint | Funktion | Status |
|---|---|---|
POST /api/quick-import |
URL-skrapning (ICA, generisk), PDF, OCR-bild | ✅ Driftsatt |
POST /api/recipes/parse-markdown |
Markdown → ingrediensstruktur (utan DB) | ✅ Driftsatt |
POST /api/receipt-import/parse |
Kvittobild/PDF → ParsedReceiptItem[] via Mistral AI |
✅ Driftsatt |
GET /api/health |
Hälsokontroll (används av Docker healthcheck) | ✅ Driftsatt |
Serverstruktur:
/opt/containers/
microservice-importer/ ← klonas och pullas separat
recipe-app/
compose.yml ← bygger importer-api från ../microservice-importer
deploy.sh
Deploy:
cd /opt/containers/microservice-importer && git pull
cd /opt/containers/recipe-app && git pull && ./deploy.sh
Nästa steg
Hög prioritet
- Kvittoimport Fas 6b — Granskningssteg och bulk-spara i Flutter-klienten (backend-logiken är klar)
Medel prioritet
- Fler webbplats-parsers — Specifika parsers för t.ex. Tasteline, Köket.se, Arla
- Swagger/OpenAPI — Automatisk API-dokumentation via
@nestjs/swagger - Testtäckning — Utökad enhetstesttäckning för parsers och
receipt-parsing.service.ts(18 testfall för kvittoimport)
Låg prioritet / Framtida
- Caching — Cacha skrapade sidor för att minska belastning på externa webbplatser
- Puppeteer — Hantera JavaScript-renderade receptsidor
- Word-dokument — Stöd för
.docx-import
AI-optimering: Mistral-modell och pipeline
Nuläge: mistral-small-2603 används för kvittoparsning. Modellen tar emot hela kvittobilden/PDF-texten och returnerar strukturerad JSON.
Möjlig optimering: AI sist i pipeline
Eftersom tjänsten redan har OCR (Tesseract) och regelbaserad parsning (regex för NxYg, Ydl, Y kg etc.) finns möjlighet att omstrukturera kvittopipelinen:
Bild/PDF → OCR/pdf-parse → Regelbaserad parsning → AI (för rader som inte lösts ut)
Fördelar:
- Regelbaserad parsning hanterar standardfall gratis och snabbt (t.ex. "MJÖLK 1,5L", "BLANDFÄRS 997G")
- AI anropas bara för rader som regelverket inte kan tolka entydigt
- Möjlighet att använda en mindre/billigare modell för enklare tolkningsuppgifter
Modellval för olika deluppgifter
| Uppgift | Rekommenderad modell | Motivering |
|---|---|---|
| Kvittoparsning (hela bilden, nuläge) | mistral-small-2603 |
Vision-förmåga krävs för bild-input |
| Tolka OCR-text (textbaserad input) | mistral-small-latest eller mindre |
Enklare uppgift när text redan extraherats |
| Kategorisering av enskild produktrad | open-mistral-nemo (7B) |
Klassificering, ej vision — kan vara mycket liten |
OBS: För bild-input (JPEG/PNG/HEIC/WebP) krävs alltid en vision-kapabel modell. Optimering med mindre modell är bara möjlig när Tesseract/pdf-parse redan har extraherat text.
Framtida förbättringar
Schemalagd Uppdatering av Kategorier
- Mål: Implementera en schemalagd uppdatering av kategorierna en gång i veckan för att säkerställa att cachen alltid är uppdaterad.
- Metod: Använda
cronför att schemalägga ett anrop tillPOST /receipt-import/refresh-categoriesen gång i veckan.
Nuvarande Implementering
Manuell Uppdatering av Kategorier
- Mål: Låta användaren manuellt uppdatera kategorierna via Flutter-UI.
- Implementering:
- En knapp i Flutter-UI:n som låter användaren trigga uppdateringen.
- Anropa
POST /receipt-import/refresh-categoriesfrån Flutter-UI:n när användaren klickar på knappen.
// Exempel på hur du kan anropa endpointen från Flutter
Future<void> refreshCategories() async {
final response = await http.post(
Uri.parse('http://YOUR_API_URL/receipt-import/refresh-categories'),
headers: {'Authorization': 'Bearer YOUR_JWT_TOKEN'},
);
if (response.statusCode == 200) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Kategorier har uppdaterats.')),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Misslyckades med att uppdatera kategorier.')),
);
}
}
Arkitektur-noteringar
- Tjänsten är helt stateless — ingen databas, ingen session
- Kommunicerar aldrig direkt med internet-klienter — exponeras bara på
recipe-internal-nätverket MISTRAL_API_KEYinjiceras via env (samma nyckel somrecipe-apianvänder)- Alpine Docker-image: systempaket
tesseract-ocr,tesseract-ocr-data-swe,tesseract-ocr-data-enginstallerade viaapk - Host-port 3001 är upptagen av
wettypå servern —importer-apiexponeras aldrig till host