8.9 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.
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.sqlmed korrektcategoryIdper rad (viaSELECTmot 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ältetrole String @default("user")lades till påUser-modellen @Roles('admin')-dekoratorn (auth/decorators/roles.decorator.ts) — använderSetMetadataför att markera endpointsRolesGuard(auth/roles.guard.ts) — registrerad globalt somAPP_GUARD; läser rollmetadata, kastar 403 om rätt roll saknas- JWT inkluderar nu
role—jwt.strategy.tsreturnerar{userId, username, role},auth.service.tssignerar medrolei payload - Bootstrap-användare (
users/admin-bootstrap.service.ts) —OnApplicationBootstrapskapar/uppdaterar Nadmin, Padmin, user1 och user2 vid varje uppstart via miljövariabler - Skyddade produkt-endpoints —
@Roles('admin')påmerge,delete,restore,reset-all,bulk-update,backfill-canonicaliproducts.controller.ts
Backend-endpoints för användarhantering (alla kräver admin-roll):
GET /api/users— lista alla användarePATCH /api/users/:id/role— ändra rollPOST /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ösenordPATCH /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/usersomdirigerar 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.
openedochsuitableForbehö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 testerbase.parser.ts(parseIngredientLine) — 12 testerrecipes.service.ts(normalizeUnit,convertUnit) — 17 tester
Kör med npm test i backend/.
Planerade funktioner
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— produktnamnproduct.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:
- Backend-endpoint —
GET /api/products/ean/:code— slår upp i Open Food Facts, returnerar normaliserat produktförslag (namn, kategori, näringsvärden) utan att spara - Frontend-import — nytt fält i produktformuläret (eller separat import-flöde): ange EAN → knapp "Hämta" → formuläret förifylls
- Alternativt: kamerabaserad skanning i mobil webbläsare via
BarcodeDetectorAPI (eller externt bibliotek somzxing-js) - Kategorimappning — Open Food Facts-kategorier är på engelska/franska; en mappningstabell eller fuzzy-matchning mot systemets kategorier behövs
- Näringsdata — om
product.nutrimentsfinns 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