Files
recipe-app/NEXT_STEPS.md
T
2026-04-19 09:44:15 +02:00

9.5 KiB

Nästa steg

Förslag på vad vi kan ta tag i nästa gång vi öppnar projektet.
Se README.md för funktionsöversikt och TEKNISK_BESKRIVNING.md för teknisk detaljerinformation.
Se AI-FUNKTIONER.md för planerade AI-funktioner.


Status — senast genomgånget: 2026-04-18

Funktion Status
Inventorie (CRUD, konsumtion, historik) Klart
Recept (skapa, visa, importera, matchning) Klart
Snabbimport (URL/PDF/bild/ICA) Klart
Kvittoimport (Mistral AI, OCR, alias) Klart
Matplanering (veckovy, inköpslista) Klart
Matplan — portionsjustering per dag Klart
Matplan — inventariejämförelse (backend) Klart
Matplan — inventariejämförelse (frontend-vy) Klart (/⚠️/ integrerat i inköpslistan)
Baslager (lista, lägg till, ta bort) Klart
Admin: Produkter (edit, merge, duplicate, restore, reset) Klart
Admin: Bulk-kategorisering Klart
Receptredigering (frontend UX) Klart
Receptbilder (upload URL) Klart
Autentisering (JWT, Auth.js v5, User-modell) Klart
Användarprofil (firstName, lastName, email) Klart
Produktkategorier — hierarkisk struktur (3 nivåer) Klart
Kategori-seed (supplement, idempotent) Klart
Kategoritilldelning i admin-UI Klart
Taggning av produkter Klart
Näringsvärden på produkter Klart (schema + API)
Seed produktdata med kategoritilldelning ⚠️ Script klart, ej aktiverat i init
Användarspecifika produkter (UserProduct) ⚠️ Schema klart, UI basic
Användarroller (user / admin) Klart
Användarhantering i admin-UI Klart
Profilsida med flikar (Min profil / Användare / Databas) Klart
Teknisk skuld — oanvända InventoryItem-fält Klart (migration 20260418)
Teknisk skuld — redirect-routes städade Klart
Avancerad AI-integration (veckoplanering, kampanjdata) Planerad
EAN-skanning via Open Food Facts API Planerad

Prioriterade förbättringar

1. Seed-data (002-seed-products.sql)

Mål: Möjliggöra demo och ny server utan manuell datainmatning.

db/init/002-seed-products.sql är inaktiverad (.disabled) tills produkterna har rätt categoryId. Skript för kategorimappning finns i db/seeds/:

  • Kör db/seeds/categories_supplement.sql → lägger till saknade kategorier
  • Kör db/seeds/seed_product_categories.sql → kopplar ~190 produkter till rätt kategori
  • Verifiera att mappningarna ser rätt ut i admin-UI (filtrera på okategoriserade)
  • Generera en ny 002-seed-products.sql med korrekt categoryId per rad (via SELECT mot live-db)
  • Ta bort .disabled-suffixet och testa fresh install

2. Användarroller och full användarhantering

Klart.

Systemet har nu fullständig rollbaserad åtkomstkontroll och ett komplett användarhanteringsgränssnitt inbyggt i profilsidan.

Rollsystemet:

  • Prisma-migration (20260418100000_add_user_role) — fältet role String @default("user") lades till på User-modellen
  • @Roles('admin')-dekoratorn (auth/decorators/roles.decorator.ts) — använder SetMetadata för att markera endpoints
  • RolesGuard (auth/roles.guard.ts) — registrerad globalt som APP_GUARD; läser rollmetadata, kastar 403 om rätt roll saknas
  • JWT inkluderar nu rolejwt.strategy.ts returnerar {userId, username, role}, auth.service.ts signerar med role i payload
  • Bootstrap-användare (users/admin-bootstrap.service.ts) — OnApplicationBootstrap skapar/uppdaterar Nadmin, Padmin, user1 och user2 vid varje uppstart via miljövariabler
  • Skyddade produkt-endpoints@Roles('admin')merge, delete, restore, reset-all, bulk-update, backfill-canonical i products.controller.ts

Backend-endpoints för användarhantering (alla kräver admin-roll):

  • GET /api/users — lista alla användare
  • PATCH /api/users/:id/role — ändra roll
  • POST /api/users — skapa ny användare (validering: unikt användarnamn och e-post)
  • DELETE /api/users/:id — ta bort användare (skyddad: kan inte ta bort sig själv)
  • POST /api/users/:id/reset-password — genererar tillfälligt lösenord, returnerar meddelandetext + lösenord
  • PATCH /api/users/:id/email — uppdatera e-postadress

Profilsidan med flikar (/profil):

  • ?tab=profil — Min profil (alla användare)
  • ?tab=anvandare — Användare (enbart admin): skapa, ta bort, rollbyte, e-postbyte, lösenordsåterställning med kopierings-modal
  • ?tab=databas — Databas (enbart admin): produktadmin (samma innehåll som /admin/products)
  • /admin/users omdirigerar till /profil?tab=anvandare
  • Navigeringslänken "👥 Användare" går direkt till /profil?tab=anvandare

