165 lines
11 KiB
Markdown
165 lines
11 KiB
Markdown
# Nasta steg
|
|
|
|
Detta ar huvudroadmap for Recipe App.
|
|
All detaljhistorik och djup teknisk bakgrund finns i respektive tekniska dokument.
|
|
|
|
## Dokumentstatus (2026-05-03)
|
|
|
|
- Fokus: en gemensam prioriteringslista for produkt, utveckling och drift.
|
|
- Delplaner for underomraden ska referera hit, inte duplicera hela roadmapen.
|
|
|
|
## MVP-plan (2026-05-10)
|
|
|
|
MVP ar uppnadd nar en vanlig anvandare kan importera, granska och spara kvitto/recept utan manuella specialsteg, och admin kan underhalla produkt- och kategoridata stabilt i drift.
|
|
|
|
### Fas 1 - Scopefrysning och releasekandidater
|
|
|
|
1. Las MVP-scope till foljande floden:
|
|
- Kvittoimport end-to-end (parse -> granska -> spara).
|
|
- Receptimport end-to-end (url/pdf/ocr/markdown -> granska -> spara).
|
|
- Admin inventarie/product-hantering (CRUD, merge, filter, restore).
|
|
2. Markera uttryckligen allt annat som post-MVP i denna fil (t.ex. EAN/Open Food Facts, utokad AI, storre webbsakerhetsomlaggning).
|
|
3. Faststall releasekandidat for backend + flutter med versionsetikett.
|
|
|
|
### Fas 2 - Hard validering i produktionslik miljo
|
|
|
|
1. Kor manuell verifiering av aliasstrategi med riktiga kvitton (privat alias, global fallback, prioriteringsordning).
|
|
2. Kor fulla regressionsfloden for import, matchning, kategorisering, merge och spara.
|
|
3. Verifiera deployflode och driftkommandon pa server med healthcheck efter release.
|
|
|
|
### Fas 3 - MVP-release
|
|
|
|
1. Publicera releasekandidat nar alla gransvarden ar godkanda.
|
|
2. Folj upp med kort hypercare-period (felrattning med hog prioritet, inga nya features).
|
|
|
|
### Exit-kriterier (Definition of Done for MVP)
|
|
|
|
- End-to-end importfloden fungerar stabilt for minst ett representativt urval av kvitton och receptkallor.
|
|
- Aliasprioritering fungerar deterministiskt: user alias -> global alias -> ordmatchning -> AI.
|
|
- User-scope och IDOR-skydd ar verifierat i kritiska domaner.
|
|
- Admin kan hantera produkter/inventarie utan datakorruption eller behov av manuella DB-ingrepp.
|
|
- Deploy, healthcheck och testkorning ar reproducerbara i driftmiljo.
|
|
|
|
|
|
## Nyligen klart
|
|
|
|
- **2026-05-10:** Admin-inventarie (CRUD, merge, filter, sortering, preview, säkerhet), user-scope, IDOR-skydd, säkerhetshärdning, optimeringar och utökad testtäckning är nu genomförda och dokumenterade i README, TEKNISK_BESKRIVNING, SÄKERHETSHÄRDNINGSPLAN och SESSIONLOGGAR.
|
|
|
|
- Kvittoimport: förbättrad antal/förpackningsinferens och robustare regelmotor.
|
|
- Kategorisering: utökade brödregler + contradiction guards och nya regler för pasta, grädde, ägg, juice, godis, och potatis.
|
|
- Kategoriträd: nya noder `Korvbröd` under `Fastfoodbröd` och `Grädde` under `Matlagning` i seed-data.
|
|
- Flutter: klientpersistens för pågående kvittoimport.
|
|
- Produktmodell: user-scoped produkter och seed renodlad till kategorier.
|
|
- Testinfrastruktur: parametriserade enhetstester för kvittoimport (18 testfall).
|
|
- CI/CD: GitHub Actions-pipeline för automatiserad testkörning vid push och pull request.
|
|
- **Node.js versionsparitet:** `package-lock.json` spåras nu i git för båda repos; Dockerfiles kör `npm ci` — reproducerbara byggen i alla miljöer.
|
|
- **PDF-kvittoimport stabiliserad:** `pdf-parse` CJS-fix + `pdfjs-dist/legacy` fallback löser `DOMMatrix`-fel i Node.js.
|
|
- **Felkods-forwarding fixad:** `receipt-import.service.ts` i recipe-api vidarebefordrar nu 503 från importer-api som `ServiceUnavailableException` istället för att alltid returnera 400.
|
|
- **AI-optimering (PDF):** `looksLikeReceiptProductLine()` i importer-api filtrerar bort header/footer-rader — Mistral anropas enbart för rader som faktiskt kan vara produkter.
|
|
- **Receptparser hardening:** gemensam parserutility, intervall/parantes/brak-forbattringar samt testtackning for parsern.
|
|
- **Receptsakerhet och dataintegritet:** aktiv-produktvalidering, transaktion vid update, orphan-fil-cleanup och striktare owner-hantering av legacy-recept.
|
|
- **Alternativa ingredienser (Option A):** lagring i `alternativeProductIds` (JSON), matchning mot flera alternativ och lagerkoll som inkluderar alternativ.
|
|
- **Flutter felhantering:** kopierbara felmeddelanden i snackbar + global textselektion for enklare support/felsokning.
|
|
- **Kvittoimport — Simplified Matching Logic (2026-05-09):** Unified matcher som konsoliderar product matching + categorization i en explicit flödestre. Eliminar split mellan `matchProducts()` och `enrichWithAiCategories()`. Ger tydligare trace-logging och bättre debuggability för varför ett item matchades på ett visst sätt. Systemet är nu mer underhållsbart och framtida förbättringar på matching/kategorisering går snabbare.
|
|
|
|
## Huvudprioriteringar
|
|
|
|
1. 🟡 Aliasstrategi i kvittoimport: DELVIS GENOMFÖRD (2026-05-09)
|
|
- Målbild:
|
|
- Vanliga användare skapar och använder privata alias som bara gäller deras egna importer.
|
|
- Admin kan dessutom skapa globala alias som fungerar som fallback för alla användare.
|
|
- Matchningsordning ska alltid vara: user alias -> global alias -> vanlig produktmatchning.
|
|
- Genomfört nu:
|
|
- Gemensam aliasnormalisering införd för lookup, upsert och alias-inlärning.
|
|
- Guardrails införda för tomma alias och brusalias som `rabatt`, `summa`, `pant`.
|
|
- Receipt import lär inte längre in alias automatiskt; användaren måste välja det explicit i edit-dialogen.
|
|
- Aliasöversikter i Flutter visar nu scope tydligare (`privat` vs `global fallback`).
|
|
- Tester tillagda för normalisering, prioritet och behörighet.
|
|
- Kvar:
|
|
- Manuell verifiering i produktionslik miljö av aliasflödet under riktig receipt import.
|
|
- Eventuell vidareutveckling av separat aliasöversikt om behov uppstår.
|
|
- Backend:
|
|
- Centralisera normalisering av `receiptName` så samma regler används i lookup, upsert och alias-inlärning.
|
|
- Härda guardrails för alias: blockera tomma alias, uppenbart brus (`rabatt`, `summa`, `pant`) och andra olämpliga kvittonamn.
|
|
- Säkerställ deterministisk prioritet mellan privata och globala alias i receipt-import.
|
|
- Behåll nuvarande schema i första fasen; ingen ny migration behövs så länge nuvarande `ReceiptAlias`-modell räcker.
|
|
- Flutter:
|
|
- Lägg alias-lärande nära manuell korrigering i receipt-import så användaren explicit kan välja att spara matchningen för framtida importer.
|
|
- Lägg en enkel aliasöversikt där användaren kan se och ta bort sina privata alias.
|
|
- Admin-UI ska kunna skapa globala alias utan att blanda ihop dem med vanliga användares privata alias.
|
|
- Tester:
|
|
- Verifiera att user alias alltid prioriteras före global alias för samma `receiptName`.
|
|
- Verifiera att global alias används när user alias saknas.
|
|
- Verifiera att vanlig användare inte kan skapa globala alias eller ta bort andras alias.
|
|
- Verifiera att manuell korrigering + `learnAlias` ger direkt träff vid nästa import.
|
|
- Verifiera att normalisering gör alias robust mot versaler, whitespace och enklare stavningsvariationer.
|
|
- Leveransordning:
|
|
- ✅ Fas 1: backend-hardening + tester.
|
|
- ✅ Fas 2: UI-stöd i receipt import för alias-inlärning.
|
|
- 🟡 Fas 3: separat aliasöversikt för användare och admin (grund finns, kan vidareutvecklas vid behov).
|
|
2. ✅ **[CLEANUP] Receipt import legacy code (2026-05-09):** KLART
|
|
- Borttaget: `matchProducts()`, `enrichWithAiCategories()`, `findWordMatch()` (gammal), m.fl.
|
|
- Tester uppdaterade och gröna (66/66)
|
|
- Se `SESSION_2026-05-09_RECEIPT_IMPORT.md` för detaljer
|
|
3. ✅ **[FEATURE] Product Management & Scroll Fix (2026-05-09):** KLART
|
|
- Scroll-issue i kvittoimport fixat (7 rader nu synliga)
|
|
- Admin rename/merge endpoints implementerade
|
|
- Private rename/merge endpoints för users implementerade
|
|
- Kodduplicering i products.service.ts eliminerad (~80 rader)
|
|
- admin_products_panel optimerad (cache, parallell restore, expression switches)
|
|
- Deploy-script förbättrad med selektiv build och seed-kontroll
|
|
- Se `SESSION_2026-05-09_RECEIPT_IMPORT.md` för detaljer
|
|
- **Todo:** Deploy till prod, testa i live miljö, ev. add UI för user private rename/merge
|
|
4. Stabilisera bildimport och diagnostik i alla miljöer.
|
|
5. Lokalisera kvarvarande stora Flutter-vyer i import/inventarie.
|
|
6. Förbereda avancerad AI-integration med tydlig loggning/audit.
|
|
7. Påbörja EAN-stöd via Open Food Facts.
|
|
|
|
## Beslut som styr arbetet
|
|
|
|
- User-scope for data som ar personligt agd.
|
|
- Backend-kontrakt ar sanningskalla; klienter foljer kontrakten.
|
|
- Importfunktionalitet ar delegerad till microservice-importer dar det ar beslutat.
|
|
|
|
## Framtida förbättringsområden
|
|
|
|
### Säkerhet: httpOnly cookies för Flutter Web
|
|
|
|
Idag lagras JWT-token i localStorage via SharedPreferences i Flutter Web. För att minska XSS-risk bör backend och Flutter Web stödja httpOnly-cookies för tokens. Detta kräver:
|
|
- Backend: endpoint för att sätta och läsa httpOnly-cookie vid login.
|
|
- Flutter Web: anpassning så att token inte läses från localStorage utan session hanteras via cookie.
|
|
Detta är en större arkitekturändring och endast relevant för webben.
|
|
|
|
### Säkerhet: Gitea webhook-signaturvalidering
|
|
|
|
Om Gitea-webhooks används, implementera endpoint i backend som validerar `X-Gitea-Signature` med timing-safe jämförelse. Lägg till `GITEA_WEBHOOK_SECRET` i .env.example. Se säkerhetshärdningsplanen för kodexempel.
|
|
|
|
### Alternativa ingredienser — migrering till relationsmodell (Option B)
|
|
|
|
Nuläge: `RecipeIngredient.alternativeProductIds` lagras som JSON-kolumn (Option A).
|
|
Detta fungerar men saknar referensintegritet — om en alternativ produkt tas bort uppdateras inte kolumnen automatiskt.
|
|
|
|
Framtida lösning: Ersätt JSON-kolumnen med en separat tabell:
|
|
```prisma
|
|
model RecipeIngredientAlternative {
|
|
id Int @id @default(autoincrement())
|
|
recipeIngredientId Int
|
|
recipeIngredient RecipeIngredient @relation(fields: [recipeIngredientId], references: [id], onDelete: Cascade)
|
|
productId Int
|
|
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
|
|
}
|
|
```
|
|
Fördelar: FK-integritet, möjlig sortering/prioritering av alternativ, lättare att querrya.
|
|
Förutsättning: migration som konverterar befintlig JSON-data till rader i tabellen.
|
|
|
|
## Relaterade dokument
|
|
|
|
- `README.md` - anvandarperspektiv.
|
|
- `TEKNISK_BESKRIVNING.md` - teknisk huvudreferens.
|
|
- [produktlansering.md](_archive/docs/produktlansering.md) - releasechecklista i arkiv.
|
|
- [migrering-MSI.md](_archive/docs/migrering-MSI.md) - migreringshistorik for importer i arkiv.
|
|
- [flutter/next_steps_flutter.md](_archive/docs/flutter/next_steps_flutter.md) - Flutter-specifik plan i arkiv.
|
|
- `_archive/microservice-ai/AI-FUNKTIONER.md` - AI-strategi och historik.
|
|
|
|
## 2026-05-10: Admin-inventarie (CRUD, merge, filter, sortering, preview, säkerhet), user-scope, IDOR-skydd, säkerhetshärdning, optimeringar och utökad testtäckning är nu genomförda och dokumenterade i README, TEKNISK_BESKRIVNING, SÄKERHETSHÄRDNINGSPLAN och SESSIONLOGGAR.
|