schema.prisma 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // This is your Prisma schema file,
  2. // learn more about it in the docs: https://pris.ly/d/prisma-schema
  3. generator client {
  4. provider = "prisma-client-js"
  5. }
  6. datasource db {
  7. provider = "postgresql"
  8. url = env("DATABASE_URL")
  9. }
  10. model User {
  11. id String @id @default(cuid())
  12. email String @unique
  13. name String
  14. password String
  15. avatarUrl String?
  16. globalRole GlobalRole @default(MEMBER)
  17. active Boolean @default(true)
  18. createdAt DateTime @default(now())
  19. updatedAt DateTime @updatedAt
  20. memberships ProjectMember[]
  21. comments Comment[]
  22. projects Project[] // projects where this user is the owner
  23. resolvedComments Comment[] @relation("ResolvedBy")
  24. requestedComments Comment[] @relation("RequestedBy")
  25. }
  26. model Project {
  27. id String @id @default(cuid())
  28. name String
  29. description String?
  30. ownerId String
  31. createdAt DateTime @default(now())
  32. updatedAt DateTime @updatedAt
  33. assets Asset[]
  34. members ProjectMember[]
  35. invitations Invitation[]
  36. owner User @relation(fields: [ownerId], references: [id])
  37. }
  38. model SiteSetting {
  39. id String @id @default(cuid())
  40. name String @unique
  41. value String
  42. }
  43. model ProjectMember {
  44. id String @id @default(cuid())
  45. userId String
  46. projectId String
  47. role Role @default(REVIEWER)
  48. joinedAt DateTime @default(now())
  49. invitedBy String? // userId who sent the invite
  50. user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  51. project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  52. @@unique([userId, projectId])
  53. @@index([projectId])
  54. @@index([userId])
  55. }
  56. model Asset {
  57. id String @id @default(cuid())
  58. projectId String
  59. title String
  60. filename String
  61. filePath String
  62. thumbnail String?
  63. hlsPath String?
  64. duration Float?
  65. fps Float @default(30)
  66. codec String?
  67. mimeType String
  68. status AssetStatus @default(PENDING_REVIEW)
  69. transcodeStatus TranscodeStatus @default(PENDING)
  70. transcodeProgress Int @default(0)
  71. transcodeError String?
  72. createdAt DateTime @default(now())
  73. updatedAt DateTime @updatedAt
  74. project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  75. comments Comment[]
  76. }
  77. model Comment {
  78. id String @id @default(cuid())
  79. assetId String
  80. userId String
  81. content String
  82. timestamp Float?
  83. annotations Json?
  84. resolved Boolean @default(false)
  85. resolveStatus ResolveStatus @default(UNRESOLVED)
  86. resolvedById String?
  87. resolvedByAt DateTime?
  88. requestedById String?
  89. requestedByAt DateTime?
  90. parentId String?
  91. createdAt DateTime @default(now())
  92. updatedAt DateTime @updatedAt
  93. asset Asset @relation(fields: [assetId], references: [id], onDelete: Cascade)
  94. user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  95. parent Comment? @relation("Replies", fields: [parentId], references: [id], onDelete: Cascade)
  96. replies Comment[] @relation("Replies")
  97. resolvedBy User? @relation("ResolvedBy", fields: [resolvedById], references: [id])
  98. requestedBy User? @relation("RequestedBy", fields: [requestedById], references: [id])
  99. }
  100. enum Role {
  101. ADMIN
  102. EDITOR
  103. REVIEWER
  104. VIEWER
  105. }
  106. enum GlobalRole {
  107. ADMIN // system-wide admin: manage users, all projects
  108. MEMBER // regular user: create projects, join via invite
  109. }
  110. enum InvitationStatus {
  111. PENDING
  112. ACCEPTED
  113. EXPIRED
  114. REVOKED
  115. }
  116. model Invitation {
  117. id String @id @default(cuid())
  118. email String // invitee email
  119. projectId String
  120. role Role @default(REVIEWER)
  121. token String @unique
  122. status InvitationStatus @default(PENDING)
  123. invitedBy String? // userId who sent the invite
  124. expiresAt DateTime
  125. createdAt DateTime @default(now())
  126. project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  127. @@index([projectId])
  128. @@index([email])
  129. @@index([token])
  130. }
  131. enum AssetStatus {
  132. PENDING_REVIEW
  133. CHANGES_REQUESTED
  134. APPROVED
  135. REJECTED
  136. }
  137. enum ResolveStatus {
  138. UNRESOLVED // no request made
  139. PENDING_APPROVAL // someone requested resolve, awaiting approval
  140. RESOLVED // approved and closed
  141. }
  142. enum TranscodeStatus {
  143. PENDING
  144. UPLOADING
  145. PROCESSING
  146. COMPLETED
  147. FAILED
  148. UNSUPPORTED_CODEC
  149. }