Files
microservice-importer/TEKNISK_BESKRIVNING.md
T
Nils-Johan Gynther 9fbb99e7a1
Test Suite / test (24.15.0) (push) Has been cancelled
fix: update documentation status and upgrade dependencies to NestJS 11 and multer 2.1.1
2026-05-12 22:01:40 +02:00

173 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Teknisk beskrivning av Microservice Importer
## Dokumentstatus (2026-05-12)
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](../recipe-app). Den hanterar URL-skrapning, OCR, PDF-parsning, markdown-parsning och AI-kvittoparsning utan databas eller användarsessioner.
## Arkitektur
### Körmiljö
- NestJS 11
- TypeScript 5
- Node.js 22-alpine
- Port `3001` internt
- Exponeras bara på `recipe-internal`-nätverket
### Moduler
```text
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-parse` eller `pdfjs-dist/legacy/build/pdf.js` som 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 * attempt` ms
- PDF-flödet använder fallback för CJS- och Node Alpine-kompatibilitet
- `GlobalExceptionFilter` ger konsekventa felobjekt
## Deployment
`importer-api` byggs och startas via [recipe-app/compose.yml](../recipe-app/compose.yml) och inte via egen compose-fil.
### Serverlayout
```text
/opt/containers/
microservice-importer/
recipe-app/
compose.yml
deploy.sh
```
### Driftsekvens
```bash
cd /opt/containers/microservice-importer && git pull
cd /opt/containers/recipe-app && git pull && ./deploy.sh
```
### Hälsokontroll
```bash
docker exec importer-api wget -qO- http://localhost:3001/api/health
```
## Tekniska detaljer
### Byggberoenden
- `pdf-parse`
- `tesseract.js`
- `@mistralai/mistralai`
- `multer` 2.1.1
### Versionsnotering
- NestJS-paket är uppgraderade till 11-serien för att ta bort sårbarheter i beroendekedjan.
- Nest CLI 11 kräver Node.js 20.11+ i CI- och byggmiljöer.
### Alpine-paket
- `tesseract-ocr`
- `tesseract-ocr-data-swe`
- `tesseract-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 `wetty` och 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.ts` prioriterar JSON-LD och extraherar `imageUrl`
- `generic.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
## Referenser
- [README.md](README.md)
- [NEXT_STEPS.md](next_steps_MSImporter.md)