diff --git a/README.md b/README.md index b96f9ec0..3d0a95d5 100644 --- a/README.md +++ b/README.md @@ -77,13 +77,43 @@ curl http://localhost:8080/health/db --- -## Importera recept från Markdown +## Lägga till recept -### Steg 1: Gå till receptsidan -Navigera till **Recept** och välj **Lägg till nytt recept → Importera från Markdown** +### 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 +- (PDF-import under utveckling) + +**Felmeddelandena vägleder dig:** +- "Länken är inte från ICA.se" — Endast ICA stöds för närvarande +- "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: -### Steg 2: Klistra in receptet -Använd följande format: ```markdown # Köttfärssås @@ -101,20 +131,31 @@ En klassisk köttfärssås med massa smak. 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 3: Granska +**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 nombres, beskrivning och instruktioner +- 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 4: Spara -Klicka "Spara recept" — basrecepet sparas med dina valida ingredienser +**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 diff --git a/TEKNISK_BESKRIVNING.md b/TEKNISK_BESKRIVNING.md index 19394a51..94ac454b 100644 --- a/TEKNISK_BESKRIVNING.md +++ b/TEKNISK_BESKRIVNING.md @@ -52,10 +52,11 @@ Recipe App är en fullstack-applikation för hantering av hemmavaror, recept och | | `actions.ts` | Server actions för inventarie | | **Recept** | `app/recipes/page.tsx` | Lista recept | | | `RecipePreview.tsx` | Receptförhandsvisning med inventariestatus | -| **Skapa recept** | `app/recipes/create/page.tsx` | Receptkreation (manual form) | -| | `app/recipes/create/CreateRecipePage.tsx` | Komponenter för receptskapande | -| **Importera recept** | `app/recipes/import/page.tsx` | Startpunkt för Markdown-import | -| | `app/recipes/import/ImportRecipePage.tsx` | 3-stegsvyn för Markdown-import | +| **Lägg till recept** | `app/recipes/create/page.tsx` | Meny för receptskaping (val mellan två vägar) | +| **Skriv in recept** | `app/recipes/write/page.tsx` | Startpunkt för Markdown-inmatning | +| | `app/recipes/write/WriteRecipePage.tsx` | Komponenter för receptskapande (Markdown-baserat, 3-steg) | +| **Importera från fil** | `app/recipes/import/page.tsx` | Startpunkt för fil/länk-import | +| | `app/recipes/import/ImportFilePage.tsx` | Komponenter för fil-/länk-import (PDF, URL, etc) | | **Recipe detail** | `app/recipes/[id]/` | Enskilt recept (detaljer, redigering) | | **Admin: Produkter** | `app/admin/products/page.tsx` | Produktadmin-panel | | | `AdminProductList.tsx` | Lista produkter, sök, sortera | @@ -67,7 +68,7 @@ Recipe App är en fullstack-applikation för hantering av hemmavaror, recept och | Route | Metod | Syfte | |-------|-------|-------| -| `/api/parse-markdown-proxy` | POST | Proxies `POST /api/recipes/parse-markdown` (Markdown-tolkning) | +| `/api/parse-markdown-proxy` | POST | Proxies `POST /api/recipes/parse-markdown` (Markdown-tolkning för skriv-in-recept) | | `/api/inventory-history-proxy` | GET | Proxies konsumtionshistorik | | `/api/recipe-preview-proxy` | GET | Proxies receptförhandsvisning | | `/api/admin/merge-preview-proxy` | GET | Proxies produktmerge-preview | @@ -126,6 +127,10 @@ backend/src/ │ ├── update-product.dto.ts │ ├── merge-products.dto.ts │ └── update-canonical-name.dto.ts +├── quick-import/ # NYT: Snabbimport-modul +│ ├── quick-import.controller.ts # POST /api/quick-import +│ ├── quick-import.service.ts # ICA-skrapning, PDF-stöd +│ └── quick-import.module.ts # Module definition └── recipes/ ├── recipes.controller.ts # Recept endpoints ├── recipes.service.ts # Recept + Markdown-parsing @@ -205,6 +210,8 @@ GET /api/inventory/:id/consumption-history Konsumtionshistorik ### 🍽️ Recept-endpoints ``` +POST /api/quick-import SNITT: Snabbimport (ICA-skrapning) + Body: { input: string (URL eller filsökväg) } POST /api/recipes/parse-markdown Tolka Markdown-recept (matchningslogik) GET /api/recipes Lista alla recept POST /api/recipes Skapa nytt recept @@ -329,15 +336,61 @@ model RecipeIngredient { --- -## Receptimport via Markdown — Detaljerad arkitektur +## Receptimport och receptskaping — Detaljerad arkitektur -### Syfte +### Syfte och struktur -Användaren kan importera ett recept skrivet i Markdown-format istället för att fylla i formularet manuellt. Systemet: -1. Tolkar Markdown-format (namn, beskrivning, ingredienser, instruktioner) -2. Matchar varje ingrediens mot produktdatabasen (intelligenta matchningar) -3. Låter användaren granska förslag och välja rätt produkt -4. Sparar receptet med valida ingredienser +Recipe App erbjuder tre vägar för att lägga till recept: + +1. **Snabbimport** — Klistra in ICA-länk för automatisk skrapning (ny feature) +2. **Skriv in recept** (`/recipes/write`) — Markdown-baserad inmatning där användaren skriver receptet i enkelt format +3. **Importera från fil** (`/recipes/import`) — Ladda upp PDF, länk eller andra receptkällor (under utveckling) + +Alla vägar möjliggör automatisk matchning av ingredienser mot databasen. + +### Strukturöversikt + +#### Snabbimport-fältet + +**Frontend: `/recipes/create/page.tsx`** +- Ovanför de två huvudvalen visas ett gult inmatningsfält för snabbimport +- Användaren klistrar in en ICA-receptlänk eller filsökväg +- Vid submit: + 1. Frontend skickar till `/api/quick-import-proxy` + 2. Proxy proxiar till backend `POST /api/quick-import` + 3. Backend returnerar Markdown-text + 4. Frontend sparar i `sessionStorage('recipeMarkdown')` + 5. Omdirigera till `/recipes/write` med förifylld Markdown + +**Backend: `QuickImportService` (ny modul)** +- Ansvarig för ICA-skrapning, PDF-tolkning, URL-validering +- **Huvudmetod:** `importFromInput(input: string)` — Detekterar input-typ och delegerar +- **ICA-specifik:** + - Validerar URL (måste vara ICA.se) + - Fetchar HTML via `fetch()` + - Parsar HTML med regex för: receptnamn, ingredienser, instruktioner + - Konverterar till Markdown-format + - **Felhantering:** Specifika felmeddelanden per scenario +- **PDF-support:** Stubben för framtida integration (throwError: "PDF-import är under utveckling") +- **Error-strategi:** + - `400 Bad Request` — Tomt input, inte URL/fil + - `400 Bad Request` — Länken är inte från ICA.se + - `503 Service Unavailable` — Network-fel vid hämtning (HTTP-fel från ICA) + - `400 Bad Request` — HTML-parsing misslyckades (receptnamn/ingredienser inte hittade) + +**API-endpoint:** +``` +POST /api/quick-import +Input: { input: string } +Output: { markdown: string, source: 'ica' | 'pdf' | 'other' } +``` + +**Proxy-route (Next.js):** +- `/api/quick-import-proxy` — Proxies till backend +- Hanterar error-konvertering (BE HTTP → FE error message) +- Returnerar Markdown eller JSON-error + +### Markdown-format och parsningsregler ### Markdown-format och parsningsregler @@ -486,44 +539,27 @@ Top 5: Max 5 förslag per ingrediens } ``` -#### 3. Frontend: `/recipes/import` page +#### 3. Frontend: Receptskapsidor -**Komponenter:** -- `ImportRecipePage.tsx` — Main client component (3-steps state machine) -- Använder `/api/parse-markdown-proxy` för backend-anrop (Next.js proxy) +**Huvudmeny: `/recipes/create/page.tsx`** +- Presenterar två val-kort (card-baserad UI) +- "Skriv in recept" → `/recipes/write` +- "Importera från fil/länk" → `/recipes/import` -**Steg 1: Klistra in Markdown** -- `