360 lines
7.3 KiB
Plaintext
360 lines
7.3 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(uuid())
|
|
|
|
// Credentials
|
|
email String @unique
|
|
password String?
|
|
|
|
// Relations
|
|
memberships ProjectMembership[]
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@map("users")
|
|
}
|
|
|
|
model Project {
|
|
id String @id @default(uuid())
|
|
|
|
// Details
|
|
name String
|
|
url String
|
|
|
|
// Verified domain
|
|
verified Boolean @default(false)
|
|
email String?
|
|
from String?
|
|
|
|
// API access
|
|
public String @unique
|
|
secret String @unique
|
|
|
|
// Relations
|
|
memberships ProjectMembership[]
|
|
contacts Contact[]
|
|
campaigns Campaign[]
|
|
actions Action[]
|
|
events Event[]
|
|
templates Template[]
|
|
emails Email[]
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@map("projects")
|
|
}
|
|
|
|
// Table to maintain many-to-many relationship between Account and Project
|
|
model ProjectMembership {
|
|
role Role @default(MEMBER)
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
userId String
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
projectId String
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@id(fields: [userId, projectId])
|
|
@@map("projectmemberhips")
|
|
}
|
|
|
|
model Event {
|
|
id String @id @default(uuid())
|
|
|
|
// Details
|
|
name String
|
|
|
|
// Relations
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
projectId String
|
|
|
|
template Template? @relation(fields: [templateId], references: [id], onDelete: Cascade)
|
|
templateId String?
|
|
|
|
campaign Campaign? @relation(fields: [campaignId], references: [id], onDelete: Cascade)
|
|
campaignId String?
|
|
|
|
actions Action[] @relation("ActionToEvent")
|
|
notActions Action[] @relation("ActionToNotEvent")
|
|
triggers Trigger[]
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index(fields: [projectId, templateId, campaignId])
|
|
@@index([projectId])
|
|
@@index([templateId])
|
|
@@index([campaignId])
|
|
@@map("events")
|
|
}
|
|
|
|
model Template {
|
|
id String @id @default(uuid())
|
|
|
|
// Details
|
|
subject String
|
|
body String
|
|
email String?
|
|
from String?
|
|
|
|
type TemplateType
|
|
style TemplateStyle
|
|
|
|
// Relations
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
projectId String
|
|
events Event[]
|
|
actions Action[]
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index(fields: [projectId])
|
|
@@map("templates")
|
|
}
|
|
|
|
model Action {
|
|
id String @id @default(uuid())
|
|
|
|
// Details
|
|
name String
|
|
runOnce Boolean @default(false)
|
|
delay Int @default(0)
|
|
|
|
// Relations
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
projectId String
|
|
|
|
template Template @relation(fields: [templateId], references: [id])
|
|
templateId String
|
|
|
|
events Event[] @relation("ActionToEvent")
|
|
notevents Event[] @relation("ActionToNotEvent")
|
|
|
|
triggers Trigger[]
|
|
emails Email[]
|
|
tasks Task[]
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index(fields: [projectId, templateId])
|
|
@@index([projectId])
|
|
@@index([templateId])
|
|
@@map("actions")
|
|
}
|
|
|
|
model Campaign {
|
|
id String @id @default(uuid())
|
|
|
|
subject String
|
|
body String
|
|
email String?
|
|
from String?
|
|
|
|
status CampaignStatus @default(DRAFT)
|
|
delivered DateTime?
|
|
|
|
style TemplateStyle
|
|
// Relations
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
projectId String
|
|
emails Email[]
|
|
tasks Task[]
|
|
recipients Contact[]
|
|
events Event[]
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index(fields: [projectId])
|
|
@@map("campaigns")
|
|
}
|
|
|
|
model Trigger {
|
|
id String @id @default(uuid())
|
|
|
|
// Relations
|
|
contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
|
|
contactId String
|
|
|
|
event Event? @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
eventId String?
|
|
action Action? @relation(fields: [actionId], references: [id], onDelete: Cascade)
|
|
actionId String?
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index(fields: [contactId, eventId, actionId, createdAt])
|
|
@@index([contactId])
|
|
@@index([eventId])
|
|
@@index([actionId])
|
|
@@index([createdAt])
|
|
@@map("triggers")
|
|
}
|
|
|
|
model Contact {
|
|
id String @id @default(uuid())
|
|
|
|
// Details
|
|
email String
|
|
subscribed Boolean @default(true)
|
|
data String?
|
|
|
|
// Relations
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
projectId String
|
|
|
|
emails Email[]
|
|
triggers Trigger[]
|
|
tasks Task[]
|
|
campaigns Campaign[]
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index(fields: [projectId, createdAt])
|
|
@@index([projectId])
|
|
@@index([email])
|
|
@@index([createdAt])
|
|
@@map("contacts")
|
|
}
|
|
|
|
model Email {
|
|
id String @id @default(uuid())
|
|
|
|
messageId String @unique
|
|
subject String?
|
|
body String?
|
|
status EmailStatus @default(SENT)
|
|
|
|
// Relations
|
|
project Project? @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
projectId String?
|
|
|
|
action Action? @relation(fields: [actionId], references: [id], onDelete: Cascade)
|
|
actionId String?
|
|
|
|
campaign Campaign? @relation(fields: [campaignId], references: [id], onDelete: Cascade)
|
|
campaignId String?
|
|
|
|
contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
|
|
contactId String
|
|
|
|
clicks Click[]
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index(fields: [projectId, actionId, campaignId, contactId, createdAt])
|
|
@@index([projectId])
|
|
@@index([actionId])
|
|
@@index([campaignId])
|
|
@@index([contactId])
|
|
@@index([createdAt])
|
|
@@map("emails")
|
|
}
|
|
|
|
model Click {
|
|
id String @id @default(uuid())
|
|
|
|
link String
|
|
|
|
// Relations
|
|
email Email @relation(fields: [emailId], references: [id], onDelete: Cascade)
|
|
emailId String
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([emailId, createdAt])
|
|
@@index([createdAt])
|
|
@@index([link])
|
|
@@index([emailId])
|
|
@@map("clicks")
|
|
}
|
|
|
|
model Task {
|
|
id String @id @default(uuid())
|
|
|
|
// Details
|
|
runBy DateTime @default(now())
|
|
|
|
// Relations
|
|
action Action? @relation(fields: [actionId], references: [id], onDelete: Cascade)
|
|
actionId String?
|
|
|
|
campaign Campaign? @relation(fields: [campaignId], references: [id], onDelete: Cascade)
|
|
campaignId String?
|
|
|
|
contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
|
|
contactId String
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([runBy, createdAt])
|
|
@@index([actionId])
|
|
@@index([campaignId])
|
|
@@index([contactId])
|
|
@@index([createdAt])
|
|
@@index([runBy])
|
|
@@map("tasks")
|
|
}
|
|
|
|
enum TemplateType {
|
|
MARKETING
|
|
TRANSACTIONAL
|
|
}
|
|
|
|
enum TemplateStyle {
|
|
PLUNK
|
|
HTML
|
|
}
|
|
|
|
enum EmailStatus {
|
|
SENT
|
|
DELIVERED
|
|
BOUNCED
|
|
OPENED
|
|
COMPLAINT
|
|
}
|
|
|
|
enum CampaignStatus {
|
|
DRAFT
|
|
SCHEDULED
|
|
DELIVERED
|
|
}
|
|
|
|
enum Role {
|
|
OWNER
|
|
ADMIN
|
|
MEMBER
|
|
}
|