generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } enum RoleEnum { OWNER MANAGER GROWER STAFF } enum RoomType { VEG FLOWER DRY CURE MOTHER CLONE FACILITY } enum TaskStatus { PENDING IN_PROGRESS COMPLETED BLOCKED } // Daily Walkthrough Enums enum WalkthroughStatus { IN_PROGRESS COMPLETED INCOMPLETE } enum TankType { VEG FLOWER } enum TankStatus { OK LOW CRITICAL } enum HealthStatus { GOOD FAIR NEEDS_ATTENTION } enum AccessStatus { OK ISSUES } model User { id String @id @default(uuid()) email String @unique passwordHash String name String? role RoleEnum @default(STAFF) // Kept for legacy/fallback, but relying on roleId usually roleId String? userRole Role? @relation(fields: [roleId], references: [id]) rate Decimal? @map("hourly_rate") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tasks Task[] timeLogs TimeLog[] walkthroughs DailyWalkthrough[] touchPoints PlantTouchPoint[] @@map("users") } model Role { id String @id @default(uuid()) name String @unique description String? permissions Json // Store permissions as JSON: { users: { read: true, write: true }, ... } isSystem Boolean @default(false) // System roles cannot be deleted users User[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("roles") } model Room { id String @id @default(uuid()) name String type RoomType sqft Float? width Float? length Float? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt batches Batch[] tasks Task[] @@map("rooms") } model Batch { id String @id @default(uuid()) name String // e.g., "B-2023-10-15-GG4" strain String startDate DateTime harvestDate DateTime? status String @default("ACTIVE") // ACTIVE, HARVESTED, COMPLETED roomId String? room Room? @relation(fields: [roomId], references: [id]) tasks Task[] touchPoints PlantTouchPoint[] ipmSchedule IPMSchedule? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("batches") } model TaskTemplate { id String @id @default(uuid()) title String description String? // Instructions/SOP roomType RoomType? estimatedMinutes Int? materials String[] // Array of material names recurrence Json? // Cron or custom pattern createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tasks Task[] @@map("task_templates") } model Task { id String @id @default(uuid()) title String description String? status TaskStatus @default(PENDING) priority String @default("MEDIUM") templateId String? template TaskTemplate? @relation(fields: [templateId], references: [id]) assignedToId String? assignedTo User? @relation(fields: [assignedToId], references: [id]) batchId String? batch Batch? @relation(fields: [batchId], references: [id]) roomId String? room Room? @relation(fields: [roomId], references: [id]) dueDate DateTime? completedAt DateTime? notes String? photos String[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("tasks") } model TimeLog { id String @id @default(uuid()) userId String user User @relation(fields: [userId], references: [id]) startTime DateTime endTime DateTime? activityType String? // e.g. "Trimming", "Feeding", "Cleaning" notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("time_logs") } // Daily Walkthrough Models model DailyWalkthrough { id String @id @default(uuid()) date DateTime @default(now()) completedBy String user User @relation(fields: [completedBy], references: [id]) startTime DateTime @default(now()) endTime DateTime? status WalkthroughStatus @default(IN_PROGRESS) reservoirChecks ReservoirCheck[] irrigationChecks IrrigationCheck[] plantHealthChecks PlantHealthCheck[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("daily_walkthroughs") } model WalkthroughSettings { id String @id @default("default") // Photo Requirements reservoirPhotos PhotoRequirement @default(OPTIONAL) irrigationPhotos PhotoRequirement @default(OPTIONAL) plantHealthPhotos PhotoRequirement @default(REQUIRED) // Enabled Sections enableReservoirs Boolean @default(true) enableIrrigation Boolean @default(true) enablePlantHealth Boolean @default(true) updatedAt DateTime @updatedAt @@map("walkthrough_settings") } enum PhotoRequirement { REQUIRED OPTIONAL WEEKLY ON_DEMAND } model ReservoirCheck { id String @id @default(uuid()) walkthroughId String walkthrough DailyWalkthrough @relation(fields: [walkthroughId], references: [id], onDelete: Cascade) tankName String tankType TankType levelPercent Int status TankStatus photoUrl String? notes String? createdAt DateTime @default(now()) @@map("reservoir_checks") } model IrrigationCheck { id String @id @default(uuid()) walkthroughId String walkthrough DailyWalkthrough @relation(fields: [walkthroughId], references: [id], onDelete: Cascade) zoneName String // "Veg Upstairs", "Veg Downstairs", "Flower Upstairs", "Flower Downstairs" drippersTotal Int drippersWorking Int drippersFailed String? // JSON array of failed dripper IDs waterFlow Boolean nutrientsMixed Boolean scheduleActive Boolean photoUrl String? // Photo of working system issues String? createdAt DateTime @default(now()) @@map("irrigation_checks") } model PlantHealthCheck { id String @id @default(uuid()) walkthroughId String walkthrough DailyWalkthrough @relation(fields: [walkthroughId], references: [id], onDelete: Cascade) zoneName String healthStatus HealthStatus pestsObserved Boolean pestType String? waterAccess AccessStatus foodAccess AccessStatus flaggedForAttention Boolean @default(false) issuePhotoUrl String? referencePhotoUrl String? // Photo of healthy system notes String? createdAt DateTime @default(now()) @@map("plant_health_checks") } // Supply/Shopping List models model SupplyItem { id String @id @default(uuid()) name String category SupplyCategory quantity Int @default(0) minThreshold Int @default(0) unit String // "each", "box", "roll", "gallon", etc. location String? // "Storage Room", "Bathroom", etc. vendor String? // "Amazon", "Local", etc. productUrl String? // Link to reorder lastOrdered DateTime? notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("supply_items") } enum SupplyCategory { FILTER // Air filters, water filters CLEANING // Cleaning supplies PPE // Gloves, masks, suits OFFICE // Paper, pens, etc. BATHROOM // Toilet paper, soap, etc. KITCHEN // Coffee, snacks, etc. MAINTENANCE // Tools, parts, etc. OTHER } // Plant Touch Points model PlantTouchPoint { id String @id @default(uuid()) type TouchType notes String? photoUrls String[] // Changed from single photoUrl to array // Measurements heightCm Float? widthCm Float? // IPM specific ipmProduct String? // e.g., "Pyganic 5.0" ipmDosage String? // e.g., "1 oz per gallon" // Issues issuesObserved Boolean @default(false) issueType String? batchId String batch Batch @relation(fields: [batchId], references: [id]) createdBy String user User @relation(fields: [createdBy], references: [id]) createdAt DateTime @default(now()) @@map("plant_touch_points") } enum TouchType { WATER FEED PRUNE TRAIN INSPECT IPM TRANSPLANT HARVEST OTHER } model IPMSchedule { id String @id @default(uuid()) batchId String @unique // One schedule per batch batch Batch @relation(fields: [batchId], references: [id]) product String // "Pyganic 5.0" intervalDays Int // 10 lastTreatment DateTime? nextTreatment DateTime? // Calculated isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("ipm_schedules") }