generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique username String @unique password String role String @default("user") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt activities Activity[] canvases Canvas[] following Follow[] @relation("follower") followers Follow[] @relation("following") groupMembers GroupMember[] profile Profile? noteLists NoteList[] } model Profile { id String @id @default(cuid()) userId String @unique displayName String bio String @default("") avatar String @default("") canvasCount Int @default(0) followerCount Int @default(0) followingCount Int @default(0) joinedAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model Canvas { id String @id name String ownerId String groupId String? isPublic Boolean @default(false) nodes Json @default("[]") edges Json @default("[]") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt group Group? @relation(fields: [groupId], references: [id]) owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) } model Group { id String @id @default(cuid()) name String description String @default("") isPublic Boolean @default(true) ownerId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt controlType String? @default("REMOTE") canvases Canvas[] members GroupMember[] Kiosk Kiosk[] } model GroupMember { id String @id @default(cuid()) userId String groupId String role String @default("member") joinedAt DateTime @default(now()) group Group @relation(fields: [groupId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([userId, groupId]) } model Activity { id String @id @default(cuid()) userId String action String targetId String targetType String timestamp DateTime @default(now()) metadata String? user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model Follow { id String @id @default(cuid()) followerId String followingId String since DateTime @default(now()) follower User @relation("follower", fields: [followerId], references: [id], onDelete: Cascade) following User @relation("following", fields: [followingId], references: [id], onDelete: Cascade) @@unique([followerId, followingId]) } model Kiosk { id String @id name String location String? groupId String status String @default("offline") lastSeen DateTime @default(now()) createdAt DateTime @default(now()) Group Group @relation(fields: [groupId], references: [id]) } model NoteList { id String @id @default(cuid()) title String category String @default("general") description String @default("") color String? icon String? ownerId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) items ListItem[] @@index([ownerId]) @@index([category]) } model ListItem { id String @id @default(cuid()) listId String title String description String @default("") isCompleted Boolean @default(false) status String @default("todo") priority String @default("normal") metadata Json? dueDate DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt list NoteList @relation(fields: [listId], references: [id], onDelete: Cascade) @@index([listId]) @@index([status]) }