# Analys av `plan importer willys.md.txt` i projektkontext ## Kontext och utgångsläge Den analyserade planen finns i `microservice-importer/plan importer willys.md.txt` och beskriver ett förslag för: - premium-gating av AI - PDF-import av Willys-underlag - produktmatchning mot inventory - receptgenerering med AI (Mistral) eller mallar Jämfört med faktisk arkitektur i era tre repos: - `recipe-app`: äger användare, premium/AI-flaggor, inventory, recept, auth, adminflöden och databas (Prisma + MariaDB). - `microservice-importer`: stateless import/parsing utan databas; ansvarar för quick-import, markdown-parse och receipt-parse. - `recipe-gitea-runner`: CI-exekvering med labels `backend-node24` och `flutter-3-41`. ## Sammanfattande bedömning Planen är ambitiös men **inte direkt kompatibel** med nuvarande systemdesign. Den blandar ansvar mellan tjänster, använder kodmönster som avviker från era etablerade stackval och återinför funktioner ni redan implementerat i annan form. Hög nivå: - Bra: tydlig stegstruktur, fallback-idé (AI -> templates), fokus på robust importflöde. - Problem: arkitekturdrift (DB i importer), felaktig domänmodell för era nuvarande User/Product-fält, Express-exempel i NestJS-miljö, svag validering/säkerhet i flera snippets. ## Styrkor att återanvända - Tydlig domänuppdelning i delsteg: extrahering -> parsing -> matchning -> generering. - Fallback-first-princip vid AI-fel (ligger i linje med era befintliga principer). - Intention att normalisera och strukturera råtext innan beslut i senare led. - Fokus på svenska enheter/uttryck som passar era kvittoflöden. ## Kritiska gap mot befintlig arkitektur 1. **Fel placerat ansvar (största gapet)** - Planen föreslår Prisma/DB i importer-flödet (`prisma.user`, `encryptedData.create`, premiumfält m.m.). - Er importer är dokumenterat stateless och DB-lös. - Rekommendation: all user/premium/inventory/recipe persistence ska ligga i `recipe-app` backend, inte i `microservice-importer`. 2. **Premium-modell avviker från faktisk datamodell** - Planen använder `is_premium` och `premium_expiry_date`. - I `recipe-app` används `isPremium` + `aiEngineEnabled` redan, med admin-styrning och JWT-scope. - Rekommendation: återanvänd befintliga fält/guards; undvik parallel premiummodell. 3. **Framework mismatch (Express vs NestJS)** - Planen innehåller Express-routerexempel medan repos är NestJS-moduler/controllers/services. - Rekommendation: all ny implementation bör följa NestJS module/service/controller + DTO + class-validator. 4. **Datamodell-krockar** - Planen antar tabeller/fält som inte finns i nuvarande schema (`encryptedData`, snake_case-kolumner osv). - Rekommendation: mappa mot faktiska modeller (`User`, `Product`, `InventoryItem`, `Recipe*`) eller skapa tydlig migrationplan med namngiven adapter. 5. **Överlapp med befintlig funktionalitet** - Ni har redan importerad kvittoparsning med regelmotor + AI-fallback och premium/ai-scope. - Rekommendation: undvik ”nytt parallellt flöde”; bygg som utökning av befintliga receipt/import pipelines. ## Tekniska förbättringar av själva planen ### A. Arkitekturförbättringar (måste prioriteras) - **Inför tydligt kontrakt mellan tjänsterna** - `microservice-importer`: parse/normalize only (ingen userstate). - `recipe-app`: auth, premium-gating, produktmatchning, persistence. - **Skapa explicit API-kontrakt för kampanjblad/Willys** - ny endpoint i importer, exempel: `POST /api/flyer/parse`. - svar med strikt schema: produkter, erbjudandeflaggor, normaliserade mått/enheter, confidence. - **Beslut i recipe-app** - besluta AI/template på basis av `isPremium && aiEngineEnabled`. - lagra endast i recipe-app DB. ### B. Datakontrakt och validering - Ersätt `any` med typed DTO/interfaces i båda repos. - Lägg till strikt validering (zod eller class-validator) för: - parsed flyer rows - matched product payload - generated recipe payload - Definiera versionerat kontrakt (`v1`) så importer och app kan deployas oberoende. ### C. Parser-kvalitet och robusthet (Willys-specifikt) - Nuvarande regex-idé är för skör för verkliga PDF-varianter. - Förbättra med pipeline: 1) textblock-normalisering 2) radklassificering (kategori, produkt, prisrad, metadata) 3) enhetsnormalisering (`förp`, `st`, `kg`) 4) probabilistisk matchscore per fält - Lägg in rule priority + fallback AI bara för osäkra rader (som ni redan gör i receipt flow). ### D. Matchning mot inventory - Planens fuzzy-match på 0.6 riskerar falska positiva. - Förslag: - kombinera alias > exact-normalized > token-similarity > levenshtein. - category-guardrails (finns redan i receipt-flöde, återanvänd). - trösklar per kategori (mejeri/kött behöver striktare gränser än exotiska varor). - returnera `matchedVia`, `confidence`, `reasonCodes` för UI-debugg och lärande. ### E. AI-generering - Planen gör fri JSON-parsning från modelltext; hög risk för parse-fel. - Förslag: - använd strikt output schema + reparationssteg vid JSON-avvikelse. - lägg budget/timeouts/retries per request. - prompta på begränsad produktmängd (top-N relevanta) för lägre kostnad/latens. - logga token-användning och feltyper för cost observability. ### F. Säkerhet - Behåll premium-kontroll i backend (ej klient). - Lägg rate limiting även på nya flyer-endpoints. - Undvik filsystemberoende (`multer dest + fs.unlinkSync`) om möjligt; använd bufferbaserad pipeline. - Lägg explicit content-type + storleksgräns + filsignature-validering. ### G. Drift och CI (recipe-gitea-runner) - Lägg nya testjobb med labels ni redan har: - `backend-node24`: contract tests mellan app/importer. - `backend-node24`: parser regression suite med fixtures från riktiga Willys-underlag. - Lägg minimikrav i CI: - typecheck - unit tests parser + matcher - contract tests importer <-> recipe-app - build - Publicera artifact med parser-rapport (precision/recall på fixture-set) för varje PR. ## Konkreta optimeringar per repo ### 1) `microservice-importer` - Lägg till separat modul `flyer-parsing` istället för att återanvända receipt rakt av. - Returnera endast normaliserad och validerad struktur, aldrig användarspecifika beslut. - Återanvänd befintlig robusthet: - fallback parsing - timeout/retry-mönster - global exception shape. - Bygg fixture-driven tester för Willys-format (varianter med OCR-brus, multipack, kampanjtext). ### 2) `recipe-app` - Implementera orkestreringstjänst för flyerimport: - anropa importer - matcha mot user-scopade produkter - premium-gata AI-recept (isPremium + aiEngineEnabled) - spara recept via befintliga modeller - Exponera adminfeature toggle för ”flyer-recipe-generation” (separation från övrig AI om ni vill kontrollera rollout). - Lägg telemetri per steg: parse time, match confidence distribution, AI fallback rate. ### 3) `recipe-gitea-runner` - Säkra att workflow i `recipe-app` inkluderar integrationstest mot importer (mockad eller ephemeral service). - Lägg nattlig regressionkörning för parser-fixtures för att fånga drift i regex/regler. - Behåll labels som idag; komplettera med tydligare jobbseparation i CI (quick PR vs full push). ## Prioriterad implementeringsplan (reviderad) 1. **Målbild/ansvar (P0)** - Fastställ och dokumentera kontrakt: importer parser-only, app stateful orchestration. 2. **Kontrakt + DTO (P0)** - Definiera `FlyerParseResponse v1` och valideringsregler. 3. **Importer-modul (P1)** - Implementera Willys/flyer parser i `microservice-importer` med tester + fixtures. 4. **Recipe-app orkestrering (P1)** - Ny service i backend som mappar parse-resultat till matchning + recipe generation. 5. **Premium-gating harmonisering (P1)** - Använd enbart `isPremium` + `aiEngineEnabled`; ta bort/undvik expiry-logik om den inte behövs produktmässigt. 6. **Observability + säkerhet (P1)** - Metrics, structured logs, rate limits, upload guards. 7. **CI-utbyggnad (P2)** - Contract tests + parser regression suite i Gitea workflows. ## Risker om planen implementeras oförändrad - Arkitekturspret: dubbla sanningskällor för premium och recipes. - Ökad driftkomplexitet: importer blir stateful och svårare att skala/deploya. - Regressionsrisk: ny kod duplicerar befintlig receipt/importlogik. - Säkerhets- och datakvalitetsrisk: svag typing/validering + osäker JSON-parsning från AI-svar. ## Rekommenderad riktning (kort) Använd planen som **idékatalog**, inte som direkt implementation. Behåll er nuvarande ansvarsfördelning mellan repos, bygg Willys-stödet som en ny parserdomän i `microservice-importer`, och låt `recipe-app` fortsätta vara enda platsen för användarlogik, premiumbeslut och datalagring. Detta ger lägst risk och bäst kompatibilitet med er nuvarande kodbas, driftmodell och CI-upplägg.