mirror of
https://github.com/hanzo-apps/dataroom.git
synced 2026-10-30 14:47:36 +00:00
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]>
207 lines
6.8 KiB
Plaintext
207 lines
6.8 KiB
Plaintext
model Conversation {
|
|
id String @id @default(cuid())
|
|
title String? // Optional title for the conversation
|
|
isEnabled Boolean @default(true)
|
|
|
|
// Visibility control
|
|
visibilityMode String @default("PRIVATE")
|
|
|
|
// Core relationships
|
|
dataroomId String
|
|
dataroom Dataroom @relation(fields: [dataroomId], references: [id], onDelete: Cascade)
|
|
|
|
// Optional attachments
|
|
dataroomDocumentId String?
|
|
dataroomDocument DataroomDocument? @relation(fields: [dataroomDocumentId], references: [id], onDelete: SetNull)
|
|
documentVersionNumber Int? // Optional document version number reference
|
|
documentPageNumber Int? // Optional document page number reference
|
|
|
|
// Optional link relationship
|
|
linkId String?
|
|
link Link? @relation(fields: [linkId], references: [id], onDelete: SetNull)
|
|
|
|
// Optional viewer group relationship
|
|
viewerGroupId String?
|
|
viewerGroup ViewerGroup? @relation(fields: [viewerGroupId], references: [id], onDelete: SetNull)
|
|
|
|
// Original view that initiated the conversation (for reference)
|
|
initialViewId String?
|
|
initialView View? @relation(name: "initialView", fields: [initialViewId], references: [id], onDelete: SetNull)
|
|
|
|
teamId String
|
|
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
|
|
|
// Track all views that accessed this conversation
|
|
views ConversationView[]
|
|
|
|
// Track participants including the owner
|
|
participants ConversationParticipant[]
|
|
|
|
// Track conversations
|
|
messages Message[]
|
|
lastMessageAt DateTime? // Last message timestamp
|
|
|
|
// Published FAQs created from this conversation
|
|
faqItems DataroomFaqItem[]
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([dataroomId])
|
|
@@index([dataroomDocumentId])
|
|
@@index([linkId])
|
|
@@index([teamId])
|
|
@@index([viewerGroupId])
|
|
@@index([initialViewId])
|
|
}
|
|
|
|
// Define conversation visibility options
|
|
|
|
// Define participant roles
|
|
|
|
// Track participants in a conversation (including the owner)
|
|
model ConversationParticipant {
|
|
id String @id @default(cuid())
|
|
conversationId String
|
|
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
|
|
|
// Role in the conversation
|
|
role String @default("PARTICIPANT")
|
|
|
|
// Participant can be either a viewer or a user
|
|
viewerId String?
|
|
viewer Viewer? @relation(fields: [viewerId], references: [id], onDelete: SetNull)
|
|
userId String?
|
|
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
|
|
|
// Notification preferences
|
|
receiveNotifications Boolean @default(false)
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([conversationId, viewerId])
|
|
@@unique([conversationId, userId])
|
|
@@index([conversationId])
|
|
@@index([viewerId])
|
|
@@index([userId])
|
|
}
|
|
|
|
model Message {
|
|
id String @id @default(cuid())
|
|
content String // The actual message content
|
|
|
|
// Conversation relationship
|
|
conversationId String
|
|
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
|
|
|
// Sender information
|
|
userId String? // Optional - for team members
|
|
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
|
|
|
viewerId String? // Optional - for viewers
|
|
viewer Viewer? @relation(fields: [viewerId], references: [id], onDelete: SetNull)
|
|
|
|
// The specific view when this message was sent (for tracking)
|
|
viewId String?
|
|
view View? @relation(fields: [viewId], references: [id], onDelete: SetNull)
|
|
|
|
// Tracking
|
|
isRead Boolean @default(false)
|
|
|
|
// FAQ relationships (reverse relations)
|
|
faqAsQuestion DataroomFaqItem[] @relation("FAQQuestionMessage")
|
|
faqAsAnswer DataroomFaqItem[] @relation("FAQAnswerMessage")
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([conversationId])
|
|
@@index([userId])
|
|
@@index([viewerId])
|
|
@@index([viewId])
|
|
}
|
|
|
|
// Join table to track all views that accessed a conversation
|
|
model ConversationView {
|
|
id String @id @default(cuid())
|
|
conversationId String
|
|
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
|
viewId String
|
|
view View @relation(fields: [viewId], references: [id], onDelete: Cascade)
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([conversationId, viewId])
|
|
@@index([conversationId])
|
|
@@index([viewId])
|
|
}
|
|
|
|
// Published FAQ items for datarooms
|
|
model DataroomFaqItem {
|
|
id String @id @default(cuid())
|
|
title String? // Optional title for the FAQ
|
|
editedQuestion String // Admin-edited version of the question
|
|
originalQuestion String? // Original question from visitor (for reference)
|
|
answer String // The answer content
|
|
description String? // Optional context or description
|
|
|
|
// Relationships
|
|
dataroomId String
|
|
dataroom Dataroom @relation(fields: [dataroomId], references: [id], onDelete: Cascade)
|
|
|
|
linkId String? // Optional: specific link visibility
|
|
link Link? @relation(fields: [linkId], references: [id], onDelete: SetNull)
|
|
|
|
dataroomDocumentId String? // Optional: document-specific FAQ
|
|
dataroomDocument DataroomDocument? @relation(fields: [dataroomDocumentId], references: [id], onDelete: SetNull)
|
|
|
|
// Source conversation and messages (for reference and editing)
|
|
sourceConversationId String? // Original conversation
|
|
sourceConversation Conversation? @relation(fields: [sourceConversationId], references: [id], onDelete: SetNull)
|
|
|
|
questionMessageId String? // Reference to original question message
|
|
questionMessage Message? @relation(name: "FAQQuestionMessage", fields: [questionMessageId], references: [id], onDelete: SetNull)
|
|
|
|
answerMessageId String? // Reference to answer message
|
|
answerMessage Message? @relation(name: "FAQAnswerMessage", fields: [answerMessageId], references: [id], onDelete: SetNull)
|
|
|
|
// Publishing details
|
|
teamId String
|
|
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
|
|
|
publishedByUserId String
|
|
publishedByUser User @relation(fields: [publishedByUserId], references: [id], onDelete: Cascade)
|
|
|
|
// Visibility and status
|
|
visibilityMode String @default("PUBLIC_DATAROOM")
|
|
status String @default("PUBLISHED")
|
|
isAnonymized Boolean @default(true)
|
|
|
|
// Analytics
|
|
viewCount Int @default(0)
|
|
|
|
// Optional categorization
|
|
tags Json @default("[]")
|
|
|
|
// Metadata
|
|
documentPageNumber Int? // Optional: specific page reference
|
|
documentVersionNumber Int? // Optional: specific version reference
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([dataroomId])
|
|
@@index([linkId])
|
|
@@index([dataroomDocumentId])
|
|
@@index([sourceConversationId])
|
|
@@index([teamId])
|
|
@@index([publishedByUserId])
|
|
@@index([status])
|
|
@@index([visibilityMode])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
// Define FAQ visibility options
|
|
|
|
// Define FAQ status
|