fix: update documentation status and enhance technical description for microservice importer
Test Suite / test (24.15.0) (push) Has been cancelled

This commit is contained in:
Nils-Johan Gynther
2026-05-11 16:41:20 +02:00
parent c639eae270
commit 4596b80408
3 changed files with 230 additions and 263 deletions
+167
View File
@@ -0,0 +1,167 @@
# 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](../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 `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`
### 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)