schema.prisma 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. }
  24. model Project {
  25. id String @id @default(cuid())
  26. name String
  27. description String?
  28. ownerId String
  29. createdAt DateTime @default(now())
  30. updatedAt DateTime @updatedAt
  31. assets Asset[]
  32. members ProjectMember[]
  33. invitations Invitation[]
  34. owner User @relation(fields: [ownerId], references: [id])
  35. }
  36. model ProjectMember {
  37. id String @id @default(cuid())
  38. userId String
  39. projectId String
  40. role Role @default(REVIEWER)
  41. joinedAt DateTime @default(now())
  42. invitedBy String? // userId who sent the invite
  43. user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  44. project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  45. @@unique([userId, projectId])
  46. @@index([projectId])
  47. @@index([userId])
  48. }
  49. model Asset {
  50. id String @id @default(cuid())
  51. projectId String
  52. title String
  53. filename String
  54. filePath String
  55. thumbnail String?
  56. hlsPath String?
  57. duration Float?
  58. fps Float @default(30)
  59. mimeType String
  60. status AssetStatus @default(PENDING_REVIEW)
  61. createdAt DateTime @default(now())
  62. updatedAt DateTime @updatedAt
  63. project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  64. comments Comment[]
  65. }
  66. model Comment {
  67. id String @id @default(cuid())
  68. assetId String
  69. userId String
  70. content String
  71. timestamp Float?
  72. annotations Json?
  73. resolved Boolean @default(false)
  74. parentId String?
  75. createdAt DateTime @default(now())
  76. updatedAt DateTime @updatedAt
  77. asset Asset @relation(fields: [assetId], references: [id], onDelete: Cascade)
  78. user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  79. parent Comment? @relation("Replies", fields: [parentId], references: [id], onDelete: Cascade)
  80. replies Comment[] @relation("Replies")
  81. }
  82. enum Role {
  83. ADMIN
  84. EDITOR
  85. REVIEWER
  86. VIEWER
  87. }
  88. enum GlobalRole {
  89. ADMIN // system-wide admin: manage users, all projects
  90. MEMBER // regular user: create projects, join via invite
  91. }
  92. enum InvitationStatus {
  93. PENDING
  94. ACCEPTED
  95. EXPIRED
  96. REVOKED
  97. }
  98. model Invitation {
  99. id String @id @default(cuid())
  100. email String // invitee email
  101. projectId String
  102. role Role @default(REVIEWER)
  103. token String @unique
  104. status InvitationStatus @default(PENDING)
  105. invitedBy String? // userId who sent the invite
  106. expiresAt DateTime
  107. createdAt DateTime @default(now())
  108. project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  109. @@index([projectId])
  110. @@index([email])
  111. @@index([token])
  112. }
  113. enum AssetStatus {
  114. PENDING_REVIEW
  115. CHANGES_REQUESTED
  116. APPROVED
  117. REJECTED
  118. }