187d0283a5
- Add support for PNG, JPEG, and WebP image formats in flyer import - Replace external importer service with internal AI-based parsing pipeline - Add new services: TextExtractorService, AiFlyerParserService, FlyerNormalizerService - Integrate Mistral AI, pdf-parse, and tesseract.js dependencies - Add quality confidence indicators and warning panels in Flutter UI - Update package.json with new dependencies and transform ignore patterns - Add documentation for flyer importer system - Add Kilo AI planning file for Happy Island project BREAKING CHANGE: Flyer import now uses internal AI parsing instead of external importer service
6.8 KiB
6.8 KiB
Plan: Omgjord flyerimport (pdf-parse + tesseract + Mistral Tiny)
Mål
Ersätta nuvarande flyerimportflöde (som idag delegerar till importer-api) med en robust pipeline som:
- extraherar text från flyer-PDF (primärt
pdf-parse, fallback OCR via Tesseract), - skickar normaliserad text till Mistral Tiny,
- returnerar strikt strukturerad JSON,
- behåller befintlig matchning/planeringsflöde i backend + Flutter men förbättrar UX kring importresultat och fel.
Nulägesanalys (projektanpassad)
- Backend endpoint finns:
POST /flyer-import/parseibackend/src/flyer-import/flyer-import.controller.ts. - Nuvarande backendlogik i
backend/src/flyer-import/flyer-import.service.tsanropar extern tjänst viaIMPORTER_SERVICE_URL(/api/flyer/parse). - Flutter har redan komplett flyerflik i
flutter/lib/features/import/presentation/flyer_import_tab.dart:- filval, importknapp, preview, radrendering med checkboxar, bulk-planering.
- Datamodell för sessions/items finns redan i Prisma (
FlyerSession,FlyerItem,FlyerSelection) och stödjer parse+match-metadata. flyerimporter.mdbeskriver rätt riktning men är generisk; projektet behöver NestJS-integration och kompatibilitet med befintliga DTO/Flutter-modeller.
Föreslagen arkitektur (ersättning av dagens lösning)
1) Ny intern parser i recipe-api (NestJS)
- Ersätt
parseViaImporter(...)iFlyerImportServicemed lokal pipeline:extractFlyerText(file)- PDF/text-extraktion via
pdf-parse. - Fallback OCR via Tesseract för sidor/underlag utan användbar text.
- PDF/text-extraktion via
parseFlyerWithMistral(text)- Mistral Tiny-anrop med strikt JSON-schema-prompt.
normalizeFlyerItems(aiJson)- validering, typkonvertering, enhetsnormalisering, confidence/reasonCodes.
- Behåll resten av tjänsten intakt (matchning, sessionpersistens, selections-kompatibilitet).
2) AI-kontrakt (strikt JSON)
- Introducera explicit schema för AI-svar (intern typ + runtime-validering):
rawName,normalizedName,category,price,priceUnit,comparisonPrice,comparisonUnit,offerText,confidence,reasonCodes.
- Promptdesign:
- svensk flyer-kontext,
- tydlig enhets- och prisnormalisering,
- "returnera ENDAST JSON" + exempel,
- fallback vid saknade fält (
null, tomma listor).
- Robust parsing av modelloutput:
- ta bort ev. markdown fences,
- fail-fast med tydligt felmeddelande om ogiltigt JSON.
3) OCR-strategi
- Primärväg:
pdf-parse(snabb, billig). - OCR-fallback: bara när extraherad text är tom/under tröskel.
- Preprocess för OCR (vid behov): sidvis rasterisering + språk
swe(ev.swe+eng). - Timeout/guardrails per steg för att undvika låsta importer.
4) API/infra-anpassning
- Controller (
flyer-import.controller.ts):- uppdatera tillåtna MIME-typer så de matchar Flutter-filtyper (PDF + bilder om vi ska stödja bildflyers).
compose.yml/env:- gör
IMPORTER_SERVICE_URLoptional eller avveckla för flyerflödet. - säkerställ
MISTRAL_API_KEYanvänds avrecipe-apiför flyer.
- gör
- Dokumentation:
- uppdatera teknisk beskrivning så flyerimport inte längre kräver extern flyer-parser.
UX-analys Flutter (nuvarande) och planerade förbättringar
Nuvarande UX (bra att bygga vidare på)
- Enkel 3-stegsinteraktion: välj fil -> importera -> markera/planera.
- Förhandsvisning finns och passar arbetsflödet.
- Offer-badge + pris/jämförpris + matchvisning ger snabb scanning.
UX-gap att täppa till i denna implementation
- Ingen tydlig visning av parserwarnings från backend (fältet
warningsfinns i modellen). - Ingen kvalitetssignal i UI trots att
parseConfidence/matchConfidencefinns. - Felmeddelanden är relativt råa; saknar råd per feltyp (timeout, ogiltig fil, AI-svar oformaterat).
Föreslagna UX-förbättringar (inkrementella, kompatibla)
- Visa
warningsöver resultatlistan i en kompakt varningspanel. - Lägg till "kvalitetsindikator" per rad (t.ex. låg/medel/hög) baserat på
parseConfidence+matchConfidence. - Lägg till filterchips:
Endast erbjudanden,Saknar matchning,Låg kvalitet. - Förbättra loading-state med stegnära text ("Extraherar text", "Tolkar med AI", "Matchar produkter").
- Felmappning till användarvänliga meddelanden i
showErrorDialog(teknisk detalj i kopierbar sekundärtext).
Implementationsplan (ordning)
Fas A - Backend kärna
- Lägg till dependencies i
backend/package.jsonför PDF/OCR/Mistral-klient. - Skapa intern flyer-parser service i
backend/src/flyer-import/(text extraction + AI parse). - Byt
parseViaImportertill intern implementation iFlyerImportService. - Lägg till runtime-validering och normalisering av AI-svar.
Fas B - Kontrakt och robusthet
- Säkerställ att response-format fortsatt matchar
FlyerImportResponse(ingen breaking change mot Flutter). - Förbättra controller MIME-regler så de stämmer med faktiska stödda format.
- Lägg till tydliga felkoder/meddelanden för:
- tom/oläsbar flyer,
- AI-parsefel,
- timeout/service unavailable.
Fas C - Flutter UX på befintlig skärm
- Visa backend
warningsiflyer_import_tab.dart. - Lägg till kvalitetsindikator + minimala filterchips.
- Förfina loading/feltexter utan att ändra grundlayouten.
Fas D - Verifiering
- Backendtester för intern flyer-parser (happy path + fallback + felbanor).
- Uppdatera/addera Flutter widgettester för warnings/indikator/filter.
- Manuell E2E: PDF med text, PDF med skannade sidor, bildflyer, trasig fil.
Filer som sannolikt berörs vid implementation
backend/src/flyer-import/flyer-import.service.tsbackend/src/flyer-import/flyer-import.controller.tsbackend/src/flyer-import/dto/flyer-import.response.ts(endast om extra metadata behövs)backend/package.jsonflutter/lib/features/import/presentation/flyer_import_tab.dart- Ev.
flutter/lib/features/import/domain/flyer_import_item.dart(om ny UI-metadata exponeras) - Dokumentation:
TEKNISK_BESKRIVNING.md(kort uppdatering av arkitektur)
Risker och mitigering
- OCR-prestanda/latens: använd fallback-only och timeout.
- Mistral kan ge semistrukturerat svar: strikt schema + robust JSON-sanitizing + validering.
- Kostnad/kvot på AI-anrop: minimera promptstorlek, trunkera brus, återanvänd normalisering.
- Driftöverraskningar: behåll endpoint-kontrakt oförändrat mot Flutter.
Acceptance criteria
- Flyerimport fungerar utan beroende av extern
/api/flyer/parsei importer-api. - Minst en PDF med inbäddad text och en skannad PDF importeras framgångsrikt.
- Backend returnerar valid
FlyerImportResponseoch befintlig planeringsfunktion fortsätter fungera. - Flutter visar warnings och gör det tydligare vilka rader som behöver manuell granskning.
Fastställt beslut
- Första leveransen ska stödja PDF + bildfiler (
png/jpg/webp) fullt ut.