mirror of
https://github.com/documenso/documenso.git
synced 2025-11-15 17:21:41 +10:00
feat: add organisations (#1820)
This commit is contained in:
@ -39,7 +39,6 @@ enum Role {
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
name String?
|
||||
customerId String? @unique
|
||||
email String @unique
|
||||
emailVerified DateTime?
|
||||
password String? // Todo: (RR7) Remove after RR7 migration.
|
||||
@ -53,24 +52,23 @@ model User {
|
||||
avatarImageId String?
|
||||
disabled Boolean @default(false)
|
||||
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
documents Document[]
|
||||
folders Folder[]
|
||||
subscriptions Subscription[]
|
||||
passwordResetTokens PasswordResetToken[]
|
||||
ownedTeams Team[]
|
||||
ownedPendingTeams TeamPending[]
|
||||
teamMembers TeamMember[]
|
||||
twoFactorSecret String?
|
||||
twoFactorEnabled Boolean @default(false)
|
||||
twoFactorBackupCodes String?
|
||||
url String? @unique
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
passwordResetTokens PasswordResetToken[]
|
||||
|
||||
ownedOrganisations Organisation[]
|
||||
organisationMember OrganisationMember[]
|
||||
|
||||
twoFactorSecret String?
|
||||
twoFactorEnabled Boolean @default(false)
|
||||
twoFactorBackupCodes String?
|
||||
|
||||
folders Folder[]
|
||||
documents Document[]
|
||||
templates Template[]
|
||||
|
||||
profile UserProfile?
|
||||
verificationTokens VerificationToken[]
|
||||
apiTokens ApiToken[]
|
||||
templates Template[]
|
||||
securityAuditLogs UserSecurityAuditLog[]
|
||||
webhooks Webhook[]
|
||||
siteSettings SiteSettings[]
|
||||
@ -80,15 +78,6 @@ model User {
|
||||
@@index([email])
|
||||
}
|
||||
|
||||
model UserProfile {
|
||||
id String @id @default(cuid())
|
||||
enabled Boolean @default(false)
|
||||
userId Int @unique
|
||||
bio String?
|
||||
|
||||
User User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model TeamProfile {
|
||||
id String @id @default(cuid())
|
||||
enabled Boolean @default(false)
|
||||
@ -191,8 +180,8 @@ model Webhook {
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
userId Int
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
teamId Int?
|
||||
team Team? @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
teamId Int
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
webhookCalls WebhookCall[]
|
||||
}
|
||||
|
||||
@ -228,8 +217,8 @@ model ApiToken {
|
||||
createdAt DateTime @default(now())
|
||||
userId Int?
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
teamId Int?
|
||||
team Team? @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
teamId Int
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
enum SubscriptionStatus {
|
||||
@ -244,16 +233,46 @@ model Subscription {
|
||||
planId String @unique
|
||||
priceId String
|
||||
periodEnd DateTime?
|
||||
userId Int?
|
||||
teamId Int? @unique
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
cancelAtPeriodEnd Boolean @default(false)
|
||||
|
||||
team Team? @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
customerId String
|
||||
|
||||
@@index([userId])
|
||||
organisationId String @unique
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([organisationId])
|
||||
}
|
||||
|
||||
/// @zod.import(["import { ZClaimFlagsSchema } from '@documenso/lib/types/subscription';"])
|
||||
model SubscriptionClaim {
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
name String
|
||||
locked Boolean @default(false)
|
||||
|
||||
teamCount Int
|
||||
memberCount Int
|
||||
|
||||
flags Json /// [ClaimFlags] @zod.custom.use(ZClaimFlagsSchema)
|
||||
}
|
||||
|
||||
/// @zod.import(["import { ZClaimFlagsSchema } from '@documenso/lib/types/subscription';"])
|
||||
model OrganisationClaim {
|
||||
id String @id
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
originalSubscriptionClaimId String?
|
||||
organisation Organisation?
|
||||
|
||||
teamCount Int
|
||||
memberCount Int
|
||||
|
||||
flags Json /// [ClaimFlags] @zod.custom.use(ZClaimFlagsSchema)
|
||||
}
|
||||
|
||||
model Account {
|
||||
@ -323,8 +342,8 @@ model Folder {
|
||||
name String
|
||||
userId Int
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
teamId Int?
|
||||
team Team? @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
teamId Int
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
pinned Boolean @default(false)
|
||||
parentId String?
|
||||
parent Folder? @relation("FolderToFolder", fields: [parentId], references: [id], onDelete: Cascade)
|
||||
@ -344,11 +363,16 @@ model Folder {
|
||||
|
||||
/// @zod.import(["import { ZDocumentAuthOptionsSchema } from '@documenso/lib/types/document-auth';", "import { ZDocumentFormValuesSchema } from '@documenso/lib/types/document-form-values';"])
|
||||
model Document {
|
||||
id Int @id @default(autoincrement())
|
||||
qrToken String? /// @zod.string.describe("The token for viewing the document using the QR code on the certificate.")
|
||||
externalId String? /// @zod.string.describe("A custom external ID you can use to identify the document.")
|
||||
userId Int /// @zod.number.describe("The ID of the user that created this document.")
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
id Int @id @default(autoincrement())
|
||||
qrToken String? /// @zod.string.describe("The token for viewing the document using the QR code on the certificate.")
|
||||
externalId String? /// @zod.string.describe("A custom external ID you can use to identify the document.")
|
||||
|
||||
userId Int /// @zod.number.describe("The ID of the user that created this document.")
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
teamId Int
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
|
||||
authOptions Json? /// [DocumentAuthOptions] @zod.custom.use(ZDocumentAuthOptionsSchema)
|
||||
formValues Json? /// [DocumentFormValues] @zod.custom.use(ZDocumentFormValuesSchema)
|
||||
visibility DocumentVisibility @default(EVERYONE)
|
||||
@ -363,14 +387,12 @@ model Document {
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
completedAt DateTime?
|
||||
deletedAt DateTime?
|
||||
teamId Int?
|
||||
templateId Int?
|
||||
source DocumentSource
|
||||
|
||||
useLegacyFieldInsertion Boolean @default(false)
|
||||
|
||||
documentData DocumentData @relation(fields: [documentDataId], references: [id], onDelete: Cascade)
|
||||
team Team? @relation(fields: [teamId], references: [id])
|
||||
template Template? @relation(fields: [templateId], references: [id], onDelete: SetNull)
|
||||
|
||||
auditLogs DocumentAuditLog[]
|
||||
@ -569,20 +591,141 @@ model DocumentShareLink {
|
||||
@@unique([documentId, email])
|
||||
}
|
||||
|
||||
enum OrganisationType {
|
||||
PERSONAL
|
||||
ORGANISATION
|
||||
}
|
||||
|
||||
model Organisation {
|
||||
id String @id
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
type OrganisationType
|
||||
name String
|
||||
url String @unique
|
||||
avatarImageId String?
|
||||
|
||||
customerId String? @unique
|
||||
subscription Subscription?
|
||||
|
||||
organisationClaimId String @unique
|
||||
organisationClaim OrganisationClaim @relation(fields: [organisationClaimId], references: [id])
|
||||
|
||||
members OrganisationMember[]
|
||||
invites OrganisationMemberInvite[]
|
||||
groups OrganisationGroup[]
|
||||
|
||||
teams Team[]
|
||||
|
||||
avatarImage AvatarImage? @relation(fields: [avatarImageId], references: [id], onDelete: SetNull)
|
||||
|
||||
ownerUserId Int
|
||||
owner User @relation(fields: [ownerUserId], references: [id], onDelete: Cascade)
|
||||
|
||||
organisationGlobalSettingsId String @unique
|
||||
organisationGlobalSettings OrganisationGlobalSettings @relation(fields: [organisationGlobalSettingsId], references: [id])
|
||||
}
|
||||
|
||||
model OrganisationMember {
|
||||
id String @id
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
userId Int
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
organisationId String
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
|
||||
organisationGroupMembers OrganisationGroupMember[]
|
||||
|
||||
@@unique([userId, organisationId])
|
||||
}
|
||||
|
||||
model OrganisationMemberInvite {
|
||||
id String @id
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
email String
|
||||
token String @unique
|
||||
|
||||
status OrganisationMemberInviteStatus @default(PENDING)
|
||||
|
||||
organisationId String
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
organisationRole OrganisationMemberRole
|
||||
}
|
||||
|
||||
model OrganisationGroup {
|
||||
id String @id
|
||||
name String?
|
||||
|
||||
type OrganisationGroupType
|
||||
organisationRole OrganisationMemberRole
|
||||
|
||||
organisationId String
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
|
||||
organisationGroupMembers OrganisationGroupMember[]
|
||||
|
||||
teamGroups TeamGroup[]
|
||||
}
|
||||
|
||||
model OrganisationGroupMember {
|
||||
id String @id
|
||||
|
||||
groupId String
|
||||
group OrganisationGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
||||
|
||||
organisationMember OrganisationMember @relation(fields: [organisationMemberId], references: [id], onDelete: Cascade)
|
||||
organisationMemberId String
|
||||
|
||||
@@unique([organisationMemberId, groupId])
|
||||
}
|
||||
|
||||
model TeamGroup {
|
||||
id String @id
|
||||
|
||||
organisationGroupId String
|
||||
organisationGroup OrganisationGroup @relation(fields: [organisationGroupId], references: [id], onDelete: Cascade)
|
||||
|
||||
teamRole TeamMemberRole
|
||||
|
||||
teamId Int
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([teamId, organisationGroupId])
|
||||
}
|
||||
|
||||
enum OrganisationGroupType {
|
||||
INTERNAL_ORGANISATION
|
||||
INTERNAL_TEAM
|
||||
CUSTOM
|
||||
}
|
||||
|
||||
enum OrganisationMemberRole {
|
||||
ADMIN
|
||||
MANAGER
|
||||
MEMBER
|
||||
}
|
||||
|
||||
enum TeamMemberRole {
|
||||
ADMIN
|
||||
MANAGER
|
||||
MEMBER
|
||||
}
|
||||
|
||||
enum TeamMemberInviteStatus {
|
||||
enum OrganisationMemberInviteStatus {
|
||||
ACCEPTED
|
||||
PENDING
|
||||
DECLINED
|
||||
}
|
||||
|
||||
model TeamGlobalSettings {
|
||||
teamId Int @unique
|
||||
model OrganisationGlobalSettings {
|
||||
id String @id
|
||||
organisation Organisation?
|
||||
|
||||
documentVisibility DocumentVisibility @default(EVERYONE)
|
||||
documentLanguage String @default("en")
|
||||
includeSenderDetails Boolean @default(true)
|
||||
@ -596,11 +739,25 @@ model TeamGlobalSettings {
|
||||
brandingLogo String @default("")
|
||||
brandingUrl String @default("")
|
||||
brandingCompanyDetails String @default("")
|
||||
brandingHidePoweredBy Boolean @default(false)
|
||||
}
|
||||
|
||||
allowEmbeddedAuthoring Boolean @default(false)
|
||||
model TeamGlobalSettings {
|
||||
id String @id
|
||||
team Team?
|
||||
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
documentVisibility DocumentVisibility?
|
||||
documentLanguage String?
|
||||
includeSenderDetails Boolean?
|
||||
includeSigningCertificate Boolean?
|
||||
|
||||
typedSignatureEnabled Boolean?
|
||||
uploadSignatureEnabled Boolean?
|
||||
drawSignatureEnabled Boolean?
|
||||
|
||||
brandingEnabled Boolean?
|
||||
brandingLogo String?
|
||||
brandingUrl String?
|
||||
brandingCompanyDetails String?
|
||||
}
|
||||
|
||||
model Team {
|
||||
@ -609,49 +766,25 @@ model Team {
|
||||
url String @unique
|
||||
createdAt DateTime @default(now())
|
||||
avatarImageId String?
|
||||
customerId String? @unique
|
||||
ownerUserId Int
|
||||
|
||||
members TeamMember[]
|
||||
invites TeamMemberInvite[]
|
||||
teamEmail TeamEmail?
|
||||
emailVerification TeamEmailVerification?
|
||||
transferVerification TeamTransferVerification?
|
||||
teamGlobalSettings TeamGlobalSettings?
|
||||
avatarImage AvatarImage? @relation(fields: [avatarImageId], references: [id], onDelete: SetNull)
|
||||
teamEmail TeamEmail?
|
||||
emailVerification TeamEmailVerification?
|
||||
avatarImage AvatarImage? @relation(fields: [avatarImageId], references: [id], onDelete: SetNull)
|
||||
|
||||
profile TeamProfile?
|
||||
owner User @relation(fields: [ownerUserId], references: [id], onDelete: Cascade)
|
||||
subscription Subscription?
|
||||
profile TeamProfile?
|
||||
|
||||
documents Document[]
|
||||
templates Template[]
|
||||
folders Folder[]
|
||||
apiTokens ApiToken[]
|
||||
webhooks Webhook[]
|
||||
}
|
||||
documents Document[]
|
||||
templates Template[]
|
||||
folders Folder[]
|
||||
apiTokens ApiToken[]
|
||||
webhooks Webhook[]
|
||||
teamGroups TeamGroup[]
|
||||
|
||||
model TeamPending {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
url String @unique
|
||||
createdAt DateTime @default(now())
|
||||
customerId String @unique
|
||||
ownerUserId Int
|
||||
organisationId String
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
|
||||
owner User @relation(fields: [ownerUserId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model TeamMember {
|
||||
id Int @id @default(autoincrement())
|
||||
teamId Int
|
||||
createdAt DateTime @default(now())
|
||||
role TeamMemberRole
|
||||
userId Int
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, teamId])
|
||||
teamGlobalSettingsId String @unique
|
||||
teamGlobalSettings TeamGlobalSettings @relation(fields: [teamGlobalSettingsId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model TeamEmail {
|
||||
@ -674,33 +807,6 @@ model TeamEmailVerification {
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model TeamTransferVerification {
|
||||
teamId Int @id @unique
|
||||
userId Int
|
||||
name String
|
||||
email String
|
||||
token String @unique
|
||||
completed Boolean @default(false)
|
||||
expiresAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
clearPaymentMethods Boolean @default(false)
|
||||
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model TeamMemberInvite {
|
||||
id Int @id @default(autoincrement())
|
||||
teamId Int
|
||||
createdAt DateTime @default(now())
|
||||
email String
|
||||
status TeamMemberInviteStatus @default(PENDING)
|
||||
role TeamMemberRole
|
||||
token String @unique
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([teamId, email])
|
||||
}
|
||||
|
||||
enum TemplateType {
|
||||
PUBLIC
|
||||
PRIVATE
|
||||
@ -735,8 +841,6 @@ model Template {
|
||||
externalId String?
|
||||
type TemplateType @default(PRIVATE)
|
||||
title String
|
||||
userId Int
|
||||
teamId Int?
|
||||
visibility DocumentVisibility @default(EVERYONE)
|
||||
authOptions Json? /// [DocumentAuthOptions] @zod.custom.use(ZDocumentAuthOptionsSchema)
|
||||
templateMeta TemplateMeta?
|
||||
@ -748,17 +852,24 @@ model Template {
|
||||
|
||||
useLegacyFieldInsertion Boolean @default(false)
|
||||
|
||||
team Team? @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
templateDocumentData DocumentData @relation(fields: [templateDocumentDataId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
recipients Recipient[]
|
||||
fields Field[]
|
||||
directLink TemplateDirectLink?
|
||||
documents Document[]
|
||||
folder Folder? @relation(fields: [folderId], references: [id], onDelete: Cascade)
|
||||
folderId String?
|
||||
userId Int
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
teamId Int
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
|
||||
templateDocumentData DocumentData @relation(fields: [templateDocumentDataId], references: [id], onDelete: Cascade)
|
||||
|
||||
recipients Recipient[]
|
||||
fields Field[]
|
||||
directLink TemplateDirectLink?
|
||||
documents Document[]
|
||||
|
||||
folder Folder? @relation(fields: [folderId], references: [id], onDelete: Cascade)
|
||||
folderId String?
|
||||
|
||||
@@unique([templateDocumentDataId])
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
model TemplateDirectLink {
|
||||
@ -836,6 +947,7 @@ model AvatarImage {
|
||||
id String @id @default(cuid())
|
||||
bytes String
|
||||
|
||||
team Team[]
|
||||
user User[]
|
||||
team Team[]
|
||||
user User[]
|
||||
organisation Organisation[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user