generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") } model User { id Int @id @default(autoincrement()) username String @unique email String @unique firstName String? lastName String? passwordHash String role String @default("user") isPremium Boolean @default(false) canShareRecipes Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt userProducts UserProduct[] ownedRecipes Recipe[] @relation("RecipeOwner") sharedRecipes RecipeShare[] ownedProducts Product[] pantryItems PantryItem[] mealPlanEntries MealPlanEntry[] } model Product { id Int @id @default(autoincrement()) name String normalizedName String @unique category String? brand String? canonicalName String? isActive Boolean @default(true) status String @default("active") deletedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt inventoryItems InventoryItem[] recipeIngredients RecipeIngredient[] pantryItems PantryItem[] receiptAliases ReceiptAlias[] tags ProductTag[] nutrition Nutrition? ownerId Int owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) userProducts UserProduct[] categoryId Int? categoryRef Category? @relation(fields: [categoryId], references: [id], onDelete: SetNull) isPrivate Boolean @default(false) } model Category { id Int @id @default(autoincrement()) name String parentId Int? parent Category? @relation("CategoryTree", fields: [parentId], references: [id], onDelete: SetNull) children Category[] @relation("CategoryTree") products Product[] @@unique([name, parentId]) @@index([parentId]) } model UserProduct { id Int @id @default(autoincrement()) userId Int productId Int note String? @db.Text preferredBrand String? preferredStore String? isPrivate Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) product Product @relation(fields: [productId], references: [id], onDelete: Cascade) @@unique([userId, productId]) @@index([userId]) @@index([productId]) } model InventoryItem { id Int @id @default(autoincrement()) productId Int quantity Decimal @db.Decimal(10, 2) unit String brand String? origin String? receiptName String? location String? purchaseDate DateTime? opened Boolean? suitableFor String? bestBeforeDate DateTime? comment String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt product Product @relation(fields: [productId], references: [id], onDelete: Cascade) consumptions InventoryConsumption[] @@index([productId]) } model InventoryConsumption { id Int @id @default(autoincrement()) inventoryItem InventoryItem @relation(fields: [inventoryItemId], references: [id]) inventoryItemId Int amountUsed Decimal @db.Decimal(10, 2) comment String? createdAt DateTime @default(now()) } model Recipe { id Int @id @default(autoincrement()) name String description String? @db.Text instructions String? @db.Text imageUrl String? servings Int? isPublic Boolean @default(false) ownerId Int? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt owner User? @relation("RecipeOwner", fields: [ownerId], references: [id], onDelete: SetNull) ingredients RecipeIngredient[] mealPlanEntries MealPlanEntry[] shares RecipeShare[] } model RecipeShare { recipeId Int userId Int recipe Recipe @relation(fields: [recipeId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@id([recipeId, userId]) @@index([userId]) } model RecipeIngredient { id Int @id @default(autoincrement()) recipe Recipe @relation(fields: [recipeId], references: [id]) recipeId Int product Product @relation(fields: [productId], references: [id]) productId Int quantity Decimal @db.Decimal(10, 2) unit String note String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model PantryItem { id Int @id @default(autoincrement()) userId Int productId Int user User @relation(fields: [userId], references: [id], onDelete: Cascade) product Product @relation(fields: [productId], references: [id], onDelete: Cascade) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([userId, productId]) @@index([userId]) } model ReceiptAlias { id Int @id @default(autoincrement()) receiptName String @unique // normaliserat kvittonamn (lowercase, trim) productId Int product Product @relation(fields: [productId], references: [id], onDelete: Cascade) createdAt DateTime @default(now()) } model MealPlanEntry { id Int @id @default(autoincrement()) userId Int date DateTime @db.Date recipe Recipe @relation(fields: [recipeId], references: [id], onDelete: Cascade) recipeId Int user User @relation(fields: [userId], references: [id], onDelete: Cascade) servings Int? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Bara ett recept per dag och anvandare. @@unique([userId, date]) @@index([userId]) @@index([date]) } model Tag { id Int @id @default(autoincrement()) name String @unique products ProductTag[] } model ProductTag { productId Int tagId Int product Product @relation(fields: [productId], references: [id], onDelete: Cascade) tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade) @@id([productId, tagId]) @@index([tagId]) } model Nutrition { id Int @id @default(autoincrement()) productId Int @unique calories Float? protein Float? fat Float? carbohydrates Float? salt Float? sugar Float? fiber Float? product Product @relation(fields: [productId], references: [id], onDelete: Cascade) }