3. Matplan-vy (frontend-polish)

Klart.

Inköpslistan och inventariejämförelsen är sammanslagna till en enhetlig vy med tre statusnivåer:

  • Saknas helt — visar hur mycket som behövs köpas
  • ⚠️ Delvis hemma — visar hur mycket mer som behövs + vad som finns
  • Finns hemma — markeras nedtonat, ingen köpindikering

Listan sorteras automatiskt: saknade ingredienser överst, hemma-ingredienser underst. En sammanfattningsrad visar totalt antal per statuskategori.

4. Teknisk skuld (underhåll)

Mål: Minska komplexitet och risk för buggar.

A. CanonicalNameForm och NameForm

Filerna var redan borttagna — inga aktiva imports hittades. Inget att göra.

B. Oanvända fält på InventoryItem

Följande 6 fält togs bort via Prisma-migration (20260418000000_remove_unused_inventory_fields): priority, shelfNote, isOnSale, priceLevel, proteinType, isLeftover

  • Schema, DTOs (create + update), service och frontend-typen är städade.
  • opened och suitableFor behölls — de används i UI.

C. Validering av DTO:er i admin-actions

Redan implementerat — trim() + max 100 tecken på alla fält i actions.ts. Inget att göra.

D. Routing-städning för kvitto och import

frontend/app/kvitto/page.tsx och frontend/app/recipes/import/page.tsx är borttagna. /import täcker båda use-cases via flikar.

E. Seed-data i versionshantering

data/matvaror_sverige.csv och data/seed_products.sql behålls i git för reproducerbarhet. Inga ändringar i .gitignore.

5. Avancerad AI-integration

Mål: Smarta receptförslag och veckoplanering baserat på inventarie och kampanjdata.

Nuvarande AI-funktionalitet (Mistral för kvittotolkning) är ett bra fundament. Nästa steg:

  • Receptförslag utifrån vad som finns hemma ("Vad ska jag laga idag?")
  • Veckoplanering med hänsyn till kampanjpriser (kräver extern datakälla)
  • Kräver: tydlig API-design, kostnadskontroll och eventuellt modellval per use-case

Enhetstester

Jest + ts-jest är uppsatt. Tester finns för:

  • normalize-name.ts — 10 tester
  • base.parser.ts (parseIngredientLine) — 12 tester
  • recipes.service.ts (normalizeUnit, convertUnit) — 17 tester

Kör med npm test i backend/.


Planerade funktioner

Säkerhet — kryptering av känslig användardata

Mål: Kryptera känsliga fält (t.ex. e-postadresser, personuppgifter) i databasen med en hybridlösning.

Förslag på approach:

  • AES-256-GCM för symmetrisk kryptering av data i vila (kolumnnivå i MariaDB eller på applikationsnivå i Prisma middleware)
  • Nyckelhantering via miljövariabel eller extern nyckelhanteringstjänst (t.ex. HashiCorp Vault)
  • Kräver genomtänkt migrering av befintlig data och påverkar sökbarhet (krypterade fält kan inte indexeras direkt)

EAN-skanning — import via streckkod (Open Food Facts)

Mål: Låt användaren skanna eller skriva in en EAN-streckkod och få produktinformation (namn, kategori, näringsvärden) ifyllt automatiskt.

Open Food Facts är ett öppet, gratis API utan API-nyckel för grundläggande användning.

Exempelanrop (EAN 7310960010016):

GET https://world.openfoodfacts.org/api/v0/product/{ean}.json

Svaret innehåller:

  • product.product_name — produktnamn
  • product.categories — kategoristräng (kommaseparerad)
  • product.nutriments — näringsvärden (energi, protein, fett, kolhydrater, m.fl.)
  • product.code — EAN-koden bekräftad

Förslag på implementation:

  1. Backend-endpointGET /api/products/ean/:code — slår upp i Open Food Facts, returnerar normaliserat produktförslag (namn, kategori, näringsvärden) utan att spara
  2. Frontend-import — nytt fält i produktformuläret (eller separat import-flöde): ange EAN → knapp "Hämta" → formuläret förifylls
  3. Alternativt: kamerabaserad skanning i mobil webbläsare via BarcodeDetector API (eller externt bibliotek som zxing-js)
  4. Kategorimappning — Open Food Facts-kategorier är på engelska/franska; en mappningstabell eller fuzzy-matchning mot systemets kategorier behövs
  5. Näringsdata — om product.nutriments finns kan det sparas direkt i Prisma-modellens näringsvärdesfält (redan schema-klara)

Begränsningar att ha i åtanke:

  • Produkttäckning varierar — svenska dagligvaror är välrepresenterade men inte allt finns
  • Produktnamn är ofta på originalspråk; kan behöva redigeras
  • Rate limiting: för hög användning rekommenderar Open Food Facts att kontakta dem