Add comprehensive documentation for Flutter frontend migration and backend review
Test Suite / test (24.15.0) (push) Has been cancelled
Test Suite / test (24.15.0) (push) Has been cancelled
- Introduced user guide for Flutter frontend in README.md, detailing user flows and recent improvements. - Created next steps roadmap for Flutter migration in next_steps_flutter.md, outlining current tasks and priorities. - Developed technical description for Flutter frontend in teknisk_beskrivning_flutter.md, covering architecture and security status. - Removed outdated migration documentation for Prisma P3009 and added recovery steps for failed migrations in migrering-MSI.md. - Established a release checklist for product launches in produktlansering.md, ensuring security and stability measures are met. - Formulated a systematic backend review and optimization plan in review_backend.md, focusing on reducing complexity and improving performance.
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
This file has been removed as all relevant information has been migrated.
|
||||
# Prisma P3009 recovery (MySQL, migrationer)
|
||||
|
||||
**Problem:**
|
||||
Prisma migrationer kan fastna i failed state (P3009) om en migration körts med fel SQL-citering (t.ex. "User" istället för `User` i MySQL) eller om deploy avbryts mitt i en migrering.
|
||||
|
||||
**Symptom:**
|
||||
```
|
||||
migrate found failed migrations in the target database, new migrations will not be applied. The `20260506144000_add_ai_engine_enabled` migration ... failed
|
||||
```
|
||||
|
||||
**Lösning/playbook:**
|
||||
1. Rätta migrationsfilen så att den använder backticks (`) för tabell- och kolumnnamn (MySQL-stil).
|
||||
2. Kör:
|
||||
```bash
|
||||
docker exec recipe-api sh -lc "cd /app && npx prisma migrate resolve --rolled-back 20260506144000_add_ai_engine_enabled --schema prisma/schema.prisma"
|
||||
docker exec recipe-api sh -lc "cd /app && npx prisma migrate deploy --schema prisma/schema.prisma"
|
||||
```
|
||||
3. Om deploy klagar på duplicate column (dvs kolumnen finns redan):
|
||||
```bash
|
||||
docker exec recipe-api sh -lc "cd /app && npx prisma migrate resolve --applied 20260506144000_add_ai_engine_enabled --schema prisma/schema.prisma"
|
||||
docker exec recipe-api sh -lc "cd /app && npx prisma migrate deploy --schema prisma/schema.prisma"
|
||||
```
|
||||
4. Verifiera status:
|
||||
```bash
|
||||
docker exec recipe-api sh -lc "cd /app && npx prisma migrate status --schema prisma/schema.prisma"
|
||||
```
|
||||
|
||||
**Lessons learned:**
|
||||
- Kontrollera alltid SQL-citering i migrationsfiler (MySQL kräver backticks, inte dubbla citattecken).
|
||||
- Vid P3009: använd `migrate resolve` för att markera migrationen som rolled-back eller applied beroende på DB-läge.
|
||||
- Kör alltid migrationskommandon i rätt container/miljö för att undvika env- och version-mismatch.
|
||||
|
||||
# Session 2026-05-06: Migreringar för user-scoped AI och premium
|
||||
|
||||
Denna session:
|
||||
- Lade till `aiEngineEnabled` på User i Prisma-schema och migrerade databasen (manuell SQL vid behov).
|
||||
- Implementerade endpoint och logik för admin att toggla AI per användare.
|
||||
- Säkerställde att alla AI-funktioner är user-scoped och premiumstyrda.
|
||||
- Lessons learned: Vid DB-connectivity-problem krävs ibland manuell migration och resolve (se driftsekvens i TEKNISK_BESKRIVNING.md).
|
||||
|
||||
Se även:
|
||||
- [TEKNISK_BESKRIVNING.md](TEKNISK_BESKRIVNING.md) för drift- och migreringsdetaljer.
|
||||
|
||||
# Migrering: Import-funktion → microservice-importer
|
||||
|
||||
## Status: ✅ GENOMFÖRD 2026-04-30
|
||||
|
||||
## Dokumentstatus (2026-05-03)
|
||||
|
||||
### Målgrupp
|
||||
Detta dokument är för systemadministratörer och utvecklare som ansvarar för integrationen mellan recipe-app och microservice-importer.
|
||||
|
||||
### Tillägg efter genomförd migrering
|
||||
- Kvittoparsningens regelbaserade tolkning har förbättrats för multipack och enheter.
|
||||
- Brödrelaterade kategoriregler och contradiction guards har utökats för högre träffsäkerhet.
|
||||
- Klientens kvittosession i Flutter är nu persistent utan att ändra backendkontrakt eller införa serverlagring av sessionen.
|
||||
- Kategoriträdet i seed-data har utökats med `Korvbröd` under `Fastfoodbröd`.
|
||||
- **PDF-fix (2026-05-03):** `pdf-parse` använder `require()` istället för ESM-import; `pdfjs-dist/legacy/build/pdf.js` är fallback vid parsningsfel — löser `DOMMatrix is not defined` i Node.js Alpine-miljö.
|
||||
- **Felkods-forwarding (2026-05-03):** `receipt-import.service.ts` returnerar nu `ServiceUnavailableException` (503) vid 503/429 från importer-api istället för `BadRequestException` (400).
|
||||
- **Reproducerbart bygge (2026-05-03):** `package-lock.json` spåras i git; Dockerfile för importer-api kör `npm ci`.
|
||||
- **AI-optimering (2026-05-03):** `looksLikeReceiptProductLine()` filtrerar PDF-rader utan siffra innan Mistral-anrop — minskar onödiga API-anrop vid kvittoimport.
|
||||
|
||||
- **Scope:** quick-import, parse-markdown, receipt-import
|
||||
- **Arkitektur:** Backend-till-backend — recipe-app NestJS-backend anropar microservice-importer internt via HTTP. Frontend ändras inte.
|
||||
- **OCR:** Implementerat i microservice-importer (tesseract.js + Alpine apk-paket)
|
||||
- **Infra:** `importer-api`-tjänst i `recipe-app/compose.yml`, port 3001 intern
|
||||
- **Driftsatt:** 2026-04-30, alla containers Healthy
|
||||
|
||||
---
|
||||
|
||||
## Fas 1 — Utöka microservice-importer ✅
|
||||
|
||||
**1. OCR-stöd och multipart i quick-import** ✅
|
||||
- `QuickImportService.importFromUpload()` tillagd — hanterar PDF (pdf-parse) och bild (tesseract.js)
|
||||
- `quick-import.controller.ts` utökat med `FileInterceptor`, `@HttpCode(200)`
|
||||
- `Dockerfile` uppdaterad: `apk add tesseract-ocr tesseract-ocr-data-swe tesseract-ocr-data-eng`
|
||||
|
||||
**2. `imageUrl` i quick-import-svaret** ✅
|
||||
- `imageUrl?: string` tillagd i `ParsedRecipe`-interfacet (`base.parser.ts`)
|
||||
- ICA-parsern extraherar nu `recipe.image` (string/array/objekt-varianter)
|
||||
- `QuickImportResult` utökad med `imageUrl?`, `imageWarning?`, source `'image'`
|
||||
- `normalizeImageUrl()` hanterar protokollrelativa URL:er (`//cdn.ica.se/...`)
|
||||
|
||||
**3. Ny `ReceiptParsingModule`** ✅
|
||||
- `backend/src/receipt-parsing/receipt-parsing.service.ts` — Mistral AI-parsning av kvitto (bild/PDF)
|
||||
- `backend/src/receipt-parsing/receipt-parsing.controller.ts` — `POST /api/receipt-import/parse`, `@HttpCode(200)`, tillåter `application/octet-stream`
|
||||
- `backend/src/receipt-parsing/receipt-parsing.module.ts`
|
||||
- Registrerad i `app.module.ts`
|
||||
|
||||
**4. Health-endpoint** ✅
|
||||
- `GET /api/health` → `{status: "ok"}` inline i `app.module.ts`
|
||||
|
||||
**5. Bugfixar i document-service** ✅
|
||||
- `document-service.module.ts`: korrigerade importvägar + klassnamn (`DocumentImportModule` → `DocumentServiceModule`)
|
||||
- `services/document-import.service.ts`: parsersökväg `./parsers/` → `../parsers/`
|
||||
- Borttagna dubbletter: `services/web-scraping.module.ts`, `services/document-service.module.ts`
|
||||
|
||||
---
|
||||
|
||||
## Fas 2 — Anpassa recipe-app backend ✅
|
||||
|
||||
**5. Refaktorera `QuickImportService`** ✅
|
||||
- All lokal parsning (ICA, pdf-parse, tesseract) borttagen
|
||||
- Delegerar URL-import: `POST importer-api:3001/api/quick-import` (JSON)
|
||||
- Delegerar filuploading: `POST importer-api:3001/api/quick-import` (FormData, `new Uint8Array(file.buffer)`)
|
||||
- `downloadAndOptimizeImage()` behålls lokalt (körs efter microservice returnerat `imageUrl`)
|
||||
- `IMPORTER_SERVICE_URL` env-variabel med fallback `http://importer-api:3001`
|
||||
|
||||
**6. Refaktorera `ReceiptImportService`** ✅
|
||||
- AI-parsning (Mistral, pdf-parse) borttagen ur recipe-app
|
||||
- Delegerar till `POST importer-api:3001/api/receipt-import/parse` (FormData)
|
||||
- `matchProducts()` och `enrichWithAiCategories()` behålls (DB-krav)
|
||||
- `RECEIPT_IMPORT_MODEL`-konstanten flyttad till `ai.controller.ts` (lokal konstant)
|
||||
|
||||
**7. Refaktorera `RecipesService.parseMarkdown()`** ✅
|
||||
- Delegerar markdown-parsning till `POST importer-api:3001/api/recipes/parse-markdown`
|
||||
- Fallback till lokal `parseRecipeMarkdown()` vid driftavbrott
|
||||
- Levenshtein-produktmatchning behålls lokalt
|
||||
|
||||
---
|
||||
|
||||
## Fas 3 — Infrastruktur ✅
|
||||
|
||||
**8. `importer-api` i `recipe-app/compose.yml`** ✅
|
||||
- Build-context: `../microservice-importer`, dockerfile `backend/Dockerfile`
|
||||
- Image: `recipe-importer-api:local`, `pull_policy: never`
|
||||
- Nätverk: `recipe-internal` (ej exponerad externt)
|
||||
- Env: `MISTRAL_API_KEY`, `PORT=3001`
|
||||
- Healthcheck: `wget -qO- http://127.0.0.1:3001/api/health`
|
||||
- `recipe-api` får `depends_on: importer-api: condition: service_healthy`
|
||||
|
||||
---
|
||||
|
||||
## Relevanta filer som ändrades
|
||||
|
||||
| Fil | Förändring |
|
||||
|---|---|
|
||||
| `microservice-importer/backend/src/web-scraping-service/parsers/base.parser.ts` | `imageUrl?` i `ParsedRecipe` |
|
||||
| `microservice-importer/backend/src/web-scraping-service/parsers/ica.parser.ts` | Extraherar `recipe.image` |
|
||||
| `microservice-importer/backend/src/web-scraping-service/services/quick-import.service.ts` | Omskriven: OCR, PDF, imageUrl, importFromUpload |
|
||||
| `microservice-importer/backend/src/web-scraping-service/controllers/quick-import.controller.ts` | FileInterceptor, HttpCode(200) |
|
||||
| `microservice-importer/backend/src/web-scraping-service/web-scraping.module.ts` | Fixade importvägar + klassnamn |
|
||||
| `microservice-importer/backend/src/document-service/document-service.module.ts` | Fixade importvägar + klassnamn |
|
||||
| `microservice-importer/backend/src/document-service/services/document-import.service.ts` | Fixad parsersökväg |
|
||||
| `microservice-importer/backend/src/receipt-parsing/` | Ny modul (service, controller, module) |
|
||||
| `microservice-importer/backend/src/app.module.ts` | ReceiptParsingModule + HealthController |
|
||||
| `microservice-importer/backend/Dockerfile` | apk add tesseract-ocr |
|
||||
| `recipe-app/backend/src/quick-import/quick-import.service.ts` | Delegerar till importer-api |
|
||||
| `recipe-app/backend/src/receipt-import/receipt-import.service.ts` | AI-del delegeras, matchning behålls |
|
||||
| `recipe-app/backend/src/recipes/recipes.service.ts` | parseMarkdown delegeras, matchning behålls |
|
||||
| `recipe-app/backend/src/ai/ai.controller.ts` | RECEIPT_IMPORT_MODEL lokal konstant |
|
||||
| `recipe-app/compose.yml` | importer-api-tjänst tillagd |
|
||||
|
||||
---
|
||||
|
||||
## Avgränsningar (oförändrade)
|
||||
|
||||
- **Frontend ändras inte** — samma proxy-routes, samma API-kontrakt
|
||||
- **Auth stannar i recipe-app backend** — microservice-importer exponeras bara internt
|
||||
- **Bildoptimering** behålls i recipe-app (`downloadAndOptimizeImage` vid `RecipesService.create()`)
|
||||
- `matchProducts()` och `enrichWithAiCategories()` stannar i recipe-app (DB-krav)
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Fas 1 — Utöka microservice-importer
|
||||
|
||||
*Steg 1–3 är oberoende och kan utföras parallellt.*
|
||||
|
||||
**1. Lägg till OCR-stöd (tesseract.js)**
|
||||
Ny `ImageParser` i `backend/src/web-scraping-service/parsers/`. Controllern
|
||||
`quick-import.controller.ts` utökas att acceptera `multipart/form-data` för
|
||||
bilder vid sidan av JSON-body för URL-anrop.
|
||||
|
||||
**2. Lägg till `imageUrl` i quick-import-svaret**
|
||||
`quick-import.service.ts` returnerar idag `{ markdown, source }`. Komplettera
|
||||
med `imageUrl?` (original-URL från skrapad sida).
|
||||
|
||||
**3. Ny `ReceiptParsingModule` – stateless kvittoparsning**
|
||||
Ny modul `backend/src/receipt-parsing/` med endpoint `POST /api/receipt-import/parse`.
|
||||
- PDF → text via `pdf-parse`; bild → base64
|
||||
- Anropar Mistral AI med kvitto-prompt
|
||||
- Returnerar: `[{ rawName, quantity, unit, price, brand, origin }]`
|
||||
- Ingen databaskoppling — rent stateless
|
||||
|
||||
---
|
||||
|
||||
## Fas 2 — Anpassa recipe-app backend
|
||||
|
||||
*Beror på Fas 1. Steg 5–7 kan utföras parallellt.*
|
||||
|
||||
**4. Lägg till `HttpModule` + `IMPORTER_SERVICE_URL`**
|
||||
recipe-app backend registrerar NestJS:s `HttpModule` (axios-wrapper).
|
||||
`IMPORTER_SERVICE_URL` sätts som env-variabel (`http://importer-api:3001` i Docker).
|
||||
|
||||
**5. Refaktorera `QuickImportService`**
|
||||
Ta bort lokal ICA-parsning, pdf-parse och tesseract — anropa istället
|
||||
microservice-importer `POST /api/quick-import` (eller `POST /api/document-import`
|
||||
för PDF). `QuickImportModule` behåller sin controller och DTO (API-kontrakt oförändrat).
|
||||
|
||||
**6. Refaktorera `ReceiptImportService`**
|
||||
- AI-parsning → delegeras till `POST $IMPORTER_URL/api/receipt-import/parse`
|
||||
- Produktmatchning (Levenshtein mot `Product`, `ReceiptAlias`) — behålls i recipe-app (DB-krav)
|
||||
- Slår ihop och returnerar samma svar som idag till frontend
|
||||
|
||||
**7. Refaktorera `RecipesService.parseMarkdown()`**
|
||||
- Anropar `POST $IMPORTER_URL/api/recipes/parse-markdown` → `{ name, ingredients[], ... }`
|
||||
- Kör befintlig Levenshtein-produktmatchning mot `Product`-tabellen i recipe-app
|
||||
- Returnerar sammansatt svar — API-kontraktet mot frontend oförändrat
|
||||
|
||||
**8. Ta bort lokala parsningsberoenden**
|
||||
Ta bort `pdf-parse`, `tesseract.js`, `node-fetch` etc. ur recipe-app backend
|
||||
`package.json` när steg 5–7 är verifierade.
|
||||
|
||||
---
|
||||
|
||||
## Fas 3 — Infrastruktur
|
||||
|
||||
*Kan påbörjas parallellt med Fas 1.*
|
||||
|
||||
**9. Länka microservice-importer i recipe-app:s Docker Compose**
|
||||
Lägg till `importer-api`-tjänst i `recipe-app/compose.yml` (byggs från
|
||||
`../microservice-importer/backend`). Delar `recipe-network` med recipe-app
|
||||
backend. Sätt `IMPORTER_SERVICE_URL=http://importer-api:3001` i recipe-app
|
||||
backend-tjänstens env.
|
||||
|
||||
---
|
||||
|
||||
## Relevanta filer
|
||||
|
||||
| Fil | Förändring |
|
||||
|---|---|
|
||||
| `microservice-importer/backend/src/web-scraping-service/` | Ny ImageParser, imageUrl i svar |
|
||||
| `microservice-importer/backend/src/` | Ny `receipt-parsing/` modul |
|
||||
| `recipe-app/backend/src/quick-import/quick-import.service.ts` | Ersätt lokal parsning med HTTP-anrop |
|
||||
| `recipe-app/backend/src/receipt-import/receipt-import.service.ts` | AI-del delegeras, matchning behålls |
|
||||
| `recipe-app/backend/src/recipes/recipes.service.ts` | parseMarkdown delegeras, matchning behålls |
|
||||
| `recipe-app/backend/src/app.module.ts` | Registrera HttpModule |
|
||||
| `recipe-app/backend/package.json` | Ta bort pdf-parse, tesseract.js |
|
||||
| `recipe-app/compose.yml` | Lägg till importer-api tjänst |
|
||||
| `recipe-app/frontend/` | **Ändras inte** |
|
||||
|
||||
---
|
||||
|
||||
## Verifiering
|
||||
|
||||
1. `POST /api/quick-import` (recipe-app backend) med ICA-URL → samma svar som idag
|
||||
2. `POST /api/quick-import` med PDF-fil → samma svar
|
||||
3. `POST /api/recipes/parse-markdown` med markdown → ingredienser med produkt-ID:n
|
||||
4. `POST /api/receipt-import` med kvittobild → matchade items med DB-produkt-ID:n
|
||||
5. Autentisering fungerar (hanteras av recipe-app backend som tidigare)
|
||||
6. `docker compose up` startar microservice-importer som intern tjänst
|
||||
|
||||
---
|
||||
|
||||
## Avgränsningar
|
||||
|
||||
- **Frontend ändras inte** — samma proxy-routes, samma API-kontrakt
|
||||
- **Auth stannar i recipe-app backend** — microservice-importer exponeras bara internt på Docker-nätverket
|
||||
- **Bildoptimering vid sparande** behålls i recipe-app (sker vid `RecipesService.create()`, inte vid import)
|
||||
- `receipt-import` splittad: AI-del → microservice, produktmatchning + DB → recipe-app backend
|
||||
|
||||
## 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.
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user