// Prisma schema for the organizer app. // Learn more: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client" output = "../lib/generated/prisma" } datasource db { provider = "postgresql" } enum Role { ADMIN USER PENDING } model User { id String @id @default(cuid()) email String @unique passwordHash String name String? // The very first person to sign up becomes ADMIN; everyone after that // defaults to USER. PENDING exists as a role an admin can move someone // into/out of later -- nothing assigns it automatically yet. role Role @default(USER) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt categories Category[] } model Category { id String @id @default(cuid()) name String order Int userId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) groups Group[] @@index([userId, order]) } model Group { id String @id @default(cuid()) // Short display title, enforced at <=20 chars in app-level validation too. title String @db.VarChar(20) // Palette key (see lib/colors.ts) rather than a raw hex value, so the // curated palette can be retinted centrally without a data migration. color String // Position within its Category lane. order Int // Single evolving markdown document for the group. Not a separate model: // it's a 1:1, always-exists field with no independent lifecycle. noteContent String @default("") @db.Text // Set once a group is archived; archived groups are kept (not deleted) // but excluded from the Home board query. Null = active. archivedAt DateTime? categoryId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade) todos Todo[] @@index([categoryId, order]) } model Todo { id String @id @default(cuid()) title String @db.VarChar(20) details String? @db.Text completed Boolean @default(false) // Position within its Group's to-do list. order Int groupId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt group Group @relation(fields: [groupId], references: [id], onDelete: Cascade) @@index([groupId, order]) }