generator client { provider = "prisma-client-js" binaryTargets = ["native", "linux-musl-openssl-3.0.x"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Recipe { id String @id @default(cuid()) title String description String? prepTime Int? // minutes cookTime Int? // minutes totalTime Int? // minutes servings Int? imageUrl String? sourceUrl String? // For imported recipes author String? cuisine String? category String? rating Float? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sections RecipeSection[] ingredients Ingredient[] instructions Instruction[] images RecipeImage[] tags RecipeTag[] @@index([title]) @@index([cuisine]) @@index([category]) } model RecipeSection { id String @id @default(cuid()) recipeId String name String // e.g., "Starter", "Dough", "Assembly" order Int timing String? // e.g., "Day 1 - 8PM", "12 hours before mixing" recipe Recipe @relation(fields: [recipeId], references: [id], onDelete: Cascade) ingredients Ingredient[] instructions Instruction[] @@index([recipeId]) } model Ingredient { id String @id @default(cuid()) recipeId String? // Optional - can be derived from section sectionId String? // Optional - if null, belongs to recipe directly name String amount String? unit String? notes String? order Int recipe Recipe? @relation(fields: [recipeId], references: [id], onDelete: Cascade) section RecipeSection? @relation(fields: [sectionId], references: [id], onDelete: Cascade) instructions IngredientInstructionMapping[] @@index([recipeId]) @@index([sectionId]) } model Instruction { id String @id @default(cuid()) recipeId String? // Optional - can be derived from section sectionId String? // Optional - if null, belongs to recipe directly step Int text String @db.Text imageUrl String? timing String? // e.g., "8:00am", "After 30 minutes", "Day 2 - Morning" recipe Recipe? @relation(fields: [recipeId], references: [id], onDelete: Cascade) section RecipeSection? @relation(fields: [sectionId], references: [id], onDelete: Cascade) ingredients IngredientInstructionMapping[] @@index([recipeId]) @@index([sectionId]) } model IngredientInstructionMapping { id String @id @default(cuid()) ingredientId String instructionId String order Int // Display order within the instruction ingredient Ingredient @relation(fields: [ingredientId], references: [id], onDelete: Cascade) instruction Instruction @relation(fields: [instructionId], references: [id], onDelete: Cascade) @@unique([ingredientId, instructionId]) @@index([instructionId]) @@index([ingredientId]) } model RecipeImage { id String @id @default(cuid()) recipeId String url String order Int recipe Recipe @relation(fields: [recipeId], references: [id], onDelete: Cascade) @@index([recipeId]) } model Tag { id String @id @default(cuid()) name String @unique recipes RecipeTag[] } model RecipeTag { recipeId String tagId String recipe Recipe @relation(fields: [recipeId], references: [id], onDelete: Cascade) tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade) @@id([recipeId, tagId]) @@index([recipeId]) @@index([tagId]) }