mirror of
https://github.com/hanzoai/dataroom.git
synced 2026-10-30 18:41:07 +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]>
209 lines
9.5 KiB
Plaintext
209 lines
9.5 KiB
Plaintext
|
|
|
|
model Link {
|
|
id String @id @default(cuid())
|
|
document Document? @relation(fields: [documentId], references: [id], onDelete: Cascade)
|
|
documentId String? // This can be nullable, representing links without documents
|
|
dataroom Dataroom? @relation(fields: [dataroomId], references: [id], onDelete: Cascade)
|
|
dataroomId String? // This can be nullable, representing links without datarooms
|
|
linkType String @default("DOCUMENT_LINK") // This will store the type of the link
|
|
url String? @unique
|
|
name String? // Link name
|
|
slug String? // Link slug for pretty URLs
|
|
expiresAt DateTime? // Optional expiration date
|
|
password String? // Optional password for link protection
|
|
allowList Json @default("[]")// Array of emails and domains allowed to view the document
|
|
denyList Json @default("[]")// Array of emails and domains denied to view the document
|
|
emailProtected Boolean @default(true) // Optional email protection
|
|
emailAuthenticated Boolean @default(false) // Optional email authentication flag
|
|
allowDownload Boolean? @default(false) // Optional give user a option to allow to download the document
|
|
isArchived Boolean @default(false) // Indicates if the link is archived
|
|
deletedAt DateTime? // Soft delete timestamp
|
|
views View[]
|
|
domain Domain? @relation(fields: [domainId], references: [id], onDelete: SetNull)
|
|
domainId String? // This can be nullable, representing links without custom domains
|
|
domainSlug String? // This will store the domain's slug even if the domain is deleted
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
enableNotification Boolean? @default(true) // Optional give user a option to pause/resume the notifications
|
|
enableFeedback Boolean? @default(false) // Optional give user a option to enable the reactions toolbar
|
|
enableQuestion Boolean? @default(false) // Optional give user a option to enable the question feedback
|
|
enableScreenshotProtection Boolean? @default(false) // Optional give user a option to enable the screenshot protection
|
|
feedback Feedback?
|
|
enableAgreement Boolean? @default(false) // Optional give user a option to enable the terms and conditions
|
|
agreement Agreement? @relation(fields: [agreementId], references: [id], onDelete: SetNull)
|
|
agreementId String? // This can be nullable, representing links without agreements
|
|
showBanner Boolean? @default(false) // Optional give user a option to show the banner and end of document signup form
|
|
enableWatermark Boolean? @default(false) // Optional give user a option to enable the watermark
|
|
watermarkConfig Json? // This will store the watermark configuration: {text: "Confidential", isTiled: false, color: "#000000", fontSize: 12, opacity: 0.5, rotation: 30, position: "top-right"}
|
|
|
|
// group links
|
|
audienceType String @default("GENERAL") // This will store the audience type of the link
|
|
groupId String?
|
|
group ViewerGroup? @relation(fields: [groupId], references: [id], onDelete: SetNull)
|
|
|
|
// granular permissions
|
|
permissionGroupId String?
|
|
permissionGroup PermissionGroup? @relation(fields: [permissionGroupId], references: [id], onDelete: SetNull)
|
|
|
|
// custom metatags
|
|
metaTitle String? // This will be the meta title of the link
|
|
metaDescription String? // This will be the meta description of the link
|
|
metaImage String? // This will be the meta image of the link
|
|
metaFavicon String? // This will be the meta favicon of the link
|
|
enableCustomMetatag Boolean? @default(false) // Optional give user a option to enable the custom metatag
|
|
|
|
// custom welcome message (overrides brand welcome message)
|
|
welcomeMessage String? // Custom welcome message for this specific link
|
|
|
|
// conversation
|
|
enableConversation Boolean @default(false) // Controls if conversations are allowed on this link
|
|
conversations Conversation[]
|
|
|
|
// FAQ system
|
|
dataroomFaqItems DataroomFaqItem[]
|
|
|
|
// AI chats
|
|
enableAIAgents Boolean? @default(false) // Enable AI agents for this link
|
|
chats Chat[]
|
|
|
|
// upload
|
|
enableUpload Boolean? @default(false) // Optional give user a option to enable the upload document function
|
|
isFileRequestOnly Boolean? @default(false) // Optional give user a option to enable the file request only
|
|
uploadFolderId String? // This can be nullable, indicating upload to root folder, either document folder or dataroom folder
|
|
enableIndexFile Boolean? @default(false)
|
|
|
|
uploadedDocuments DocumentUpload[]
|
|
|
|
teamId String?
|
|
team Team? @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
|
|
|
ownerId String?
|
|
owner User? @relation("LinkOwner", fields: [ownerId], references: [id], onDelete: SetNull)
|
|
|
|
customFields CustomField[]
|
|
|
|
tags TagItem[]
|
|
viewerInvitations ViewerInvitation[]
|
|
|
|
// visitor groups for allow-list
|
|
visitorGroups LinkVisitorGroup[]
|
|
|
|
// workflow entry link
|
|
workflow Workflow?
|
|
|
|
@@unique([domainSlug, slug])
|
|
@@index([documentId])
|
|
@@index([teamId])
|
|
@@index([documentId, isArchived]) // Performance optimization for active links filtering
|
|
@@index([permissionGroupId]) // Performance optimization for permission group queries
|
|
@@index([deletedAt]) // Performance optimization for filtering deleted links
|
|
@@index([ownerId]) // Performance optimization for link owner queries
|
|
}
|
|
|
|
model LinkPreset {
|
|
id String @id @default(cuid())
|
|
name String
|
|
teamId String
|
|
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
|
pId String? @unique
|
|
|
|
enableCustomMetaTag Boolean? @default(false) // Optional give user a option to enable the custom metatag
|
|
metaTitle String? // This will be the meta title of the link
|
|
metaDescription String? // This will be the meta description of the link
|
|
metaImage String? // This will be the meta image of the link
|
|
metaFavicon String? // This will be the meta favicon of the link
|
|
|
|
enableNotification Boolean? @default(false)
|
|
emailProtected Boolean? @default(true)
|
|
emailAuthenticated Boolean? @default(false)
|
|
allowDownload Boolean? @default(false)
|
|
enableAllowList Boolean? @default(false)
|
|
allowList Json@default("[]")
|
|
enableDenyList Boolean? @default(false)
|
|
denyList Json@default("[]")
|
|
expiresIn Int? // how many days from link creation until it expires in seconds
|
|
enableScreenshotProtection Boolean? @default(false)
|
|
expiresAt DateTime?
|
|
enablePassword Boolean? @default(false)
|
|
password String?
|
|
enableWatermark Boolean? @default(false)
|
|
watermarkConfig Json? //{text: "Confidential", isTiled: false, color: "#000000", fontSize: 12, opacity: 0.5, rotation: 30, position: "top-right"}
|
|
|
|
enableAgreement Boolean? @default(false)
|
|
agreementId String?
|
|
|
|
enableCustomFields Boolean? @default(false)
|
|
customFields Json? //[{type: "SHORT_TEXT", identifier: "name", label: "Name", required: true}]
|
|
|
|
showBanner Boolean? @default(false) // Optional give user a option to show the "Powered by Papermark" banner
|
|
|
|
welcomeMessage String? // Custom welcome message for links created from this preset
|
|
|
|
isDefault Boolean @default(false)
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([teamId])
|
|
}
|
|
|
|
|
|
model VisitorGroup {
|
|
id String @id @default(cuid())
|
|
name String
|
|
emails Json @default("[]")// List of emails and domains (e.g., "[email protected]", "@example.org")
|
|
|
|
teamId String
|
|
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
|
|
|
links LinkVisitorGroup[]
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([teamId])
|
|
}
|
|
|
|
model LinkVisitorGroup {
|
|
id String @id @default(cuid())
|
|
linkId String
|
|
link Link @relation(fields: [linkId], references: [id], onDelete: Cascade)
|
|
visitorGroupId String
|
|
visitorGroup VisitorGroup @relation(fields: [visitorGroupId], references: [id], onDelete: Cascade)
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([linkId, visitorGroupId])
|
|
@@index([linkId])
|
|
@@index([visitorGroupId])
|
|
}
|
|
|
|
model CustomField {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
type String
|
|
identifier String
|
|
label String
|
|
placeholder String?
|
|
required Boolean @default(false)
|
|
disabled Boolean @default(false)
|
|
link Link @relation(fields: [linkId], references: [id], onDelete: Cascade)
|
|
linkId String
|
|
orderIndex Int @default(0)
|
|
|
|
@@index([linkId])
|
|
}
|
|
|
|
model CustomFieldResponse {
|
|
id String @id @default(cuid())
|
|
data Json // Store the custom field responses as a JSON object [{ "identifier": "value", "label": "value", "response:" }]
|
|
viewId String @unique
|
|
view View @relation(fields: [viewId], references: [id], onDelete: Cascade)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([viewId])
|
|
}
|