chore(docs): consolidate legacy documentation into new structure
Test Suite / backend-pr-quick (push) Has been skipped
Test Suite / quick-import-pr-quick (push) Has been skipped
Test Suite / backend-full (push) Successful in 2m57s
Test Suite / flutter-quality (push) Failing after 1m16s

- 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:
Nils-Johan Gynther
2026-05-25 08:14:35 +02:00
parent 2a87a18edd
commit 9e513c2f5e
9 changed files with 27 additions and 0 deletions
+459
View File
@@ -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** (40100 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.