5.3 KiB
5.3 KiB
Teknisk beskrivning av Microservice Importer
Dokumentstatus (2026-05-10)
Detta dokument riktar sig till utvecklare och driftansvariga för microservice-importer. Det beskriver arkitektur, drift och tekniska beslut för den interna importtjänsten.
Roll och ansvar
importer-api är en stateless intern tjänst för recipe-app. Den hanterar URL-skrapning, OCR, PDF-parsning, markdown-parsning och AI-kvittoparsning utan databas eller användarsessioner.
Arkitektur
Körmiljö
- NestJS 10
- TypeScript 5
- Node.js 22-alpine
- Port
3001internt - Exponeras bara på
recipe-internal-nätverket
Moduler
src/
├── app.module.ts # Root module + HealthController (GET /api/health)
├── main.ts
├── common/
│ ├── filters/global-exception.filter.ts
│ └── utils/normalize-name.ts
├── web-scraping-service/
│ ├── web-scraping.module.ts
│ ├── controllers/quick-import.controller.ts # POST /api/quick-import
│ ├── services/quick-import.service.ts # Scraping, OCR, PDF
│ └── parsers/
│ ├── base.parser.ts # ParsedRecipe interface
│ ├── ica.parser.ts # ICA.se JSON-LD + imageUrl
│ └── generic.parser.ts
├── receipt-parsing/
│ ├── receipt-parsing.module.ts
│ ├── receipt-parsing.controller.ts # POST /api/receipt-import/parse
│ └── receipt-parsing.service.ts
├── document-service/
│ ├── document-service.module.ts
│ ├── controllers/document-import.controller.ts
│ ├── services/document-import.service.ts
│ └── parsers/
│ ├── document.parser.ts
│ └── pdf.parser.ts
└── recipes/
├── recipes.module.ts
├── recipes.controller.ts # POST /api/recipes/parse-markdown
├── recipes.service.ts
└── dto/parse-markdown.dto.ts
Endpoints
| Endpoint | Funktion |
|---|---|
POST /api/quick-import |
URL-skrapning, bild-OCR och PDF-import |
POST /api/recipes/parse-markdown |
Markdown till strukturerat recept utan databas |
POST /api/receipt-import/parse |
Kvittobild/PDF till ParsedReceiptItem[] via Mistral AI |
GET /api/health |
Hälsokontroll för Docker healthcheck |
Kvittoparsning
Modell och pipeline
- Vision-input använder
mistral-small-2603 - PDF-flödet kör
pdf-parseellerpdfjs-dist/legacy/build/pdf.jssom fallback - Regelbaserad parsning körs före AI när det är möjligt
looksLikeReceiptProductLine()filtrerar bort rader utan siffra så att AI bara används för sannolika produktrader
Mängd- och enhetsregler
Följande regler är inbyggda i kvitto-prompten:
| Typ | Regel | Exempel |
|---|---|---|
| Lösvikt | quantity = faktisk vikt, unit = kg/g |
BLANDFÄRS 20% 0.997 kg |
| Förpackad vara med storlek i namn | quantity = antal förpackningar, unit = förp |
MJÖLK 1,5L × 3 |
| Multipack | quantity=1, unit=förp |
BACON 3X120G |
| Förpackat innehåll | quantity = antal förpackningar, unit = förp |
BRIOCHE SESAM × 2 |
| Lösa styckvaror | quantity = antal, unit = st |
BANAN × 1 |
Tillåtna enheter: st, kg, g, l, dl, cl, ml, förp, pak, burk, flaska.
Retry och stabilitet
- Mistral 429/503 backas av med
3000 * attemptms - PDF-flödet använder fallback för CJS- och Node Alpine-kompatibilitet
GlobalExceptionFilterger konsekventa felobjekt
Deployment
importer-api byggs och startas via recipe-app/compose.yml och inte via egen compose-fil.
Serverlayout
/opt/containers/
microservice-importer/
recipe-app/
compose.yml
deploy.sh
Driftsekvens
cd /opt/containers/microservice-importer && git pull
cd /opt/containers/recipe-app && git pull && ./deploy.sh
Hälsokontroll
docker exec importer-api wget -qO- http://localhost:3001/api/health
Tekniska detaljer
Byggberoenden
pdf-parsetesseract.js@mistralai/mistralaimulter
Alpine-paket
tesseract-ocrtesseract-ocr-data-swetesseract-ocr-data-eng
Viktiga tekniska beslut
- Tjänsten är stateless och saknar databaskonfiguration
- Importer exponeras aldrig externt, bara internt via Docker-nätverket
- Host-port 3001 är upptagen av
wettyoch får därför inte användas av tjänsten
Parser-arkitektur
Dokument-parsers
Abstrakt bas DocumentParser används för dokumenttypsspecifik parsing.
PDF Parser
pdf.parser.ts hanterar textbaserade PDFs. Skannade PDFs varnas och kan falla tillbaka på OCR-vägen.
Webb-parsers
ica.parser.tsprioriterar JSON-LD och extraherarimageUrlgeneric.parser.tsär fallback för webbplatser utan specialparser
Framtida utbyggnader
- Fler webbplats-parsers som Arla, Tasteline och Köket.se
- Word/import av
.docx - Swagger/OpenAPI-dokumentation
- Caching av skrapade sidor om belastningen mot externa webbplatser blir ett problem