Skip to content

Instantly share code, notes, and snippets.

@AlexandroMtzG
Created September 29, 2022 01:34
Show Gist options
  • Save AlexandroMtzG/bc7e17d1a23843dbf3c81f41061e4c2e to your computer and use it in GitHub Desktop.
Save AlexandroMtzG/bc7e17d1a23843dbf3c81f41061e4c2e to your computer and use it in GitHub Desktop.
SaasRock schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
email String @unique
passwordHash String
firstName String
lastName String
avatar String?
phone String?
defaultTenantId String?
verifyToken String?
active Boolean @default(false)
admin AdminUser?
createdApiKeys ApiKey[]
contacts Contact[]
createdContractActivites ContractActivity[]
contracts ContractMember[]
workflowSteps EntityWorkflowStepAssignee[]
createdGroups Group[]
groups GroupUser[]
createdLinkedAccounts LinkedAccount[]
logs Log[]
createdRows Row[]
createdRowComments RowComment[]
createdRowCommentReactions RowCommentReaction[]
rowPermissions RowPermission[]
assignedTasks RowTask[] @relation("assignedToUser")
completedTasks RowTask[] @relation("completedByUser")
createdRowTasks RowTask[] @relation("createdByUser")
workflowTransitions RowWorkflowTransition[]
tenants TenantUser[]
invitation TenantUserInvitation?
roles UserRole[]
readEmails EmailRead[]
}
model AdminUser {
userId String @unique
role Int
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model Tenant {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
slug String @unique
name String
icon String?
subscriptionId String?
active Boolean @default(false)
apiKeys ApiKey[]
workflowSteps EntityWorkflowStepAssignee[]
groups Group[]
asClientLinkedAccounts LinkedAccount[] @relation("clientTenant")
createdLinkedAccounts LinkedAccount[] @relation("createdByTenant")
asProviderLinkedAccounts LinkedAccount[] @relation("providerTenant")
logs Log[]
rows Row[]
rowPermissions RowPermission[]
subscription TenantSubscription?
users TenantUser[]
invitations TenantUserInvitation[]
userRoles UserRole[]
inboundAddresses TenantInboundAddress[]
events Event[]
fromRegistration Registration?
}
model Registration {
id String @id @default(cuid())
createdAt DateTime @default(now())
email String @unique
firstName String
lastName String
token String @unique
ipAddress String?
company String?
selectedSubscriptionPriceId String?
createdTenantId String? @unique
createdTenant Tenant? @relation(fields: [createdTenantId], references: [id], onDelete: Cascade)
}
model Blacklist {
id String @id @default(cuid())
createdAt DateTime @default(now())
type String // email, domain, ip
value String
active Boolean @default(true)
registerAttempts Int @default(0)
}
model TenantSubscription {
id String @id @default(cuid())
tenantId String @unique
stripeCustomerId String?
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
products TenantSubscriptionProduct[]
}
model TenantSubscriptionProduct {
id String @id @default(cuid())
createdAt DateTime @default(now())
tenantSubscriptionId String
subscriptionProductId String
cancelledAt DateTime?
endsAt DateTime?
stripeSubscriptionId String?
quantity Int?
fromCheckoutSessionId String?
tenantSubscription TenantSubscription @relation(fields: [tenantSubscriptionId], references: [id], onDelete: Cascade)
subscriptionProduct SubscriptionProduct @relation(fields: [subscriptionProductId], references: [id])
prices TenantSubscriptionProductPrice[]
}
model TenantSubscriptionProductPrice {
id String @id @default(cuid())
tenantSubscriptionProductId String
tenantSubscriptionProduct TenantSubscriptionProduct @relation(fields: [tenantSubscriptionProductId], references: [id], onDelete: Cascade)
subscriptionPriceId String?
subscriptionPrice SubscriptionPrice? @relation(fields: [subscriptionPriceId], references: [id])
subscriptionUsageBasedPriceId String?
subscriptionUsageBasedPrice SubscriptionUsageBasedPrice? @relation(fields: [subscriptionUsageBasedPriceId], references: [id])
usageRecords TenantSubscriptionUsageRecord[]
}
model TenantSubscriptionUsageRecord {
id String @id @default(cuid())
tenantSubscriptionProductPriceId String
tenantSubscriptionProductPrice TenantSubscriptionProductPrice @relation(fields: [tenantSubscriptionProductPriceId], references: [id], onDelete: Cascade)
timestamp Int
quantity Int
stripeSubscriptionItemId String?
}
model CheckoutSessionStatus {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @unique
pending Boolean @default(true) // has not added products to tenant
email String
fromUrl String
fromUserId String?
fromTenantId String?
createdUserId String?
createdTenantId String?
}
model TenantUser {
id String @id @default(cuid())
createdAt DateTime @default(now())
tenantId String
userId String
type Int
joined Int
status Int
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
roles TenantUserRole[]
}
model Role {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String @unique
description String
type String
assignToNewUsers Boolean
isDefault Boolean
order Int
workflowSteps EntityWorkflowStepAssignee[]
permissions RolePermission[]
rowPermissions RowPermission[]
users UserRole[]
}
model Permission {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String @unique
description String
type String
isDefault Boolean
order Int
inRoles RolePermission[]
entityId String?
entity Entity? @relation(fields: [entityId], references: [id], onDelete: Cascade)
}
model RolePermission {
id String @id @default(cuid())
roleId String
permissionId String
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
}
model UserRole {
id String @id @default(cuid())
createdAt DateTime @default(now())
userId String
roleId String
tenantId String?
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
tenant Tenant? @relation(fields: [tenantId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, roleId, tenantId])
}
model Group {
id String @id @default(cuid())
createdAt DateTime @default(now())
createdByUserId String
tenantId String?
name String
description String
color Int
createdByUser User @relation(fields: [createdByUserId], references: [id], onDelete: Cascade)
tenant Tenant? @relation(fields: [tenantId], references: [id], onDelete: Cascade)
workflowSteps EntityWorkflowStepAssignee[]
users GroupUser[]
rowPermissions RowPermission[]
}
model GroupUser {
id String @id @default(cuid())
groupId String
userId String
group Group @relation(fields: [groupId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model TenantUserRole {
id String @id @default(cuid())
tenantUserId String
order Int
name String
tenantUser TenantUser @relation(fields: [tenantUserId], references: [id], onDelete: Cascade)
}
model TenantUserInvitation {
id String @id @default(cuid())
tenantId String
email String
firstName String
lastName String
type Int
pending Boolean
createdUserId String? @unique
user User? @relation(fields: [createdUserId], references: [id], onDelete: Cascade)
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
}
model LinkedAccount {
id String @id @default(cuid())
createdAt DateTime @default(now())
createdByUserId String
createdByTenantId String
providerTenantId String
clientTenantId String
status Int
clientTenant Tenant @relation("clientTenant", fields: [clientTenantId], references: [id], onDelete: Cascade)
createdByTenant Tenant @relation("createdByTenant", fields: [createdByTenantId], references: [id], onDelete: Cascade)
createdByUser User @relation(fields: [createdByUserId], references: [id], onDelete: Cascade)
providerTenant Tenant @relation("providerTenant", fields: [providerTenantId], references: [id], onDelete: Cascade)
rows Row[]
}
model ApiKey {
id String @id @default(cuid())
createdAt DateTime @default(now())
createdByUserId String
tenantId String
key String @default(uuid())
alias String
expires DateTime?
active Boolean
createdByUser User @relation(fields: [createdByUserId], references: [id], onDelete: Cascade)
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
entities ApiKeyEntity[]
apiKeyLogs ApiKeyLog[]
logs Log[]
createdRows Row[]
transitions RowWorkflowTransition[]
@@unique([tenantId, alias])
}
model ApiKeyEntity {
id String @id @default(cuid())
apiKeyId String
entityId String
create Boolean
read Boolean
update Boolean
delete Boolean
apiKey ApiKey @relation(fields: [apiKeyId], references: [id], onDelete: Cascade)
entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
}
model Log {
id String @id @default(cuid())
createdAt DateTime @default(now())
tenantId String?
userId String?
apiKeyId String?
rowId String?
url String
action String
details String?
commentId String?
workflowTransitionId String?
apiKey ApiKey? @relation(fields: [apiKeyId], references: [id], onDelete: Cascade)
comment RowComment? @relation(fields: [commentId], references: [id])
row Row? @relation(fields: [rowId], references: [id])
tenant Tenant? @relation(fields: [tenantId], references: [id], onDelete: Cascade)
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
workflowTransition RowWorkflowTransition? @relation(fields: [workflowTransitionId], references: [id])
webhookLogs EntityWebhookLog[]
}
model ApiKeyLog {
id String @id @default(cuid())
createdAt DateTime @default(now())
apiKeyId String?
ip String
endpoint String
method String
params String
status Int?
error String?
apiKey ApiKey? @relation(fields: [apiKeyId], references: [id], onDelete: Cascade)
}
model SubscriptionProduct {
id String @id @default(cuid())
stripeId String
order Int
title String
active Boolean
model Int
public Boolean
description String?
badge String?
prices SubscriptionPrice[]
features SubscriptionFeature[]
tenantProducts TenantSubscriptionProduct[]
usageBasedPrices SubscriptionUsageBasedPrice[]
}
model SubscriptionPrice {
id String @id @default(cuid())
subscriptionProductId String
subscriptionProduct SubscriptionProduct @relation(fields: [subscriptionProductId], references: [id], onDelete: Cascade)
stripeId String
type Int
billingPeriod Int
price Decimal
currency String
trialDays Int
active Boolean
deals Deal[]
tenantProductPrices TenantSubscriptionProductPrice[]
}
model SubscriptionUsageBasedPrice {
id String @id @default(cuid())
subscriptionProductId String
subscriptionProduct SubscriptionProduct @relation(fields: [subscriptionProductId], references: [id], onDelete: Cascade)
stripeId String
billingPeriod Int
currency String
unit String
unitTitle String
unitTitlePlural String
usageType String
aggregateUsage String
tiersMode String
billingScheme String
tiers SubscriptionUsageBasedTier[]
tenantProductPrices TenantSubscriptionProductPrice[]
}
model SubscriptionUsageBasedTier {
id String @id @default(cuid())
subscriptionUsageBasedPriceId String
subscriptionUsageBasedPrice SubscriptionUsageBasedPrice @relation(fields: [subscriptionUsageBasedPriceId], references: [id], onDelete: Cascade)
from Int
to Int?
perUnitPrice Decimal?
flatFeePrice Decimal?
}
model SubscriptionFeature {
id String @id @default(cuid())
subscriptionProductId String
order Int
title String
name String
type Int
value Int
subscriptionProduct SubscriptionProduct @relation(fields: [subscriptionProductId], references: [id], onDelete: Cascade)
}
model BlogAuthor {
id String @id @default(cuid())
createdAt DateTime @default(now())
slug String @unique
firstName String
lastName String
image String
url String
posts BlogPost[]
}
model BlogCategory {
id String @id @default(cuid())
createdAt DateTime @default(now())
name String @unique
color Int
posts BlogPost[]
}
model BlogTag {
id String @id @default(cuid())
createdAt DateTime @default(now())
name String @unique
color Int
posts BlogPostTag[]
}
model BlogPostTag {
id String @id @default(cuid())
postId String
tagId String
post BlogPost @relation(fields: [postId], references: [id], onDelete: Cascade)
tag BlogTag @relation(fields: [tagId], references: [id], onDelete: Cascade)
}
model BlogPost {
id String @id @default(cuid())
createdAt DateTime @default(now())
slug String @unique
title String
description String
date DateTime
image String
content String
readingTime String
published Boolean
authorId String
categoryId String
author BlogAuthor @relation(fields: [authorId], references: [id], onDelete: Cascade)
category BlogCategory @relation(fields: [categoryId], references: [id], onDelete: Cascade)
tags BlogPostTag[]
}
model Entity {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String @unique
slug String @unique
order Int @unique
prefix String @unique
title String
titlePlural String
isFeature Boolean
isAutogenerated Boolean
isDefault Boolean
hasApi Boolean
requiresLinkedAccounts Boolean
icon String
active Boolean
hasTags Boolean @default(true)
hasComments Boolean @default(true)
hasTasks Boolean @default(true)
hasWorkflow Boolean @default(false)
defaultVisibility String @default("private")
createdPermissions Permission[]
apiKeys ApiKeyEntity[]
tags EntityTag[]
permissions EntityTenantUserPermission[]
webhooks EntityWebhook[]
workflowStates EntityWorkflowState[]
workflowSteps EntityWorkflowStep[]
properties Property[]
rows Row[]
views EntityView[]
}
model Property {
id String @id @default(cuid())
entityId String
order Int
name String
title String
type Int
formula String?
parentId String?
isDynamic Boolean
isDefault Boolean
isRequired Boolean
isHidden Boolean
isDetail Boolean
attributes PropertyAttribute[]
entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
parent Property? @relation("parentProperty", fields: [parentId], references: [id], onDelete: Cascade)
children Property[] @relation("parentProperty")
options PropertyOption[]
values RowValue[]
inViewProperties EntityViewProperty[]
inViewGroupBy EntityView[]
@@unique([entityId, order])
@@unique([entityId, name])
@@unique([entityId, title])
}
model EntityView {
id String @id @default(cuid())
entityId String
entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
layout String @default("table") // table, board, calendar, list, gallery...
order Int
name String
title String
pageSize Int
isDefault Boolean
columns Int?
properties EntityViewProperty[]
filters EntityViewFilter[]
sort EntityViewSort[]
groupByWorkflowStates Boolean @default(false)
groupByPropertyId String?
groupByProperty Property? @relation(fields: [groupByPropertyId], references: [id], onDelete: Cascade)
@@unique([entityId, name])
@@unique([entityId, order])
}
model EntityViewProperty {
id String @id @default(cuid())
entityViewId String
entityView EntityView @relation(fields: [entityViewId], references: [id], onDelete: Cascade)
propertyId String
property Property @relation(fields: [propertyId], references: [id], onDelete: Cascade)
order Int
@@unique([entityViewId, propertyId])
}
model EntityViewFilter {
id String @id @default(cuid())
entityViewId String
entityView EntityView @relation(fields: [entityViewId], references: [id], onDelete: Cascade)
name String
condition String // is, isNot, contains, doesNotContain...
value String
}
model EntityViewSort {
id String @id @default(cuid())
entityViewId String
entityView EntityView @relation(fields: [entityViewId], references: [id], onDelete: Cascade)
name String
asc Boolean
order Int
}
model PropertyAttribute {
id String @id @default(cuid())
propertyId String
property Property @relation(fields: [propertyId], references: [id], onDelete: Cascade)
name String // pattern, min, max, step, rows, defaultValue, maxSize, acceptFileTypes, uppercase...
value String
@@unique([propertyId, name])
}
model PropertyOption {
id String @id @default(cuid())
propertyId String
parentId String?
order Int
value String
name String?
color Int @default(0)
parent PropertyOption? @relation("parentOption", fields: [parentId], references: [id], onDelete: Cascade)
property Property @relation(fields: [propertyId], references: [id], onDelete: Cascade)
options PropertyOption[] @relation("parentOption")
}
model EntityTag {
id String @id @default(cuid())
entityId String
value String
color Int
entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
rowTags RowTag[]
}
model EntityTenantUserPermission {
id String @id @default(cuid())
entityId String
level Int
entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
}
model EntityWebhook {
id String @id @default(cuid())
entityId String
action String
method String
endpoint String
entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
logs EntityWebhookLog[]
}
model EntityWebhookLog {
id String @id @default(cuid())
webhookId String
logId String
status Int
error String?
log Log @relation(fields: [logId], references: [id], onDelete: Cascade)
webhook EntityWebhook @relation(fields: [webhookId], references: [id], onDelete: Cascade)
}
model EntityWorkflowState {
id String @id @default(cuid())
entityId String
order Int
name String
title String
color Int
canUpdate Boolean
canDelete Boolean
emailSubject String
emailBody String
entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
fromStates EntityWorkflowStep[] @relation("fromState")
toStates EntityWorkflowStep[] @relation("toState")
rows Row[]
}
model EntityWorkflowStep {
id String @id @default(cuid())
entityId String
action String
fromStateId String
toStateId String
assignTo String @default("private")
entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
fromState EntityWorkflowState @relation("fromState", fields: [fromStateId], references: [id], onDelete: Cascade)
toState EntityWorkflowState @relation("toState", fields: [toStateId], references: [id], onDelete: Cascade)
assignees EntityWorkflowStepAssignee[]
transitions RowWorkflowTransition[]
}
model EntityWorkflowStepAssignee {
id String @id @default(cuid())
stepId String
tenantId String?
roleId String?
groupId String?
userId String?
group Group? @relation(fields: [groupId], references: [id], onDelete: Cascade)
role Role? @relation(fields: [roleId], references: [id], onDelete: Cascade)
step EntityWorkflowStep @relation(fields: [stepId], references: [id], onDelete: Cascade)
tenant Tenant? @relation(fields: [tenantId], references: [id], onDelete: Cascade)
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model Row {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
entityId String
tenantId String?
folio Int
visibility String
createdByUserId String?
createdByApiKeyId String?
linkedAccountId String?
canComment Boolean @default(true)
canUpdate Boolean @default(true)
canDelete Boolean @default(true)
workflowStateId String?
parentRowId String?
contactId String?
dealId String?
contractId String?
createdByApiKey ApiKey? @relation(fields: [createdByApiKeyId], references: [id], onDelete: Cascade)
createdByUser User? @relation(fields: [createdByUserId], references: [id], onDelete: Cascade)
entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)
linkedAccount LinkedAccount? @relation(fields: [linkedAccountId], references: [id], onDelete: Cascade)
parentRow Row? @relation("parentRowId", fields: [parentRowId], references: [id], onDelete: Cascade)
tenant Tenant? @relation(fields: [tenantId], references: [id], onDelete: Cascade)
workflowState EntityWorkflowState? @relation(fields: [workflowStateId], references: [id], onDelete: Cascade)
contact Contact?
contract Contract?
contractEmployees ContractEmployee[]
deal Deal?
logs Log[]
details Row[] @relation("parentRowId")
comments RowComment[]
permissions RowPermission[]
tags RowTag[]
tasks RowTask[]
relatedRows RowValue[] @relation("relatedRow")
values RowValue[]
transitions RowWorkflowTransition[]
}
model RowValue {
id String @id @default(cuid())
rowId String
propertyId String
relatedRowId String?
idValue String?
textValue String?
numberValue Decimal?
dateValue DateTime?
booleanValue Boolean?
property Property @relation(fields: [propertyId], references: [id], onDelete: Cascade)
relatedRow Row? @relation("relatedRow", fields: [relatedRowId], references: [id], onDelete: Cascade)
row Row @relation(fields: [rowId], references: [id], onDelete: Cascade)
media RowMedia[]
}
model RowPermission {
id String @id @default(cuid())
rowId String
tenantId String?
roleId String?
groupId String?
userId String?
group Group? @relation(fields: [groupId], references: [id], onDelete: Cascade)
role Role? @relation(fields: [roleId], references: [id], onDelete: Cascade)
row Row @relation(fields: [rowId], references: [id], onDelete: Cascade)
tenant Tenant? @relation(fields: [tenantId], references: [id], onDelete: Cascade)
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model RowMedia {
id String @id @default(cuid())
rowValueId String
title String
name String
file String
type String
publicUrl String?
storageBucket String?
storageProvider String?
rowValue RowValue @relation(fields: [rowValueId], references: [id], onDelete: Cascade)
}
model RowTag {
id String @id @default(cuid())
rowId String
tagId String
row Row @relation(fields: [rowId], references: [id], onDelete: Cascade)
tag EntityTag @relation(fields: [tagId], references: [id], onDelete: Cascade)
}
model RowComment {
id String @id @default(cuid())
createdAt DateTime @default(now())
createdByUserId String
rowId String
value String
isDeleted Boolean?
createdByUser User @relation(fields: [createdByUserId], references: [id], onDelete: Cascade)
row Row @relation(fields: [rowId], references: [id], onDelete: Cascade)
logs Log[]
reactions RowCommentReaction[]
}
model RowCommentReaction {
id String @id @default(cuid())
createdAt DateTime @default(now())
createdByUserId String
rowCommentId String
reaction String
createdByUser User @relation(fields: [createdByUserId], references: [id], onDelete: Cascade)
rowComment RowComment @relation(fields: [rowCommentId], references: [id], onDelete: Cascade)
}
model RowTask {
id String @id @default(cuid())
createdAt DateTime @default(now())
createdByUserId String
rowId String
title String
description String
completed Boolean
completedAt DateTime?
completedByUserId String?
assignedToUserId String?
deadline DateTime?
assignedToUser User? @relation("assignedToUser", fields: [assignedToUserId], references: [id], onDelete: Cascade)
completedByUser User? @relation("completedByUser", fields: [completedByUserId], references: [id], onDelete: Cascade)
createdByUser User @relation("createdByUser", fields: [createdByUserId], references: [id], onDelete: Cascade)
row Row @relation(fields: [rowId], references: [id], onDelete: Cascade)
}
model RowWorkflowTransition {
id String @id @default(cuid())
createdAt DateTime @default(now())
byUserId String?
byApiKeyId String?
byEmailId String?
byEventWebhookAttemptId String?
rowId String
workflowStepId String
byUser User? @relation(fields: [byUserId], references: [id], onDelete: Cascade)
byApiKey ApiKey? @relation(fields: [byApiKeyId], references: [id], onDelete: Cascade)
byEmail Email? @relation(fields: [byEmailId], references: [id], onDelete: Cascade)
byEventWebhookAttempt EventWebhookAttempt? @relation(fields: [byEventWebhookAttemptId], references: [id], onDelete: Cascade)
row Row @relation(fields: [rowId], references: [id], onDelete: Cascade)
workflowStep EntityWorkflowStep @relation(fields: [workflowStepId], references: [id], onDelete: Cascade)
logs Log[]
}
model TenantInboundAddress {
id String @id @default(cuid())
tenantId String
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
address String @unique
email Email[]
}
model Email {
id String @id @default(cuid())
tenantInboundAddressId String?
tenantInboundAddress TenantInboundAddress? @relation(fields: [tenantInboundAddressId], references: [id], onDelete: Cascade)
messageId String @unique
type String // inbound, outbound
date DateTime
subject String
fromEmail String
fromName String?
toEmail String
toName String?
textBody String
htmlBody String
// parentEmailId String?
// parentEmail Email? @relation(name: "replies", fields: [parentEmailId], references: [id], onDelete: Cascade)
reads EmailRead[]
attachments EmailAttachment[]
cc EmailCc[]
// replies Email[] @relation(name: "replies")
transitions RowWorkflowTransition[]
}
model EmailRead {
id String @id @default(cuid())
createdAt DateTime @default(now())
emailId String
email Email @relation(fields: [emailId], references: [id], onDelete: Cascade)
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model EmailCc {
id String @id @default(cuid())
emailId String
toEmail String
toName String?
email Email @relation(fields: [emailId], references: [id], onDelete: Cascade)
}
model EmailAttachment {
id String @id @default(cuid())
emailId String
name String
type String
length Int
content String
publicUrl String?
storageBucket String?
storageProvider String?
email Email @relation(fields: [emailId], references: [id], onDelete: Cascade)
}
model Contact {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
rowId String @unique
ownerId String?
status String
email String
firstName String
lastName String
phone String?
company String?
title String?
owner User? @relation(fields: [ownerId], references: [id], onDelete: Cascade)
row Row @relation(fields: [rowId], references: [id], onDelete: Cascade)
deals Deal[]
}
model Deal {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
rowId String @unique
contactId String
name String
value Decimal
subscriptionPriceId String?
contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
row Row @relation(fields: [rowId], references: [id], onDelete: Cascade)
subscriptionPrice SubscriptionPrice? @relation(fields: [subscriptionPriceId], references: [id], onDelete: Cascade)
}
model Event {
id String @id @default(cuid())
createdAt DateTime @default(now())
tenantId String?
tenant Tenant? @relation(fields: [tenantId], references: [id])
name String
data String
resource String?
attempts EventWebhookAttempt[]
}
model EventWebhookAttempt {
id String @id @default(cuid())
createdAt DateTime @default(now())
startedAt DateTime?
finishedAt DateTime?
eventId String
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
endpoint String
success Boolean?
status Int?
message String?
body String?
transitions RowWorkflowTransition[]
}
model AnalyticsSettings {
id String @id @default(cuid())
public Boolean @default(false)
ignorePages String
onlyPages String
}
model AnalyticsUniqueVisitor {
id String @id @default(cuid())
createdAt DateTime @default(now())
cookie String @unique
httpReferrer String?
browser String?
browserVersion String?
os String?
osVersion String?
device String?
source String?
medium String?
campaign String?
content String?
term String?
country String?
city String?
fromUrl String?
fromRoute String?
pageViews AnalyticsPageView[]
events AnalyticsEvent[]
}
model AnalyticsPageView {
id String @id @default(cuid())
createdAt DateTime @default(now())
uniqueVisitorId String
uniqueVisitor AnalyticsUniqueVisitor @relation(fields: [uniqueVisitorId], references: [id], onDelete: Cascade)
url String
route String?
}
model AnalyticsEvent {
id String @id @default(cuid())
createdAt DateTime @default(now())
uniqueVisitorId String
uniqueVisitor AnalyticsUniqueVisitor @relation(fields: [uniqueVisitorId], references: [id], onDelete: Cascade)
action String
category String?
label String?
value String?
url String?
route String?
}
// Application Demo: Contracts
model Contract {
id String @id @default(cuid())
rowId String @unique
name String
description String
file String
status Int
row Row @relation(fields: [rowId], references: [id], onDelete: Cascade)
activity ContractActivity[]
employees ContractEmployee[]
members ContractMember[]
}
model ContractMember {
id String @id @default(cuid())
contractId String
role Int
userId String
signDate DateTime?
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model ContractEmployee {
id String @id @default(cuid())
contractId String
rowId String
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
row Row @relation(fields: [rowId], references: [id], onDelete: Cascade)
}
model ContractActivity {
id String @id @default(cuid())
createdAt DateTime @default(now())
createdByUserId String
contractId String
type Int
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
createdByUser User @relation(fields: [createdByUserId], references: [id], onDelete: Cascade)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment