Files
microservice-importer/next_steps_MSImporter.md
T

4.9 KiB

Plan för vidareutveckling av Microservice Importer

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 — Enhetstester för parsers och receipt-parsing.service.ts

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 cron för att schemalägga ett anrop till POST /receipt-import/refresh-categories en 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-categories frå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_KEY injiceras via env (samma nyckel som recipe-api använder)
  • Alpine Docker-image: systempaket tesseract-ocr, tesseract-ocr-data-swe, tesseract-ocr-data-eng installerade via apk
  • Host-port 3001 är upptagen av wetty på servern — importer-api exponeras aldrig till host