# 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). --- ## Funktioner ### Inventorie (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, mera detaljer ### Recept - **Skapa och redigera recept** — med ingredienser, kvantiteter, enheter och instruktioner (Markdown-stöd) - **Receptjämförelse mot inventorie** — se direkt vilka ingredienser du har hemma, vad som saknas och enhetskonflikt - **Importera recept från Markdown** — klistra in ett recept i enkelt format, låt systemet matcha ingredienser, granska och spara med ett klick - **Intelligenta matchningar** — Levenshtein-baserad likhetsbedömning hittar rätt produkt även på osäker stavning - **Enhetskonvertering** — automatisk konvertering mellan viktenheter (g/kg), volymenheter (ml/dl) och portionsenheter (tsk/msk) ### Admin: Produkter - **Hantera produktnamn** — uppdatera canonical name för varje produkt (användes vid receptmatchning) - **Hitta dubbletter** — identifiera produkter med samma normaliserade namn - **Slå ihop produkter** — merge två produktposter, flytta alla inventarieföremål till målprodukten (källan soft-deleteras) - **Förhandsvisning** — granska vad som kommer att hända innan merge genomförs - **Återställ produkter** — restore tidigare raderade produkter --- ## 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) ### 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/health # Databasspecifik hälsokontroll curl http://localhost:8080/health/db ``` --- ## 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 - En länk omdirigeras till "Skriv in recept" med förifylld Markdown **Stödda webbplatser:** - ICA.se — Recept skrapas automatiskt - Andra webbplatser — Generic HTML-parser (JSON-LD först, sedan HTML-fallback) - (PDF-import under utveckling) **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, länk eller annan receptkälla (under utveckling) ### 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 eller andra receptfiler - Ange URL till en receptsida eller blogg - Systemet tolkar filen/länken och föreslår ingredienser > **Notering:** Fil- och länk-import är under utveckling. För närvarande kan du använda "Skriv in recept" för att mata in receptet manuellt. ### 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.