chore(docs): consolidate legacy documentation into new structure
- Removed outdated documentation files (MVP_CHECKLISTA.md, NEXT_STEPS.md, README.md, TEKNISK_BESKRIVNING.md, filanalys.md, flyerimporter.md, kilo.json, plan-dokumentation.md) - Added new centralized documentation structure under docs/ directory - Added .kilo/ directory for Kilo AI agent configuration and plans BREAKING CHANGE: Legacy documentation files removed and replaced with new centralized structure
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
# MVP-checklista: Recipe App (maj 2026)
|
||||
|
||||
## 1. Funktionell sluttestning (produktion/lik miljö)
|
||||
- [ ] Testa inventarie: skapa, ändra, ta bort, ändra kategori, filtrera, konsumera, historik.
|
||||
- [ ] Testa baslager: lägg till/ta bort, ändra kategori, filtrera, grupperad vy.
|
||||
- [ ] Testa receptimport: länk, PDF, bild, Markdown. Kontrollera parser, fallback, och matchning.
|
||||
- [ ] Testa produktadmin: merge, bulk-kategorisering, AI-kategorisering, dubblett-hantering, statuskö.
|
||||
- [ ] Testa alias: skapa, ta bort, user/global, badge i UI.
|
||||
- [ ] Testa seed-data: kontrollera att nya kategorier finns efter deploy.
|
||||
- [ ] Testa navigation: admin-knapp i profilmeny, alla länkar och vyer.
|
||||
|
||||
## 2. Säkerhet och access ✅
|
||||
- [x] Verifiera user-scope och IDOR-skydd på alla endpoints. (86 tests, PASS)
|
||||
- [x] Testa rollbaserad access (admin/user). (86 tests, PASS)
|
||||
- [x] Kontrollera JWT, throttling, och inputvalidering. (86 tests, PASS)
|
||||
|
||||
## 3. Regression och buggrättning ✅
|
||||
[ ] Fixa eventuella UI-buggar (scroll, dropdown, state).
|
||||
|
||||
[ ] Slutgiltig README och teknisk beskrivning.
|
||||
- [ ] Kontrollera .env-exempel och seed-instruktioner.
|
||||
|
||||
## 5. UI/UX-polish
|
||||
- [ ] Loading states, felmeddelanden, mobilanpassning.
|
||||
- [ ] Extra tester för bulk-operationer, AI-förslag, aliasradering.
|
||||
|
||||
## 6. Release
|
||||
- [ ] Tagga release i git.
|
||||
- [ ] Deploy till produktion.
|
||||
- [ ] Bekräfta drift och funktion i live-miljö.
|
||||
@@ -0,0 +1,223 @@
|
||||
## Utforda steg (2026-05-20)
|
||||
|
||||
- [x] **Deploy-script uppdaterat:** `deploy.sh` forenklat genom att ta bort `--migrate`; `--clean-database` kor nu migrering explicit innan rensning.
|
||||
- [x] **Prisma-integrering i deploy:** `--clean-database` kor `prisma migrate deploy` i `recipe-api` med explicit schema-parameter for att sakerstalla uppdaterat schema fore SQL-rensning.
|
||||
- [x] **Loggsynlighet for Prisma Client:** `deploy.sh` visar nu output fran `npx prisma generate` i terminalen vid migreringsrelaterade deployfloden.
|
||||
- [x] **Databasrensning standardiserad:** Ny underhallsfil `backend/prisma/maintenance/clean-database.sql` skapad for reset som bevarar kategorier.
|
||||
- [x] **Produktionsnara fel rattat:** `clean-database.sql` korrigerad efter serverfel (`Table 'ShoppingList' doesn't exist`).
|
||||
- [x] **Tabellista hardad:** SQL-filen anvander nu existerande tabeller i nuvarande Prisma-schema och tar bort beroenden i saker ordning med `FOREIGN_KEY_CHECKS`.
|
||||
|
||||
## Utförda steg (2026-05-21)
|
||||
|
||||
- [x] **Flyer AI-trace persisteras:** `AiFlyerParserService` returnerar trace-data (prompt/rawOutput/chunkCount/retryCount) och `FlyerImportService` sparar detta i `AiTrace` med `source=flyer`.
|
||||
- [x] **Admin AI observability utökad:** `AiTraceService` hämtar kompletterande flyer-trace via `sessionId` och exponerar prompt/output/retry/chunk i detaljvyn.
|
||||
- [x] **Maskning i trace-detail:** känslig data maskas konsekvent i prompt/raw output/normaliserad output innan retur till admin-UI.
|
||||
- [x] **Flyer-kvalitet:** dedupe justerad för att minska dubletter utan att slå ihop olika kampanjer; hårdostnamn använder korrekt åäö.
|
||||
- [x] **Kontextstyrd OCR-korrigering:** kända fel (ex. `Pröd`) korrigeras endast i relevant textkontext för att minska falska rättningar.
|
||||
- [x] **Flutter Admin AI-panel UX:** selekterbar prompt/output, varningspanel med kopiering och output-trunkering med expandera/kollapsa.
|
||||
|
||||
# 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
|
||||
|
||||
## Utförda steg (2026-05-19)
|
||||
|
||||
- [x] **Flyerimport-sessioner i backend:** Implementerat session-endpoints för senaste och specifik session.
|
||||
- [x] **Flyerimport-persistens i Flutter:** Lättviktig lagring i `SharedPreferences` med `sessionId` + vald state.
|
||||
- [x] **Hydreringsflöde i klient:** Restore lokalt -> hämta via sessionId -> fallback till latest-session.
|
||||
- [x] **HTTP-semantik + optimering:** 404 för saknad session och single-query för latest-session.
|
||||
- [x] **Regressionstester:** Backendtester för flyer-sessioner tillagda och gröna (3/3).
|
||||
|
||||
## Utförda steg (2026-05-18)
|
||||
|
||||
- [x] **ESLint i backend + CI:** ESLint-konfiguration tillagd i backend och CI-workflow uppdaterad med lint-step för PR/push.
|
||||
- [x] **Dart lint-konfig aktiverad:** `flutter/analysis_options.yaml` tillagd för att säkerställa `flutter_lints` i analyskörningar.
|
||||
- [x] **Prisma query logging styrbar per miljö:** `PRISMA_LOG_QUERIES` implementerad i backend samt kopplad i `compose.yml`.
|
||||
- [x] **Dokumenterat aktivering av query-loggar:** Instruktion att sätta `PRISMA_LOG_QUERIES=1` och starta om `recipe-api` i test/staging.
|
||||
- [x] **Korrigerat testförväntan i receipt-import:** Security-test för saknat användar-id uppdaterat till `UnauthorizedException`.
|
||||
|
||||
## Utförda steg (2026-05-13)
|
||||
|
||||
- [x] **Centralt hjälptextsystem (backend):** Nytt `HelpTextsModule` med service, controller och DTO. `GET /api/help-texts/:key` returnerar rätt hjälptext baserat på användarroll (prioritetsordning: admin → user → default). `PUT /api/help-texts/:key/:scope` kräver admin-roll.
|
||||
- [x] **Prisma-migration:** `20260513150000_add_help_texts` — `HelpText`-tabell med `@@unique([key, scope])`-constraint och index. Seed-data för `receipt_import` (default + admin-scope) på svenska.
|
||||
- [x] **Flutter — "Läs hjälp"-knapp:** `TextButton.icon` i receipt_import_tab hämtar hjälptext från backend och visar AlertDialog med scopeindikator och datum.
|
||||
- [x] **Deploy och verifiering:** Migration tillämpad på produktionsserver (`recipe-api` ombyggd och omstartad). Backend och Flutter live och funktionellt.
|
||||
- [x] **Copilot-instruktioner:** `.github/copilot-instructions.md` tillagd i samtliga tre repos med robust `.env`-läsningsmönster.
|
||||
|
||||
## Utförda steg (2026-05-12)
|
||||
|
||||
- [x] **Alias-scopehantering (admin):** Admin kan höja privat alias → globalt via PATCH-endpoint. Backend blockerar omvänd riktning utan owner (`BadRequestException`). Vanliga användare blockeras med `ForbiddenException`.
|
||||
- [x] **Admin alias-UI:** Switch i edit-dialog begränsad till privat → global (låst om redan globalt). Temporär bekräftelse-chip visas 6 s i listan.
|
||||
- [x] **Kategori-chip fallback:** "okänd"-chip borttagen globalt – fallback returnerar `SizedBox.shrink()`.
|
||||
- [x] **Beroendehärdning:** Nest 11 + multer 2.1.1. `npm audit --audit-level=high` = 0 sårbarheter i recipe-app backend.
|
||||
- [x] **Quality-gates:** `prisma:validate`, `typecheck`, `audit:high`, `quality:ci` tillagda som npm-scripts. CI kör nu typecheck i PR- och push-jobb.
|
||||
- [x] **Tester:** Ny testtäckning för alias-scope i `receipt-alias.service.spec.ts` och `receipt-alias.security.spec.ts` (16/16 passerar).
|
||||
|
||||
## Utförda steg (2026-05-11)
|
||||
|
||||
- [x] Löste Flutter web build-fel och säkerställde att Docker-build går igenom på både lokal och server.
|
||||
- [x] Dokumenterade rutiner för hantering av build-artifacts och merge-konflikter.
|
||||
- [ ] Säkerställ att .gitignore exkluderar alla genererade Flutter-filer.
|
||||
|
||||
- **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. Verifiera flyerimportens sessionhydrering end-to-end i test/staging (tab-byte + app-omstart).
|
||||
5. Lägg till retention-policy och schemalagd rensning för `AiTrace` (receipt/flyer) för att styra datalivslängd i produktion.
|
||||
6. Lägg till API-stöd för filtrering av trace-lista på `status` och fri textsökning i varningskoder.
|
||||
7. Lokalisera kvarvarande stora Flutter-vyer i import/inventarie.
|
||||
8. Förbereda avancerad AI-integration med tydlig loggning/audit.
|
||||
9. 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.
|
||||
+459
@@ -0,0 +1,459 @@
|
||||
# Nyheter och förbättringar (2026-05-24)
|
||||
|
||||
- **Supply-chain-skydd för npm i backend:** `backend/.npmrc` innehåller nu `min-release-age=1`, vilket kräver att paketversioner är minst 1 dag gamla innan `npm install`/`npm ci` tillåts.
|
||||
- **CI påverkas automatiskt:** Backend-jobben i GitHub Actions använder redan `npm ci` i `backend/` och följer därmed policyn utan workflow-ändringar.
|
||||
- **Driftpolicy:** Vid blockerad akut uppgradering väntar vi normalt ut cooldown-fönstret i stället för att öppna generell policy.
|
||||
- **Deprecation-kedja åtgärdad i backend-teststacken:** `jest` uppgraderad till 30.x och backend använder en kontrollerad `overrides` för `test-exclude`, vilket tar bort `inflight@1.0.6` och `glob@7` från dependency-trädet.
|
||||
- **Felsökning av transitiva varningar:** Kör `npm ls <paket>` i `backend/` för att se exakt toppnivåkälla innan åtgärd (uppdatera direkt beroende först, `overrides` endast vid behov).
|
||||
- **Uppdateringspolicy för dependencies:** Säkerhets- och deprecation-relaterade backend-beroenden prioriteras löpande och ska normalt hanteras i närmast följande utvecklingscykel.
|
||||
|
||||
# Nyheter och förbättringar (2026-05-21)
|
||||
|
||||
- **Flyer AI-trace end-to-end:** flyer-importen sparar nu prompt/output/metadata i `AiTrace` (source=`flyer`) och adminpanelen kan visa detaljerad trace per session.
|
||||
- **Bättre produktkvalitet vid flyer-import:** dedupe förbättrad för att minska dubletter, hårdostnamn normaliseras med korrekt åäö, samt kontextstyrd OCR-korrigering för kända fel.
|
||||
- **Admin AI-panel förbättrad:** model output och prompt är selekterbara, varningar visas med detaljer + kopieringsstöd, och status har tooltip med förklaring.
|
||||
- **Stora outputs hanteras bättre i UI:** outputkortet trunkerar stora JSON-svar och låter admin expandera vid behov.
|
||||
|
||||
# Nyheter och forbattringar (2026-05-20)
|
||||
|
||||
- **Deploy-flode for migrering/rensning uppdaterat:** `deploy.sh` kor automatisk migrering vid vanlig deploy, medan `--clean-database` nu forst kor explicit `prisma migrate deploy` och sedan rensnings-SQL. Flaggan `--migrate` ar borttagen.
|
||||
- **Prisma Client-output i deploy-logg:** Vid migreringsrelaterat deployflode skrivs output fran `npx prisma generate` ut i terminalen (inklusive versionsnotiser), sa att status syns direkt i `deploy.sh`.
|
||||
- **Ny underhallsfil:** `backend/prisma/maintenance/clean-database.sql` infordes for kontrollerad reset av data i test/staging.
|
||||
- **Serververifiering och fix:** Rensningsskriptet uppdaterades efter verkligt driftfel (`ShoppingList` saknades) och pekar nu pa tabeller som faktiskt finns i schema/databas.
|
||||
|
||||
# Nyheter och förbättringar (2026-05-19)
|
||||
|
||||
- **Flyerimport-sessioner i backend:** Nya endpoints `GET /api/flyer-import/sessions/latest` och `GET /api/flyer-import/sessions/:sessionId` för att återhämta senaste eller specifik importsession per användare.
|
||||
- **Persistens i Flutter för flyerimport:** `flyer_import_session.dart` sparar nu endast `sessionId`, `fileName` och valda rader i `SharedPreferences` för lättviktig cache.
|
||||
- **Hydrering vid återöppning:** Flutter-tabben återläser lokalt tillstånd och hämtar därefter full session från backend, med fallback till senaste session.
|
||||
- **Robustare felsemantik:** Backend returnerar `NotFoundException` (404) för saknade sessioner i stället för `BadRequestException`.
|
||||
- **Verifiering:** Backend typecheck och tjänstetester (`flyer-import.service.spec.ts`, 3/3) passerar.
|
||||
|
||||
# Nyheter och förbättringar (2026-05-18)
|
||||
|
||||
- **CI: ESLint för backend:** ESLint är infört i backend (`backend/eslint.config.mjs`) och körs i GitHub Actions (`.github/workflows/test.yml`) via steget `Lint backend`.
|
||||
- **CI: Dart lints aktiverade:** `flutter/analysis_options.yaml` är tillagd med `include: package:flutter_lints/flutter.yaml`, så `flutter analyze` använder explicita lint-regler.
|
||||
- **Prisma query logging i test/staging:** Backend stödjer nu env-styrd query-loggning via `PRISMA_LOG_QUERIES` i `backend/src/prisma/prisma.service.ts`.
|
||||
- **Compose-stöd för loggning:** `compose.yml` har `PRISMA_LOG_QUERIES: "${PRISMA_LOG_QUERIES:-0}"` för säker default av.
|
||||
- **Testfix receipt-import:** Säkerhetstestet för saknat användar-id i `upsertUnitMapping` är uppdaterat till `UnauthorizedException`, i linje med controllerns beteende.
|
||||
|
||||
# Nyheter och förbättringar (2026-05-13)
|
||||
|
||||
- **Centralt hjälptextsystem:** Nytt backend-modul (`HelpTextsModule`) med `GET /api/help-texts/:key` (rollmedveten) och `PUT /api/help-texts/:key/:scope` (admin). Stöd för scopade hjälptexter: `admin`, `user`, `default` med prioritetsordning beroende på användarroll.
|
||||
- **Prisma-migration:** `20260513150000_add_help_texts` — skapar `HelpText`-tabell och seedar initiala hjälptexter för kvittoimport (standard + admin-variant) på svenska.
|
||||
- **Flutter — "Läs hjälp"-knapp i kvittoimport:** Nytt `TextButton.icon` med `Icons.help_outline` i headern på receipt_import_tab. Hämtar hjälptext från backend vid klick och visar den i en AlertDialog med titel, innehåll (selekterbart), scope-chip och uppdateringsdatum.
|
||||
- **Copilot-instruktioner:** `.github/copilot-instructions.md` tillagd i alla tre repos för att alltid använda robust `.env`-läsningsmönster (grep/sed/tr) vid databas-kommandon.
|
||||
|
||||
# Nyheter och förbättringar (2026-05-10)
|
||||
|
||||
- **Admin-inventarie:** Full CRUD, merge, filter, sortering, preview och säkerhet för admin i inventarietabellen. Endast admin kan se och hantera alla användares inventarieposter via nya endpoints och adminpanel i Flutter.
|
||||
- **User-scope och IDOR-skydd:** Inventory och produkter är nu strikt user-scopade. Alla operationer kräver och filtrerar på userId. Tester verifierar att åtkomst nekas vid försök till IDOR.
|
||||
- **Säkerhetshärdning:** DTO-validering, guard-ordning, logging, throttling, merge abuse-skydd, och rollbaserad access är implementerat och testat.
|
||||
- **Optimeringar:** DRY i service-lager, striktare query parsing, preview-cache, API-cleanup, och kodduplication eliminerad.
|
||||
- **Testtäckning:** Utökade enhets-, integrations- och säkerhetstester för alla kritiska flöden.
|
||||
|
||||
# Session 2026-05-06: User-scoped AI-fallback, admin-toggles och premium-funktioner
|
||||
|
||||
Under denna session har Recipe App fått:
|
||||
- **User-scoped AI-fallback:** AI-förslag för ingrediens- och kategorimatchning aktiveras nu per användare (premium). Endast användare med premium-tillgång får AI-hints vid import.
|
||||
- **Admin-toggles:** Admin kan slå på/av AI-funktioner per användare via backend och UI.
|
||||
- **Premium-scope:** Flutter och backend respekterar premium-flagga och AI-tillgång i alla flöden.
|
||||
- **Rematch och manuell produkt:** Flutter har stöd för ommatchning och manuell produkt vid import.
|
||||
- **Arkitektur:** Fallback-first AI, strikt separation av analys/import/matchning, user-scoped produktdata.
|
||||
|
||||
Se [TEKNISK_BESKRIVNING.md](TEKNISK_BESKRIVNING.md) för teknisk genomgång och [NEXT_STEPS.md](NEXT_STEPS.md) för roadmap.
|
||||
|
||||
# Recipe App
|
||||
|
||||
En fullstack-applikation för hantering av hemmavaror och recept. Håll koll på vad du har hemma, spara recept och se direkt om du har allt du behöver för att laga en rätt.
|
||||
|
||||
> För teknisk detaljinformation, se [TEKNISK_BESKRIVNING.md](TEKNISK_BESKRIVNING.md).
|
||||
> För förslag på nästa steg i projektet, se [NEXT_STEPS.md](NEXT_STEPS.md).
|
||||
> För planerade AI-funktioner, se [_archive/microservice-ai/AI-FUNKTIONER.md](_archive/microservice-ai/AI-FUNKTIONER.md).
|
||||
|
||||
## Dokumentkarta
|
||||
|
||||
- [README.md](README.md): användaröversikt och funktioner.
|
||||
- [TEKNISK_BESKRIVNING.md](TEKNISK_BESKRIVNING.md): teknisk referens för drift och utveckling.
|
||||
- [NEXT_STEPS.md](NEXT_STEPS.md): gemensam roadmap och prioriteringar.
|
||||
- [produktlansering.md](_archive/docs/produktlansering.md): releasechecklista i arkiv.
|
||||
- Migrerings- och driftinstruktioner finns nu i [TEKNISK_BESKRIVNING.md](TEKNISK_BESKRIVNING.md). Tidigare migreringsdokument finns i [_archive/docs/migrering-MSI.md](_archive/docs/migrering-MSI.md).
|
||||
- [flutter/README.md](_archive/docs/flutter/README.md): Flutter ur användarperspektiv i arkiv.
|
||||
- [flutter/teknisk_beskrivning_flutter.md](_archive/docs/flutter/teknisk_beskrivning_flutter.md): Flutter teknisk referens i arkiv.
|
||||
- [flutter/next_steps_flutter.md](_archive/docs/flutter/next_steps_flutter.md): Flutter roadmap i arkiv.
|
||||
|
||||
## Dokumentstatus (2026-05-11)
|
||||
|
||||
# Nyheter och förbättringar (2026-05-11)
|
||||
|
||||
# Nyheter och förbättringar (2026-05-11)
|
||||
|
||||
- **Flutter web build:** Löste dart2js-kompilationsfel i Flutter-webbappen (adminpanel). Fixade runtime-beroende i meny, deklarerade saknade state-fält i formulärdialoger för inventarie och baslager.
|
||||
- **Git och deploy:** Rensade build-artifacts från versionshantering och dokumenterade rekommenderad .gitignore för Flutter build-mappar.
|
||||
- **Stabiliserad deploy:** Dokumenterat rutiner för att hantera merge-konflikter orsakade av genererade filer vid serveruppdatering.
|
||||
|
||||
- **Seed-data:** Nya kategorier under `Skafferi > Sylt, mos & marmelad`: `Marmelad`, `Sylt`, `Mos` tillagda i seed.
|
||||
- **Navigation/UI:** Admin-knappen flyttad från sidomenyn till profilmenyn ovanför logout.
|
||||
- **Deploy och seed:** Förtydligande om att seed-data körs automatiskt vid `./deploy.sh --backend` och att seed-kontroll sker i deploy-scriptet. Hur man verifierar att seed körts och att nya kategorier finns.
|
||||
- **Kodförenklingar/optimeringar:** Samtliga tre förenklingar/optimeringar från senaste commit är nu implementerade (se SESSION_2026-05-09_RECEIPT_IMPORT.md för detaljer).
|
||||
|
||||
|
||||
### Målgrupp
|
||||
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`.
|
||||
- Importerat kvitto i Flutter ligger kvar i klientens session vid navigering/refresh, så användaren kan fortsätta utan att börja om.
|
||||
- Produkter är user-scopade (personliga per användare), vilket minskar felmatchningar mellan olika användare.
|
||||
- Ingen ny serverlagring infördes för kvitto-sessionen; persistensen sker i klienten.
|
||||
|
||||
---
|
||||
|
||||
### Funktioner
|
||||
|
||||
### 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
|
||||
- **Konsumtionshistorik** — spåra vad som använts när och i vilken mängd
|
||||
- **Utförlig information** — stöd för varumärke, lagringsnot, tillkomsttid och mer
|
||||
|
||||
### Baslager
|
||||
- **Ständigt lager** — markera produkter du alltid räknar med att ha hemma
|
||||
- **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
|
||||
|
||||
Dessa två funktioner fyller olika syften och kompletterar varandra:
|
||||
|
||||
#### Inventarie — ”vad du faktiskt har hemma”
|
||||
Inventariet är en **aktiv förrådsbok** över varor du just nu har hemma. Här registrerar du:
|
||||
- Exakt mängd (t.ex. 500 g pasta, 1,5 liter mjolk)
|
||||
- Var varan förvaras (kyl, frys, skafferi)
|
||||
- Bäst före-datum
|
||||
- Om förpackningen är öppnad
|
||||
|
||||
#### Praktiskt flöde
|
||||
| Du vill se vad du behöver köpa | **Matplanen** — inköpslistan jämför mot båda |
|
||||
| Du tog slut på mjolk | Ta bort från inventariet (baslagret påverkas inte) |
|
||||
- **Portionsjustering** — ange antal portioner vid skapandet; matplanen räknar automatiskt om ingrediensmängder om du lagar fler eller färre portioner
|
||||
- **Receptjämförelse mot inventorie** — se direkt vilka ingredienser du har hemma, vad som saknas och om enheter är inkompatibla
|
||||
- **Importera recept från Markdown** — klistra in ett recept i enkelt format, låt systemet matcha ingredienser, granska och spara med ett klick
|
||||
- **Importera recept från PDF, bild eller länk** — stöd för PDF-textutvinning, OCR av bilder och webbimport via snabbimport
|
||||
- **Intelligenta matchningar** — Levenshtein-baserad likhetsbedömning hittar rätt produkt även vid osäker stavning
|
||||
- **Enhetskonvertering** — automatisk konvertering mellan viktenheter (g/kg), volymenheter (ml/dl) och portionsenheter (tsk/msk)
|
||||
|
||||
- **Inköpslista** — genereras automatiskt utifrån veckans planerade recept; ingrediensmängder skalas proportionellt om portioner justerats
|
||||
- **Inventariejämförelse** — jämför inköpslistans ingredienser mot vad du faktiskt har hemma (aggregerat per vecka)
|
||||
> Obs: Destruktiva åtgärder (merge, ta bort, återställ, bulk-uppdatera, återställ all data) kräver admin-roll.
|
||||
**Admin: Produkter (fliken Databas i /profil)**
|
||||
|
||||
Produktadmin är nu uppdelad i tre undertabbar:
|
||||
- **🗑️ Papperskorg** — visa mjukraderade produkter, återställ eller radera permanent
|
||||
- Redigera produkter — uppdatera namn, canonical name, kategori (hierarkisk dropdown) och varumärke inline
|
||||
- Bulk-kategorisering — filtrera fram okategoriserade produkter, markera flera och sätt kategori på alla markerade
|
||||
- AI-kategorisering per produkt och bulk — "✨ Fråga AI" för kategori
|
||||
- Hitta dubbletter och slå ihop produkter (merge)
|
||||
- Förhandsvisning av merge
|
||||
- Ta bort (mjukradera) och återställ produkter
|
||||
- **Produktförslags-kö** — produkter med status `pending` samlas på sidan `/admin/products/pending` (länk "⏳ Förslag" i navigeringen)
|
||||
- **Godkänn eller avvisa** — admin kan godkänna (status → `active`) eller avvisa (status → `rejected`) varje förslag med ett klick
|
||||
|
||||
- **Min profil** — redigera förnamn, efternamn och e-postadress
|
||||
- **Databas** — hantera inventarie och baslager (se nedan)
|
||||
|
||||
**Enbart admin:**
|
||||
- **Användare** — fullständig användarhantering:
|
||||
- Skapa ny användare (användarnamn, e-post, lösenord, roll)
|
||||
- Ändra roll via dropdown direkt i tabellen
|
||||
- Ändra **plan** (Free / Paid ✨) via dropdown — styr tillgång till premium-AI-funktioner
|
||||
- Ändra e-postadress inline
|
||||
- Återställ lösenord — genererar ett tillfälligt lösenord och visar ett kopierings-redo meddelande
|
||||
- Ta bort användare (skyddad: kan inte ta bort sig själv)
|
||||
- **Databas** — produktdatabasen: redigera, merga, bulk-kategorisera och återställa produkter
|
||||
|
||||
### Autentisering och roller
|
||||
- **Rollbaserad åtkomstkontroll** — systemet har två roller: `user` (standard) och `admin`
|
||||
- **Premium-plan** — `isPremium`-flagga på användaren styr tillgång till AI-funktioner (kvittoimport AI-hints m.fl.); administreras via Plan-kolumnen i användarhanteringen
|
||||
- **Automatisk bootstrap** — fyra användare skapas eller uppdateras automatiskt när backend startar, baserat på miljövariabler:
|
||||
- `Nadmin` (admin), `Padmin` (admin), `user1` (user), `user2` (user)
|
||||
- **Skyddade admin-endpoints** — destruktiva produkt-endpoints och all användarhantering kräver `admin`-roll; försök utan rätt roll ger 403 Förbjuden
|
||||
- **Navigering** — admin-länkarna "⚙️ Admin", "⏳ Förslag" och "👥 Användare" visas enbart för inloggade administratörer
|
||||
|
||||
---
|
||||
|
||||
## Kom igång
|
||||
|
||||
### Förutsättningar
|
||||
|
||||
- Docker och Docker Compose
|
||||
- En extern `proxy`-nätverk i Docker för Caddy (rekommenderat) eller localhost-konfiguration
|
||||
|
||||
### Starta applikationen
|
||||
|
||||
```bash
|
||||
# Bygg alla images (första gånger)
|
||||
docker compose build
|
||||
|
||||
# Starta alla tjänster i bakgrunden
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Frontend är tillgänglig på `http://localhost:3000` (eller via Caddy proxy)
|
||||
Backend API är tillgänglig på `http://localhost:8080` (eller via Caddy proxy)
|
||||
|
||||
> Stacken använder lokala Docker-images, hälsokontroller och startordning mellan databasen, API:t och frontend för stabilare uppstarter och Portainer-deployer.
|
||||
|
||||
### Drift-snabbguide
|
||||
|
||||
Använd dessa kommandon konsekvent beroende på vilken del av systemet som ska vara uppe.
|
||||
|
||||
**Huvudappen (recept.gynther.se):**
|
||||
```bash
|
||||
docker compose build recipe-frontend recipe-api
|
||||
docker compose up -d recipe-db recipe-api recipe-frontend
|
||||
```
|
||||
|
||||
**Endast backend:**
|
||||
```bash
|
||||
docker compose build recipe-api
|
||||
docker compose up -d recipe-db recipe-api
|
||||
```
|
||||
|
||||
**Flutter-spåret (test.gynther.se):**
|
||||
```bash
|
||||
docker compose -f compose.yml -f compose.flutter.yml build recipe-flutter
|
||||
docker compose -f compose.yml -f compose.flutter.yml up -d --no-deps recipe-flutter
|
||||
```
|
||||
|
||||
**Viktigt:** `docker compose build ...` bygger bara image. Tjänsten startar först efter `docker compose up -d ...`.
|
||||
|
||||
**Om orphan-varningen:**
|
||||
- Varning om orphan-containers är väntad när huvudappen körs med bara `compose.yml` men Flutter tidigare startats med `compose.flutter.yml`.
|
||||
- Det är normalt ofarligt.
|
||||
- Kör inte `docker compose down --remove-orphans` om du inte avser att även stoppa Flutter-spåret.
|
||||
|
||||
### Bygg bara backend eller frontend om behövligt
|
||||
|
||||
```bash
|
||||
# Bygg enbart backend (t.ex. efter kodändringar)
|
||||
docker compose build recipe-api
|
||||
|
||||
# Starta bara backend (övriga tjänster fortsätter)
|
||||
docker compose up -d recipe-api
|
||||
|
||||
# Liknande för frontend
|
||||
docker compose build recipe-frontend
|
||||
docker compose up -d recipe-frontend
|
||||
```
|
||||
|
||||
### Kontrollera hälsa
|
||||
|
||||
```bash
|
||||
# Hälsokontroll via HTTP (backend måste köra)
|
||||
curl http://localhost:8080/api/health
|
||||
|
||||
# Databasspecifik hälsokontroll
|
||||
curl http://localhost:8080/api/health/db
|
||||
```
|
||||
|
||||
### Databas (one-liners via .env)
|
||||
|
||||
Anvand dessa kommandon vid drift/felsokning for att alltid lasa MariaDB-credentials direkt fran `.env`.
|
||||
|
||||
```bash
|
||||
# Visa senaste Prisma-migreringar
|
||||
docker exec -i recipe-db mariadb -uroot -p"$(grep -E '^[[:space:]]*MARIADB_ROOT_PASSWORD[[:space:]]*=' .env | tail -n1 | sed -E 's/^[^=]*=[[:space:]]*//; s/[[:space:]]+$//; s/^["'\''']|["'\''']$//g' | tr -d '\r')" "$(grep -E '^[[:space:]]*MARIADB_DATABASE[[:space:]]*=' .env | tail -n1 | sed -E 's/^[^=]*=[[:space:]]*//; s/[[:space:]]+$//; s/^["'\''']|["'\''']$//g' | tr -d '\r')" -e "SELECT migration_name, finished_at FROM _prisma_migrations ORDER BY finished_at DESC LIMIT 10;"
|
||||
|
||||
# Kontrollera att HelpText-tabellen finns
|
||||
docker exec -i recipe-db mariadb -uroot -p"$(grep -E '^[[:space:]]*MARIADB_ROOT_PASSWORD[[:space:]]*=' .env | tail -n1 | sed -E 's/^[^=]*=[[:space:]]*//; s/[[:space:]]+$//; s/^["'\''']|["'\''']$//g' | tr -d '\r')" "$(grep -E '^[[:space:]]*MARIADB_DATABASE[[:space:]]*=' .env | tail -n1 | sed -E 's/^[^=]*=[[:space:]]*//; s/[[:space:]]+$//; s/^["'\''']|["'\''']$//g' | tr -d '\r')" -e "SHOW TABLES LIKE 'HelpText';"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Lägga till recept
|
||||
|
||||
### Snabbimport
|
||||
|
||||
På sidan "Lägg till nytt recept" finns ett **snabbimportfält** längst upp:
|
||||
|
||||
```
|
||||
Snabbimport: Klistra in länk eller fil
|
||||
[https://www.ica.se/recept/...] [→]
|
||||
```
|
||||
|
||||
Klistra in:
|
||||
- **ICA-receptlänk** — systemet skrapar automatiskt receptet och importerar det
|
||||
- **Andra receptlänkar** — fallback till generisk HTML/JSON-LD-parser
|
||||
- En lyckad import omdirigeras till "Skriv in recept" med förifylld Markdown
|
||||
|
||||
**Stödda källor:**
|
||||
- ICA.se — Recept skrapas automatiskt
|
||||
- Andra webbplatser — Generic HTML-parser (JSON-LD först, sedan HTML-fallback)
|
||||
- PDF-filer — textutvinning från uppladdad PDF
|
||||
- Bildfiler — OCR via Tesseract (`swe+eng`) för PNG, JPG, JPEG, WEBP och BMP
|
||||
|
||||
**Felmeddelandena vägleder dig:**
|
||||
- "Länken är inte från ICA.se" — Försöker Generic parser istället
|
||||
|
||||
> **Notering:** Snabbimport-logiken är också tillgänglig som en **[standalone microservice](../microservice-importer/README.md)** för integrations- eller API-använding.
|
||||
|
||||
---
|
||||
|
||||
## Arkitektur: Recipe App + Microservice Importer
|
||||
|
||||
Recipe App är uppbyggd i två komponenter:
|
||||
|
||||
### Recipe App (detta repo)
|
||||
**Fullstack-applikation:** Frontend (Next.js), Backend (NestJS), Databas (MariaDB)
|
||||
|
||||
Innehåller:
|
||||
- Inventorie-hantering (CRUD, konsumtion, history)
|
||||
- Recept-hantering (CRUD, matchning mot inventorie)
|
||||
- Produktadmin (merge, duplicates, canonical names)
|
||||
- **Quick-import** (ICA-skrapning integrerad i `/recipes/create`)
|
||||
|
||||
### Microservice Importer (separat repo)
|
||||
**Standalone-tjänst:** Frontend (Next.js), Backend (NestJS, INGEN databas)
|
||||
|
||||
Innehåller:
|
||||
- **URL-scraping:** ICA.se + generic HTML-parser
|
||||
- **Markdown-parsing:** Samma parser-logik som recipe-app
|
||||
- Eget kontrollpanel på `/import`
|
||||
|
||||
**Användningsfall:**
|
||||
- Extern API-integration (POST `http://microservice:3001/api/quick-import`)
|
||||
- Oberoende snabbimport-webb-UI
|
||||
- Muligt att scalea separat från recipe-app
|
||||
|
||||
**Repo:** [`microservice-importer`](../microservice-importer/)
|
||||
- "Kunde inte hämta recept från ICA: ..." — Länken är bruten eller receptet kunde inte parsas
|
||||
- "Du måste ange en URL eller filsökväg" — Fältet var tomt
|
||||
|
||||
### Välja mellan alternativen
|
||||
|
||||
Klicka på **Lägg till nytt recept** i receptmenyn. Du får ett val mellan:
|
||||
1. **Skriv in recept** — Skriv receptet i Markdown-format med ingredienser och instruktioner
|
||||
2. **Importera från fil** — Ladda upp PDF, bild eller ange receptlänk för automatisk tolkning
|
||||
|
||||
### Skriv in recept (Markdown)
|
||||
|
||||
Navigera till **Lägg till nytt recept → Skriv in recept**
|
||||
|
||||
**Steg 1: Skriv receptet**
|
||||
Använd detta format:
|
||||
|
||||
|
||||
```markdown
|
||||
# Köttfärssås
|
||||
|
||||
En klassisk köttfärssås med massa smak.
|
||||
|
||||
## Ingredienser
|
||||
- 500 g köttfärs
|
||||
- 1 st lök
|
||||
- 2 msk tomatpuré
|
||||
- 1 dl grädde (vispgrädde)
|
||||
- salt och peppar
|
||||
|
||||
## Tillvägagångssätt
|
||||
Hacka löken och stek den mjuk i lite olja. Tillsätt köttfärsen och bräsera tills den är genomstekt. Tillsätt tomatpuré och låt det småkoka ett par minuter innan du tillsätter grädde. Smaka av med salt och peppar.
|
||||
```
|
||||
|
||||
**Steg 2: Granska**
|
||||
Systemet:
|
||||
- Tolkar receptnamn, beskrivning och instruktioner
|
||||
- Försöker matcha varje ingrediens mot databasen (Levenshtein-likhet)
|
||||
- Visar förslag för varje ingrediens i prioriteringsordning
|
||||
|
||||
Du kan:
|
||||
- Redigera Namnet, beskrivning och instruktioner
|
||||
- Välj rätt produkt från förslagen för varje ingrediens
|
||||
- Ta bort ingredienser som inte behövs
|
||||
- Ändra kvantiteter och enheter
|
||||
|
||||
**Steg 3: Spara**
|
||||
Klicka "Spara recept" — receptet sparas med dina valida ingredienser
|
||||
|
||||
### Importera från fil eller länk
|
||||
|
||||
Navigera till **Lägg till nytt recept → Importera från fil**
|
||||
|
||||
I denna sektion kan du:
|
||||
- Ladda upp PDF-filer med inbyggd text
|
||||
- Ladda upp bilder (`png`, `jpg`, `jpeg`, `webp`, `bmp`) som tolkas med OCR
|
||||
- Ange URL till en receptsida eller blogg
|
||||
- Låta systemet omvandla resultatet till Markdown och öppna det i redigeringsläget
|
||||
|
||||
> **Notering:** Importen använder PDF-textutvinning och Tesseract OCR för att ge en första receptversion som sedan kan granskas och sparas.
|
||||
|
||||
### Receptformat — regler
|
||||
|
||||
| Sektion | Beskrivning |
|
||||
|---------|------------|
|
||||
| **H1 (# titel)** | Receptnamn |
|
||||
| **Text efter H1, före ## Ingredienser** | Receptbeskrivning (valfritt) |
|
||||
| **## Ingredienser** | Rubrik för ingredienslistan |
|
||||
| **Ingrediensrader** | Mönster: `- ANTAL ENHET NAMN` eller `- ANTAL NAMN` (standard: st) |
|
||||
| **Parentes i ingrediens** | Text i `(parentes)` sparas som ingrediensnot, t.ex. `(vispgrädde)`, `(eller crème fraiche)` |
|
||||
| **## Tillvägagångssätt** (eller `## Instruktioner`) | Rubrik för tillagningsinstruktioner |
|
||||
| **Text under instruktioner** | Instruktionstexten (kan fortsätta över flera rader) |
|
||||
|
||||
### Matchningsalgoritm
|
||||
|
||||
Systemet använder tre metoder för att hitta rätt produkt:
|
||||
|
||||
1. **Exakt match** (100 poäng)
|
||||
- Ingrediensnamn matchar exakt efter normalisering (lowercase, utan skiljetecken)
|
||||
|
||||
2. **Delsträng-match** (70 poäng)
|
||||
- Ingrediensnamn förekommer som del av produktnamnet eller vice versa
|
||||
|
||||
3. **Levenshtein-likhet** (40–100 poäng)
|
||||
- Likhetspoäng baserat på tecknenskillnad
|
||||
- Mindre än 40 poäng filtreras bort
|
||||
|
||||
Systemet visar upp till 5 bästa förslag per ingrediens.
|
||||
|
||||
---
|
||||
|
||||
## Projektstruktur
|
||||
|
||||
```
|
||||
recipe-app/
|
||||
├── frontend/ # Next.js (App Router)
|
||||
├── backend/ # NestJS REST API
|
||||
├── recipe-document-converter/ # Markdown-parserbibliotek
|
||||
├── db/init/ # SQL-initialiseringsskript
|
||||
├── compose.yml # Docker Compose
|
||||
└── backup_recipe_app.sh # Backupskript
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Backup
|
||||
|
||||
```bash
|
||||
bash backup_recipe_app.sh
|
||||
```
|
||||
|
||||
Säkerhetskopierar källkod och Docker-images till konfigurerad backupmapp.
|
||||
|
||||
## 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.
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user