Files
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

88 lines
3.3 KiB
Plaintext

model Team {
id String @id @default(cuid())
name String
slug String? @unique // Optional human-readable identifier (e.g. "acme"), used for SSO login
users UserTeam[]
documents Document[]
folders Folder[]
domains Domain[]
invitations Invitation[]
sentEmails SentEmail[]
brand Brand?
datarooms Dataroom[]
agreements Agreement[]
viewerGroups ViewerGroup[]
visitorGroups VisitorGroup[]
viewers Viewer[]
permissionGroups PermissionGroup[]
linkPresets LinkPreset[] // Link presets for the team
incomingWebhooks IncomingWebhook[]
restrictedTokens RestrictedToken[]
webhooks Webhook[]
conversations Conversation[]
dataroomFaqItems DataroomFaqItem[]
uploadedDocuments DocumentUpload[]
Tag Tag[]
annotations DocumentAnnotation[] // Annotations created by team members
installedIntegrations InstalledIntegration[]
links Link[]
views View[]
workflows Workflow[]
plan String @default("free")
stripeId String? @unique // Stripe customer ID
subscriptionId String? @unique // Stripe subscription ID
startsAt DateTime? // Stripe subscription start date
endsAt DateTime? // Stripe subscription end date
pausedAt DateTime? // When the subscription was paused
pauseStartsAt DateTime? // When the pause period starts
pauseEndsAt DateTime? // When the pause period ends
cancelledAt DateTime? // When the subscription was cancelled
limits Json? // Plan limits // {datarooms: 1, users: 1, domains: 1, customDomainOnPro: boolean, customDomainInDataroom: boolean}
// team settings
enableExcelAdvancedMode Boolean @default(false) // Enable Excel advanced mode for all documents in the team
replicateDataroomFolders Boolean @default(true) // Replicate dataroom folder structure in "All Documents"
timezone String @default("Etc/UTC") // Team-wide timezone for analytics display (IANA timezone identifier)
// SSO (SAML/SCIM via BoxyHQ Jackson)
ssoEnabled Boolean @default(false) // Feature flag: team has access to SSO
ssoEmailDomain String? @unique // Email domain enforced for SSO (e.g. "acme.com")
ssoEnforcedAt DateTime? // When set, all users with this domain MUST use SSO
// Survey data (stored as JSON for flexibility)
surveyData Json? // { dealType?: string, dealSize?: string, ... }
// AI agents
agentsEnabled Boolean @default(false) // Enable AI agents for the team
vectorStoreId String? // OpenAI vector store ID for team-level document search
chats Chat[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ignoredDomains Json @default("[]")// Domains that are ignored for the team
globalBlockList Json @default("[]")// Email and domains that are blocked for the team
}
model UserTeam {
role String @default("MEMBER")
status String @default("ACTIVE")
userId String
teamId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
blockedAt DateTime? // When the user was blocked
notificationPreferences Json? // Format: { yearInReview: { "enabled": false } }
@@id([userId, teamId])
@@index([userId])
@@index([teamId])
}