fix: enhance PDF parsing and retry logic; improve reproducibility and AI filtering
Test Suite / test (24.15.0) (push) Has been cancelled
Test Suite / test (24.15.0) (push) Has been cancelled
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -12,8 +12,10 @@ Detta dokument är för systemadministratörer och utvecklare som driftar eller
|
|||||||
- Parserstödet för brödrelaterade produkter och guardrails mot felkategorisering har utökats.
|
- Parserstödet för brödrelaterade produkter och guardrails mot felkategorisering har utökats.
|
||||||
- Integrationen med klienten för kvitto-session är fortfarande stateless i denna tjänst; ingen serverlagring av användarsession infördes.
|
- Integrationen med klienten för kvitto-session är fortfarande stateless i denna tjänst; ingen serverlagring av användarsession infördes.
|
||||||
- Kvittokategorisering: nya regler för pasta, grädde, ägg, juice, godis, och potatis samt justerad AI-guardrail.
|
- Kvittokategorisering: nya regler för pasta, grädde, ägg, juice, godis, och potatis samt justerad AI-guardrail.
|
||||||
- Testinfrastruktur: parametriserade enhetstester för kvittoimport (18 testfall) och CI/CD-pipeline med automatiserad testkörning på push.
|
- Testinfrastruktur: parametriserade enhetstester för kvittoimport (18 testfall) och CI/CD-pipeline med automatiserad testkörning på push.- **PDF-fix:** `pdf-parse` importeras nu med `require()` (CJS-kompatibilitet). `pdfjs-dist/legacy/build/pdf.js` används som fallback för att undvika `DOMMatrix is not defined` i Node.js-miljö.
|
||||||
|
- **Retry-förbättring:** Mistral 429/503 → väntar `3000 * attempt` ms innan nytt försök.
|
||||||
|
- **Reproducerbart bygge:** `package-lock.json` spåras i git; Dockerfile kör `npm ci`.
|
||||||
|
- **AI-skippning för icke-produktrader:** `looksLikeReceiptProductLine()` filtrerar PDF-rader utan siffra (header/footer/butiksinformation) — dessa skickas inte till Mistral.
|
||||||
## Viktigt!! Kod- och byggpraxis!
|
## 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
|
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
|
||||||
|
|
||||||
@@ -32,7 +34,8 @@ Tolkar Markdown-recept till strukturerat JSON utan databas.
|
|||||||
|
|
||||||
### Kvittoparsning (`POST /api/receipt-import/parse`)
|
### Kvittoparsning (`POST /api/receipt-import/parse`)
|
||||||
- Bild (JPEG/PNG/WebP/HEIC/HEIF) eller PDF
|
- Bild (JPEG/PNG/WebP/HEIC/HEIF) eller PDF
|
||||||
- **Modell:** `mistral-small-2603` (vision-kapabel) med retry-logik (3 försök vid 503/429)
|
- **Bild:** `mistral-small-2603` (vision-kapabel) med retry-logik (3 försök, `3000 * attempt` ms fördröjning vid 429/503)
|
||||||
|
- **PDF:** `pdf-parse` → fallback `pdfjs-dist/legacy` → regelbaserad parsning → AI enbart för rader med namntext + siffra
|
||||||
- Returnerar `ParsedReceiptItem[]` med fälten `rawName`, `quantity`, `unit`, `price`, `brand`, `origin`
|
- Returnerar `ParsedReceiptItem[]` med fälten `rawName`, `quantity`, `unit`, `price`, `brand`, `origin`
|
||||||
- Inbyggda regler i AI-prompten styr tolkning av `quantity`/`unit` (se nedan)
|
- Inbyggda regler i AI-prompten styr tolkning av `quantity`/`unit` (se nedan)
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ Detta dokument riktar sig till utvecklare och driftansvariga för microservice-i
|
|||||||
- Klientens granskningsflöde och sessionpersistens i Flutter är implementerat, vilket minskar avbrott mellan parse och spara.
|
- Klientens granskningsflöde och sessionpersistens i Flutter är implementerat, vilket minskar avbrott mellan parse och spara.
|
||||||
- Kvittokategorisering: nya regler för pasta, grädde, ägg, juice, godis, och potatis samt justerad AI-guardrail.
|
- Kvittokategorisering: nya regler för pasta, grädde, ägg, juice, godis, och potatis samt justerad AI-guardrail.
|
||||||
- Testinfrastruktur: parametriserade enhetstester för kvittoimport (18 testfall) och CI/CD-pipeline med automatiserad testkörning på push.
|
- Testinfrastruktur: parametriserade enhetstester för kvittoimport (18 testfall) och CI/CD-pipeline med automatiserad testkörning på push.
|
||||||
|
- **PDF-parsning stabiliserad:** `pdf-parse` använder nu `require()` för CJS-kompatibilitet; `pdfjs-dist/legacy/build/pdf.js` används som fallback för att undvika `DOMMatrix`-fel i Node.js-miljö.
|
||||||
|
- **Retry-logik förbättrad:** Mistral-anrop vid 429/503 väntar nu `3000 * attempt` ms (3s, 6s, 9s) i stället för fast 1s.
|
||||||
|
- **Reproducerbart bygge:** `package-lock.json` är nu spårat i repot; Dockerfile använder `npm ci`.
|
||||||
|
- **AI-optimering implementerad:** `looksLikeReceiptProductLine()` filtrerar bort PDF-rader utan siffra (header/footer/butiksinformation) innan Mistral-anrop. Minskar drastiskt antal onödiga AI-anrop vid kvittoimport.
|
||||||
|
|
||||||
## Status (2026-05-03) — Driftsatt och integrerad med recipe-app
|
## Status (2026-05-03) — Driftsatt och integrerad med recipe-app
|
||||||
|
|
||||||
@@ -43,7 +47,6 @@ cd /opt/containers/recipe-app && git pull && ./deploy.sh
|
|||||||
|
|
||||||
### Hög prioritet
|
### Hög prioritet
|
||||||
- **Kvittoimport Fas 6b** — Granskningssteg och bulk-spara i Flutter-klienten (backend-logiken är klar)
|
- **Kvittoimport Fas 6b** — Granskningssteg och bulk-spara i Flutter-klienten (backend-logiken är klar)
|
||||||
- **Node.js versionsparitet** — Lås samma Node-version i lokal utveckling, Docker-image och CI-runner för att eliminera miljödrift mellan build och runtime.
|
|
||||||
|
|
||||||
### Medel prioritet
|
### Medel prioritet
|
||||||
- **Fler webbplats-parsers** — Specifika parsers för t.ex. Tasteline, Köket.se, Arla
|
- **Fler webbplats-parsers** — Specifika parsers för t.ex. Tasteline, Köket.se, Arla
|
||||||
@@ -59,16 +62,18 @@ cd /opt/containers/recipe-app && git pull && ./deploy.sh
|
|||||||
|
|
||||||
## AI-optimering: Mistral-modell och pipeline
|
## 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.
|
**Nuläge:** `mistral-small-2603` används för bildinput (vision). För PDF-flödet extraheras text först via `pdf-parse`/`pdfjs-dist`; sedan regelbaserad parsning; sedan AI enbart för återstående rader.
|
||||||
|
|
||||||
### Möjlig optimering: AI sist i pipeline
|
### Implementerad optimering: AI sist i pipeline (PDF)
|
||||||
|
|
||||||
Eftersom tjänsten redan har OCR (Tesseract) och regelbaserad parsning (regex för `NxYg`, `Ydl`, `Y kg` etc.) finns möjlighet att omstrukturera kvittopipelinen:
|
Kvittopipelinen för PDF ser nu ut:
|
||||||
|
|
||||||
```
|
```
|
||||||
Bild/PDF → OCR/pdf-parse → Regelbaserad parsning → AI (för rader som inte lösts ut)
|
PDF → pdf-parse / pdfjs-dist → preprocessPdfLines → isIgnoredReceiptLine → ruleBasedParseLine → looksLikeReceiptProductLine → AI
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**`looksLikeReceiptProductLine(line)`** filtrerar bort rader som saknar siffra (butiksnamn, datum, välkomsttext m.m.) innan Mistral-anropet. Enbart rader med namnliknande text OCH minst ett tal skickas till AI.
|
||||||
|
|
||||||
**Fördelar:**
|
**Fördelar:**
|
||||||
- Regelbaserad parsning hanterar standardfall gratis och snabbt (t.ex. "MJÖLK 1,5L", "BLANDFÄRS 997G")
|
- 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
|
- AI anropas bara för rader som regelverket inte kan tolka entydigt
|
||||||
|
|||||||
Reference in New Issue
Block a user