Files
2026-04-13 13:59:26 -04:00

153 lines
3.9 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
passwordHash String
displayName String
createdAt DateTime @default(now())
devices Device[]
refreshTokens RefreshToken[]
messages Message[] @relation("MessageSender")
memberships ChatMember[]
bots Bot[]
}
model Device {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
name String?
createdAt DateTime @default(now())
lastSeenAt DateTime?
}
model RefreshToken {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
deviceId String?
tokenHash String
expiresAt DateTime
createdAt DateTime @default(now())
}
enum ChatTypeEnum {
DIRECT
GROUP
CHANNEL
}
model Chat {
id String @id @default(cuid())
type ChatTypeEnum
title String?
isBroadcast Boolean @default(false)
isPublic Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
members ChatMember[]
messages Message[]
pins PinnedMessage[]
calls CallSession[]
botMembers BotMember[]
}
model ChatMember {
chatId String
userId String
role String
lastReadSeq Int @default(0)
lastDeliveredSeq Int @default(0)
chat Chat @relation(fields: [chatId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@id([chatId, userId])
}
model Message {
id String @id @default(cuid())
chatId String
chat Chat @relation(fields: [chatId], references: [id], onDelete: Cascade)
senderId String?
sender User? @relation("MessageSender", fields: [senderId], references: [id])
kind String
body String?
replyToId String?
seq Int
createdAt DateTime @default(now())
editedAt DateTime?
deletedAt DateTime?
media MessageMedia[]
pins PinnedMessage[]
@@unique([chatId, seq])
@@index([chatId, seq])
}
model MediaObject {
id String @id @default(cuid())
userId String
mimeType String
s3Key String
sizeBytes Int?
thumbnailKey String?
finalized Boolean @default(false)
createdAt DateTime @default(now())
messageLinks MessageMedia[]
}
model MessageMedia {
messageId String
mediaId String
message Message @relation(fields: [messageId], references: [id], onDelete: Cascade)
media MediaObject @relation(fields: [mediaId], references: [id])
@@id([messageId, mediaId])
}
model PinnedMessage {
chatId String
messageId String
chat Chat @relation(fields: [chatId], references: [id], onDelete: Cascade)
message Message @relation(fields: [messageId], references: [id], onDelete: Cascade)
@@id([chatId, messageId])
}
model CallSession {
id String @id @default(cuid())
chatId String
chat Chat @relation(fields: [chatId], references: [id], onDelete: Cascade)
createdBy String
status String
createdAt DateTime @default(now())
}
model Bot {
id String @id @default(cuid())
ownerUserId String
owner User @relation(fields: [ownerUserId], references: [id], onDelete: Cascade)
displayName String
tokenHash String
webhookUrl String?
createdAt DateTime @default(now())
memberships BotMember[]
}
model BotMember {
botId String
chatId String
bot Bot @relation(fields: [botId], references: [id], onDelete: Cascade)
chat Chat @relation(fields: [chatId], references: [id], onDelete: Cascade)
@@id([botId, chatId])
}