From 73309cb1103e0021001376d0e53a387a45cc6474 Mon Sep 17 00:00:00 2001 From: Nils-Johan Gynther Date: Thu, 7 May 2026 14:15:45 +0200 Subject: [PATCH] feat: implement alias strategy for receipt import with matchedVia tracking --- README.md | 18 ++++++++++++++--- RECIPE_IMPORT_REFACTOR_PLAN.md | 12 +++++++++++- TEKNISK_BESKRIVNING.md | 35 +++++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f26227c5..2d1e56cd 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,12 @@ En fullstack-applikation för hantering av hemmavaror och recept. Håll koll på Detta dokument är skrivet för användare och produktägare. Fokus är vad som fungerar i appen och vad som förbättrats i det dagliga flödet. ### Nytt sedan senaste sessionerna +- **Alias-strategi för kvittoimport:** + - Backend och Flutter har nu stöd för användarspecifika alias (user-alias) och globala alias (admin). + - Varje rad i kvittoimporten visar nu en badge som anger hur matchningen skedde: **Alias**, **Ordmatch** eller **AI-kategori**. + - Alla användare kan spara egna alias direkt vid import ("Spara som alias"), admins kan spara globala alias. + - Ny profilsida: användare kan se och radera sina alias. + - Admin-panelen för alias visar nu produkt-ID och tydligare radstruktur. - Kvittoimporten har blivit mer träffsäker för förpackningar och mängder (t.ex. rader med multipack och "2st"). - Kategorisering av brödrelaterade produkter har förbättrats så att färre varor hamnar fel. - Ny underkategori i kategoriträdet: `Bröd & Kakor > Bröd > Fastfoodbröd > Korvbröd`. @@ -43,9 +49,15 @@ Detta dokument är skrivet för användare och produktägare. Fokus är vad som --- -## Funktioner +### Funktioner -### Inventorie (Hemmavaror) +### Kvittoimport och alias +- **Alias-badge:** Varje rad i kvittoimporten visar nu en badge som anger om matchningen skedde via Alias, Ordmatch eller AI-kategori. +- **Spara som alias:** Alla användare kan spara egna alias direkt vid import. Admins kan spara globala alias. +- **Alias-hantering:** Användare kan se och radera sina alias på profilsidan. Admins har en förbättrad panel med produkt-ID och tydligare radstruktur. +- **Prioritering:** Systemet prioriterar användarens egna alias före globala alias och ordmatchning. + +### Inventarie (Hemmavaror) - **Lägg till, redigera och ta bort varor** — hantera produkt, kvantitet, enhet, plats, märke och bäst före-datum - **Filtrera och sortera** — efter plats (kyl, frys, skafferi), bäst före-datum, och namn (A–Ö) - **Konsumera varor** — registrera förbrukad mängd med eventuell kommentar @@ -57,7 +69,7 @@ Detta dokument är skrivet för användare och produktägare. Fokus är vad som - **Grupperat per kategori** — produkterna i baslagret visas grupperade under kategorirubrik - **Lägg till och ta bort** — välj från produktlistan via sökbar dropdown, ta bort med ett klick ---- +---- ### 📌 Så använder du Inventarie och Baslager diff --git a/RECIPE_IMPORT_REFACTOR_PLAN.md b/RECIPE_IMPORT_REFACTOR_PLAN.md index 50fa5a38..2cde2584 100644 --- a/RECIPE_IMPORT_REFACTOR_PLAN.md +++ b/RECIPE_IMPORT_REFACTOR_PLAN.md @@ -296,7 +296,17 @@ Analysen blir en egen endpoint. --- -## 6. Receptmodul + +--- + +## 7. Alias-strategi och matchedVia (2026-05-07) + +- Alias-strategin är nu fullt implementerad: + - Backend och Flutter stödjer user-alias och globala alias. + - matchedVia-badge visas i UI (Alias/Ordmatch/AI). + - Användare kan spara egna alias, admins kan spara globala. + - Profilsidan har alias-lista för användare, admin-panelen visar produkt-ID och radstruktur. + - Backend har 3 nya tester för matchedVia, totalt 66 tester gröna. ### Fil: `backend/src/recipes/recipes.module.ts` diff --git a/TEKNISK_BESKRIVNING.md b/TEKNISK_BESKRIVNING.md index 3209f942..79db72f7 100644 --- a/TEKNISK_BESKRIVNING.md +++ b/TEKNISK_BESKRIVNING.md @@ -146,14 +146,36 @@ sker på remote server. Säkerställ att inga absoluta Windows-sökvägar anv --- ## Nyheter och förbättringar (2026-05-02) + ## Nyheter och förbättringar (2026-05-07) +- **Alias-strategi och matchedVia:** + - Backend: `ParsedReceiptItem` har fått fältet `matchedVia: 'alias' | 'wordmatch' | 'ai' | 'none'` som sätts i matchningslogiken och returneras till klienten. + - Flutter: matchedVia visas som badge i UI (Alias/Ordmatch/AI-kategori). Alias-lärande är öppet för alla användare (user-alias), admins kan spara globala alias. + - Användare kan se och radera sina alias på profilsidan. Admin-panelen visar produkt-ID och tydligare radstruktur. + - Prioritering: Egna alias (ownerId=userId) används före globala alias (isGlobal=true), därefter ordmatchning och sist AI. + - Tester: 3 nya tester för matchedVia i backend, totalt 66 tester gröna. - **Inventory user-scope och IDOR-skydd:** InventoryItem-modellen har fått userId, migration har backfillat data, och alla endpoints kräver nu CurrentUser. Service och controller är uppdaterade, och tester för IDOR-skydd är på plats. - **.gitignore och deploy-hygien:** backend/dist och backend/tsconfig.tsbuildinfo är nu ignorerade och ej längre spårade. .env och .env.* ignoreras, .env.example är komplett. -- **CI/CD-härdning:** npm audit och prisma validate körs i pipeline. Testsviten (63 tester) och build måste passera. +- **CI/CD-härdning:** npm audit och prisma validate körs i pipeline. Testsviten (66 tester) och build måste passera. -### Ny databasarkitektur: user-scoped produkter +### Alias-strategi och matchedVia (detaljer) + +- **Datamodell:** + - `ReceiptAlias` har fälten `ownerId` (user-alias), `isGlobal` (global alias) och prioriteras i matchningslogik. + - `matchedVia` sätts i backend och skickas till Flutter. +- **UI-flöde:** + - Vid kvittoimport visas badge för matchkälla. + - "Spara som alias" är tillgängligt för alla användare (sparar user-alias), admins kan spara globalt. + - Profilsidan har en alias-lista där användaren kan radera egna alias. + - Admin-panelen visar alla globala alias, produktnamn och produkt-ID. +- **Prioriteringsordning:** + 1. Egna alias (ownerId=userId) + 2. Globala alias (isGlobal=true) + 3. Ordmatchning + 4. AI-kategori + Produkttabellen är omgjord till ett fullständigt user-scope-modell. Beslutet grundar sig på att en global produktkatalog skapade falska matchningar i kvittoimport för nya användare (produkter "hittades" fast användaren aldrig lagt till dem). @@ -192,6 +214,7 @@ Nya noder sedan 2026-05-01: | L3 under Allergi mejeri | Matfett | | L3 under Allergi mejeri | Allergi matlagning | + ### Regelbaserad kategoridetektion (`ruleBasedCategorySuggestion`) Funktionen i `receipt-import.service.ts` matchar kvittonamn mot nyckelord och returnerar rätt kategori direkt — utan AI-anrop. Täcker: @@ -203,7 +226,13 @@ Funktionen i `receipt-import.service.ts` matchar kvittonamn mot nyckelord och re `AiService.suggestCategory()` remappar `low`/`medium`-konfidenspoäng till L1-föräldern istället för att returnera ett potentiellt fel L2/L3. Loggning sker via NestJS Logger. -### Förbättrad produktmatchning + +### Förbättrad produktmatchning och alias + +`matchProducts()` i `receipt-import.service.ts`: +- Returnerar nu även `matchedVia` för varje rad: 'alias', 'wordmatch', 'ai' eller 'none'. +- Alias prioriteras enligt ovan. +- Flutter visar badge och styr alias-lärande utifrån matchedVia. `findWordMatch()` i `receipt-import.service.ts`: - **Diakritiksnormalisering** — `normalizeToken()` konverterar å→a, ä→a, ö→o före jämförelse. Löser t.ex. `gradde` == `grädde`.