Files
dataroom/prisma/schema/dataroom.prisma
zeekayandHanzo Dev 8dfcb6af82 feat(db): migrate Prisma datasource postgres -> sqlite (native, file-backed)
Drops the shared sql-0 postgres dependency in favor of an embedded SQLite
file (DATABASE_URL=file:/data/<db>), WAL-replicated to SeaweedFS by the
operator persistence sidecar — same pattern as esign (Documenso).

Schema changes for the sqlite connector:
- datasource provider postgresql -> sqlite; drop directUrl/shadowDatabaseUrl
- 18 enums -> String (values preserved as string defaults)
- scalar-list fields (String[]/Int[]) -> Json @default("[]") (arrays
  round-trip through Prisma Json at runtime; next.config ignoreBuildErrors
  keeps the type-only churn out of the build)
- strip pg-native @db.* attributes (@db.Text/@db.Timestamp)
- startup: prisma migrate deploy -> prisma db push (pg migration history is
  postgres-specific; db push reconciles the sqlite schema idempotently)

CI: amd64-only (DOKS has no arm64); deploy:false — rollout is operator-managed
via the universe Service CR, never `kubectl set image`.

Verified: `prisma validate` + `prisma db push` materialize all 62 tables on a
fresh sqlite file. Source DB is empty (0 app rows), so cutover is data-safe.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-05 00:33:13 -07:00

229 lines
7.5 KiB
Plaintext

model Dataroom {
id String @id @default(cuid())
pId String @unique // This is the generated public ID for the dataroom dr_1234
name String
internalName String? // Private, internal name/alias visible only to the dataroom owner
description String?
teamId String
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
documents DataroomDocument[]
folders DataroomFolder[]
links Link[]
views View[]
viewers Viewer[]
viewerGroups ViewerGroup[]
brand DataroomBrand?
permissionGroups PermissionGroup[]
// conversation
conversationsEnabled Boolean @default(false)
conversations Conversation[]
// FAQ system
faqItems DataroomFaqItem[]
// AI agents
agentsEnabled Boolean @default(false) // Enable AI agents for this dataroom
vectorStoreId String? // OpenAI vector store ID for AI search
chats Chat[]
// upload external documents
uploadedDocuments DocumentUpload[]
// tags
tags TagItem[]
// notification settings
enableChangeNotifications Boolean @default(false)
// unified permission strategy
defaultPermissionStrategy String @default("INHERIT_FROM_PARENT")
// bulk download setting
allowBulkDownload Boolean @default(true) // Allow bulk download of entire dataroom
// display settings
showLastUpdated Boolean @default(true) // Show/hide last updated date in dataroom view
// Introduction page settings
introductionEnabled Boolean @default(false) // Toggle to show introduction on first visit
introductionContent Json? // TipTap JSON content for the introduction page
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([teamId])
}
model DataroomDocument {
id String @id @default(cuid())
dataroomId String
dataroom Dataroom @relation(fields: [dataroomId], references: [id], onDelete: Cascade)
documentId String
document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
folderId String?
folder DataroomFolder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
orderIndex Int?
hierarchicalIndex String? // Computed field like "1.2.3" for hierarchical display
conversations Conversation[]
// FAQ system
dataroomFAQs DataroomFaqItem[]
uploadedDocuments DocumentUpload[]
vectorStoreFileId String? // vector store file ID for AI search
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([dataroomId, documentId])
@@index([folderId])
@@index([dataroomId, folderId, orderIndex])
@@index([documentId])
}
model DataroomFolder {
id String @id @default(cuid())
name String
path String // the materialized path to the folder; starts always with "/"
parentId String?
icon String? // Icon identifier from predefined icon set (e.g., "folder", "briefcase", "archive")
color String? // Color from predefined palette (e.g., "gray", "red", "blue")
documents DataroomDocument[]
childFolders DataroomFolder[] @relation("SubFolders")
parentFolder DataroomFolder? @relation("SubFolders", fields: [parentId], references: [id], onDelete: SetNull)
dataroomId String
dataroom Dataroom @relation(fields: [dataroomId], references: [id], onDelete: Cascade)
orderIndex Int?
hierarchicalIndex String? // Computed field like "1.2" for hierarchical display
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([dataroomId, path])
@@index([parentId])
@@index([dataroomId, parentId, orderIndex])
}
model DataroomBrand {
id String @id @default(cuid())
logo String? // This should be a reference to where the file is stored (S3, Google Cloud Storage, etc.)
banner String? // This should be a reference to where the file is stored (S3, Google Cloud Storage, etc.)
brandColor String? // This should be a reference to the brand color
accentColor String? // This should be a reference to the accent color
applyAccentColorToDataroomView Boolean @default(false) // When true, apply accentColor to dataroom list/tree viewer background
welcomeMessage String? // This should be a reference to the welcome message
dataroomId String @unique
dataroom Dataroom @relation(fields: [dataroomId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model ViewerGroup {
id String @id @default(cuid())
name String
members ViewerGroupMembership[]
domains Json@default("[]")
links Link[]
accessControls ViewerGroupAccessControls[]
allowAll Boolean @default(false)
dataroomId String
dataroom Dataroom @relation(fields: [dataroomId], references: [id], onDelete: Cascade)
teamId String
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
views View[]
conversations Conversation[]
invitations ViewerInvitation[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([dataroomId])
@@index([teamId])
@@index([dataroomId, createdAt])
}
model ViewerGroupMembership {
id String @id @default(cuid())
viewerId String
viewer Viewer @relation(fields: [viewerId], references: [id], onDelete: Cascade)
groupId String
group ViewerGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([viewerId, groupId])
@@index([viewerId])
@@index([groupId])
}
model ViewerGroupAccessControls {
id String @id @default(cuid())
groupId String
group ViewerGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
// Access control for items (documents or dataroom items)
itemId String // This can be a document ID or a dataroom item ID
itemType String // Enum: DATAROOM_DOCUMENT, DATAROOM_FOLDER
// Granular permissions
canView Boolean @default(true)
canDownload Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([groupId, itemId])
@@index([groupId])
}
model PermissionGroup {
id String @id @default(cuid())
name String
description String?
links Link[]
accessControls PermissionGroupAccessControls[]
dataroomId String
dataroom Dataroom @relation(fields: [dataroomId], references: [id], onDelete: Cascade)
teamId String
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([dataroomId])
@@index([teamId])
}
model PermissionGroupAccessControls {
id String @id @default(cuid())
groupId String
group PermissionGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
// Access control for items (documents or dataroom items)
itemId String // This can be a document ID or a dataroom item ID
itemType String // Enum: DATAROOM_DOCUMENT, DATAROOM_FOLDER
// Granular permissions
canView Boolean @default(true)
canDownload Boolean @default(false)
canDownloadOriginal Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([groupId, itemId])
@@index([groupId])
}