// Moon Base — property management for the Moon homestead. // Tracks the food forest (plants, care logs, harvests), home maintenance, // and equipment. v0.1 ships the garden module; home + equipment come next. generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } // --------------------------------------------------------------------------- // Auth // --------------------------------------------------------------------------- enum UserRole { ADMIN // full access — add/edit/delete anything MEMBER // can log observations and care, but not delete records } model User { id String @id @default(cuid()) email String @unique username String? @unique name String passwordHash String role UserRole @default(MEMBER) active Boolean @default(true) mustChangePassword Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } // --------------------------------------------------------------------------- // Audit log — append-only, every mutation lands here // --------------------------------------------------------------------------- model AuditEvent { id String @id @default(cuid()) action String // e.g. "plant.create", "plant.log.add" entityId String? actorId String? payload Json? createdAt DateTime @default(now()) @@index([entityId]) @@index([createdAt]) } // --------------------------------------------------------------------------- // Garden — food forest plant registry // --------------------------------------------------------------------------- enum PlantCategory { CANOPY_TREE // apple, pear, cherry, walnut — the tall ones UNDERSTORY_TREE // serviceberry, elderberry, pawpaw LARGE_SHRUB // hazelnuts, currants, gooseberries SHRUB // roses, raspberries, blueberries HERB // comfrey, yarrow, mint, chives GROUNDCOVER // strawberries, clover, creeping thyme VINE // grapes, hops, kiwi ANNUAL_VEGETABLE // tomatoes, squash, beans, peppers — seasonal veg ANNUAL // legacy, treated as annual vegetable ANNUAL_FLOWER // zinnias, marigolds, nasturtiums, cosmos PERENNIAL // asparagus, rhubarb, perennial veg PERENNIAL_FLOWER // coneflower, bee balm, black-eyed susan BULB // garlic, onions, tulips, daffodils MUSHROOM // shiitake log, oyster bed, etc. OTHER } model PlantGroup { id String @id @default(cuid()) name String @unique notes String? active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt plants Plant[] @@index([active]) } model Plant { id String @id @default(cuid()) commonName String species String? // scientific name (optional) variety String? // cultivar / variety name category PlantCategory zone String? // location on the property, freeform ("Back fence guild", "Front yard") plantedAt DateTime? // when it went in the ground source String? // where it came from ("Jung's Nursery", "from seed", "division from Mom's") notes String? // general notes about this plant groupId String? // optional: belongs to a PlantGroup (e.g. "Irises") group PlantGroup? @relation(fields: [groupId], references: [id]) imageUrl String? // thumbnail fetched from Wikipedia on add/edit active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt logs PlantLog[] tasks Task[] @@index([category]) @@index([zone]) @@index([active]) @@index([groupId]) } enum PlantLogType { OBSERVATION // general note — "looking healthy", "saw first flowers" CARE // watering, mulching, pruning, fertilizing, chop-and-drop HARVEST // picked fruit, veg, herb, flower TREATMENT // pest or disease treatment TRANSPLANT // moved to a different spot DIED // plant died or was removed } // --------------------------------------------------------------------------- // Tasks / reminders // --------------------------------------------------------------------------- enum TaskCategory { GARDEN HOME EQUIPMENT OTHER } enum RecurrenceType { ONCE // one-time task, no repeat CUSTOM // every N days (intervalDays) MONTHLY // same day every month (uses nextDue day-of-month) YEARLY // same month every year (month field) } model Task { id String @id @default(cuid()) title String notes String? category TaskCategory @default(GARDEN) plantId String? plant Plant? @relation(fields: [plantId], references: [id]) recurrence RecurrenceType @default(YEARLY) intervalDays Int? // for CUSTOM: every N days month Int? // 1–12: for YEARLY, which month nextDue DateTime lastDone DateTime? active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt completions TaskCompletion[] @@index([nextDue]) @@index([plantId]) @@index([active]) } model TaskCompletion { id String @id @default(cuid()) taskId String task Task @relation(fields: [taskId], references: [id]) doneAt DateTime @default(now()) notes String? actorId String? @@index([taskId]) } model PlantLog { id String @id @default(cuid()) plantId String plant Plant @relation(fields: [plantId], references: [id]) type PlantLogType date DateTime @default(now()) notes String? quantity String? // freeform for harvests: "2 lbs", "1 gallon", "a big handful" actorId String? createdAt DateTime @default(now()) @@index([plantId]) @@index([date]) }