generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } enum RoleScope { SYSTEM ROOM } enum FriendStatus { PENDING ACCEPTED DECLINED BLOCKED } enum RoomVisibility { PUBLIC FRIENDS ROLE_RESTRICTED EXPLICIT } enum MediaProvider { YOUTUBE TWITCH DIRECT UNKNOWN } model User { id String @id @default(cuid()) username String @unique passwordHash String displayName String? avatarUrl String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt roles UserRole[] ownedRooms Room[] @relation("RoomOwner") sentFriends Friendship[] @relation("FriendRequester") gotFriends Friendship[] @relation("FriendReceiver") roomMembers RoomMember[] submitted MediaSource[] } model AppSetting { key String @id value String updatedAt DateTime @updatedAt } model Role { id String @id @default(cuid()) name String @unique description String? scope RoleScope @default(SYSTEM) createdAt DateTime @default(now()) users UserRole[] permissions RolePermission[] } model Permission { id String @id @default(cuid()) key String @unique description String? roles RolePermission[] } model UserRole { userId String roleId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) role Role @relation(fields: [roleId], references: [id], onDelete: Cascade) @@id([userId, roleId]) } model RolePermission { roleId String permissionId String role Role @relation(fields: [roleId], references: [id], onDelete: Cascade) permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade) @@id([roleId, permissionId]) } model Friendship { id String @id @default(cuid()) requesterId String receiverId String status FriendStatus @default(PENDING) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt requester User @relation("FriendRequester", fields: [requesterId], references: [id], onDelete: Cascade) receiver User @relation("FriendReceiver", fields: [receiverId], references: [id], onDelete: Cascade) @@unique([requesterId, receiverId]) } model Room { id String @id @default(cuid()) slug String @unique name String ownerId String? visibility RoomVisibility @default(FRIENDS) currentState Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt owner User? @relation("RoomOwner", fields: [ownerId], references: [id], onDelete: SetNull) members RoomMember[] mediaSources MediaSource[] } model RoomMember { roomId String userId String canManage Boolean @default(false) room Room @relation(fields: [roomId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@id([roomId, userId]) } model MediaSource { id String @id @default(cuid()) roomId String submitterId String? provider MediaProvider originalUrl String playbackUrl String title String? createdAt DateTime @default(now()) room Room @relation(fields: [roomId], references: [id], onDelete: Cascade) submitter User? @relation(fields: [submitterId], references: [id], onDelete: SetNull) }