6.1 KiB
Microservice Importer
Intern import-tjänst (importer-api) för recipe-app. Hanterar URL-skrapning, OCR, PDF-parsning och AI-kvittoparsning utan databas. Körs som Docker-tjänst på det interna recipe-internal-nätverket — exponeras ej externt.
Viktigt!! Kod- och byggpraxis!
Säkerställ att inga absoluta Windows-sökvägar används i koden, för att stödja bygg och drift på Linux/Ubuntu
Features
Quick-import (POST /api/quick-import)
- URL-skrapning — ICA.se (JSON-LD) och generisk parser. Extraherar
imageUrlfrån receptbild. - OCR (bild) — tesseract.js, svenska+engelska. Returnerar
source: 'image'. - PDF-parsning — pdf-parse för digitala PDFs, OCR-fallback för skannade.
- Multipart — Tar emot antingen JSON-body (
{ url }) eller FormData (file).
Parse-Markdown (POST /api/recipes/parse-markdown)
Tolkar Markdown-recept till strukturerat JSON utan databas.
Kvittoparsning (POST /api/receipt-import/parse)
- Bild (JPEG/PNG/WebP/HEIC/HEIF) eller PDF
- Mistral AI vision med retry-logik (3 försök vid 503/429)
- Returnerar
ParsedReceiptItem[]
Health (GET /api/health)
Används av Docker-healthcheck i recipe-app/compose.yml. Returnerar { status: "ok" }.
Miljövariabler
| Variabel | Beskrivning | Standardvärde |
|---|---|---|
MISTRAL_API_KEY |
API-nyckel för Mistral AI | (krävs för kvittoparsning) |
PORT |
HTTP-port | 3001 |
Arkitektur
Backend (NestJS 10, TypeScript 5, Node.js 22-alpine)
Port: 3001 (intern, ej exponerad till host)
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/ # Quick-import (URL + fil)
│ ├── 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/ # Kvittoparsning via Mistral AI
│ ├── receipt-parsing.module.ts
│ ├── receipt-parsing.controller.ts # POST /api/receipt-import/parse
│ └── receipt-parsing.service.ts
├── document-service/ # PDF-dokumentimport
│ ├── document-service.module.ts
│ ├── controllers/document-import.controller.ts
│ ├── services/document-import.service.ts
│ └── parsers/
│ ├── document.parser.ts
│ └── pdf.parser.ts
└── recipes/ # Markdown-tolkning
├── recipes.module.ts
├── recipes.controller.ts # POST /api/recipes/parse-markdown
├── recipes.service.ts
└── dto/parse-markdown.dto.ts
Viktigt: Backend har INGEN databaskonfiguration — stateless service.
Parser-arkitektur
Dokument-parsers (document-service/parsers/)
Abstrakt bas DocumentParser som alla dokumenttyp-specifika parsers ärver från.
PDF Parser (pdf.parser.ts)
Hanterar textbaserade PDFs via pdf-parse. Skannade PDFs varnas.
Webb-parsers (web-scraping-service/parsers/)
Abstrakt bas RecipeParser med canHandle(url) + parse(html). Implementationer:
ica.parser.ts— ICA.se, prioriterar JSON-LD structured data, extraherarimageUrlgeneric.parser.ts— Fallback för alla webbplatser
Deployment
importer-api byggs och startas via recipe-app/compose.yml — ej via sin egen compose-fil.
Serverstruktur:
/opt/containers/
microservice-importer/ ← klonas separat, pullas vid deploy
recipe-app/
compose.yml ← definierar importer-api-tjänsten
deploy.sh ← kör docker compose build + up
Deploy:
# 1. Uppdatera importer (om ändringar gjorts)
cd /opt/containers/microservice-importer && git pull
# 2. Bygg och starta alla containers
cd /opt/containers/recipe-app && git pull && ./deploy.sh
Loggar:
docker logs importer-api -f
Hälsokontroll:
docker exec importer-api wget -qO- http://localhost:3001/api/health
# → {"status":"ok"}
OBS: Host-port 3001 används av wetty på servern. importer-api exponeras aldrig utanför Docker-nätverket — anropas via http://importer-api:3001 från recipe-api.
Tekniska detaljer
Backend Stack
- NestJS 10 — REST API & modular architecture
- TypeScript 5 — Type safety
- Node.js 22-alpine — Runtime (Alpine Linux)
- pdf-parse — PDF text extraction
- tesseract.js — OCR (bild och skannade PDFs, svenska + engelska)
- @mistralai/mistralai — AI-kvittoparsning
- multer — Multipart file upload handling
- Ingen databas — Stateless service
Systempaket (Alpine)
Installerade i Dockerfile runner-stage:
tesseract-ocr
tesseract-ocr-data-swe
tesseract-ocr-data-eng
Error Handling
- Centraliserad
GlobalExceptionFilter(svenska meddelanden) - Konsistent JSON-responsformat:
{ statusCode, message, timestamp, path } - HTTP status codes: 200, 400, 503
Framtida utbyggnader
- PDF-import — textbaserad extraction
- OCR för skannade bild-PDFs (tesseract.js + Alpine-paket)
- Kvittoparsning via Mistral AI
- ICA-receptbildsextraktion (
imageUrliParsedRecipe) - Fler webbplats-parsers (Arla, Tasteline, Köket.se)
- Word (.docx) import
- Swagger/OpenAPI-dokumentation
- Rate limiting / Caching
Licens
MIT
Support
- Git Repo — Gitea på
192.168.50.2:2222/nilsjohan/microservice-importer