shellphone.app/db/schema.prisma

258 lines
6.6 KiB
Plaintext

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
datasource db {
provider = "postgres"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
// --------------------------------------
model Organization {
id String @id @default(uuid())
createdAt DateTime @default(now()) @db.Timestamptz
updatedAt DateTime @updatedAt @db.Timestamptz
encryptionKey String
twilioAccountSid String?
twilioAuthToken String? // TODO: encrypt it with encryptionKey
twilioApiKey String?
twilioApiSecret String? // TODO: encrypt it with encryptionKey
twimlAppSid String?
memberships Membership[]
phoneNumbers PhoneNumber[]
notificationSubscriptions NotificationSubscription[]
messages Message[]
phoneCalls PhoneCall[]
processingPhoneNumbers ProcessingPhoneNumber[]
subscriptions Subscription[]
@@unique([id, twilioAccountSid])
}
model Subscription {
createdAt DateTime @default(now()) @db.Timestamptz
updatedAt DateTime @updatedAt @db.Timestamptz
paddleSubscriptionId Int @id @unique
paddlePlanId Int
paddleCheckoutId String
status SubscriptionStatus
updateUrl String
cancelUrl String
currency String
unitPrice Int
nextBillDate DateTime @db.Date
lastEventTime DateTime @db.Timestamp
cancellationEffectiveDate DateTime? @db.Date
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
organizationId String
}
enum SubscriptionStatus {
active
trialing
past_due
paused
deleted
}
model Membership {
id String @id @default(uuid())
role MembershipRole
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
organizationId String
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String?
// When the user joins, we will clear out the name and email and set the user.
invitedName String?
invitedEmail String?
@@unique([organizationId, invitedEmail])
}
enum MembershipRole {
OWNER
ADMIN
USER
}
// The owners of the SaaS (you) can have a SUPERADMIN role to access all data
enum GlobalRole {
SUPERADMIN
CUSTOMER
}
model User {
id String @id @default(uuid())
createdAt DateTime @default(now()) @db.Timestamptz
updatedAt DateTime @updatedAt @db.Timestamptz
fullName String
email String @unique
hashedPassword String?
role GlobalRole @default(CUSTOMER)
memberships Membership[]
tokens Token[]
sessions Session[]
}
enum Role {
USER
ADMIN
}
model Session {
id String @id @default(uuid())
createdAt DateTime @default(now()) @db.Timestamptz
updatedAt DateTime @updatedAt @db.Timestamptz
expiresAt DateTime? @db.Timestamptz
handle String @unique
hashedSessionToken String?
antiCSRFToken String?
publicData String?
privateData String?
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String?
}
model Token {
id String @id @default(uuid())
createdAt DateTime @default(now()) @db.Timestamptz
updatedAt DateTime @updatedAt @db.Timestamptz
hashedToken String
type TokenType
expiresAt DateTime @db.Timestamptz
sentTo String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String
@@unique([hashedToken, type])
}
enum TokenType {
RESET_PASSWORD
}
model Message {
id String @id @default(uuid())
sentAt DateTime @db.Timestamptz
content String
from String
to String
direction Direction
status MessageStatus
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
organizationId String
phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id], onDelete: Cascade)
phoneNumberId String
@@unique([organizationId, phoneNumberId, id])
}
enum Direction {
Inbound
Outbound
}
enum MessageStatus {
Queued
Sending
Sent
Failed
Delivered
Undelivered
Receiving
Received
Accepted
Scheduled
Read
PartiallyDelivered
Canceled
Error
}
model PhoneCall {
id String @id
createdAt DateTime @default(now()) @db.Timestamptz
from String
to String
status CallStatus
direction Direction
duration String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
organizationId String
phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id], onDelete: Cascade)
phoneNumberId String
@@unique([organizationId, phoneNumberId, id])
}
enum CallStatus {
Queued
Ringing
InProgress
Completed
Busy
Failed
NoAnswer
Canceled
}
model PhoneNumber {
id String @id
createdAt DateTime @default(now()) @db.Timestamptz
number String
messages Message[]
phoneCalls PhoneCall[]
notificationSubscriptions NotificationSubscription[]
processingPhoneNumber ProcessingPhoneNumber?
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
organizationId String
@@unique([organizationId, id])
}
model ProcessingPhoneNumber {
createdAt DateTime @default(now()) @db.Timestamptz
hasFetchedMessages Boolean
hasFetchedCalls Boolean
phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id], onDelete: Cascade)
phoneNumberId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
organizationId String
@@id([organizationId, phoneNumberId])
}
model NotificationSubscription {
id String @id @default(uuid())
createdAt DateTime @default(now()) @db.Timestamptz
updatedAt DateTime @updatedAt @db.Timestamptz
endpoint String @unique
expirationTime Int?
keys_p256dh String
keys_auth String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
organizationId String
phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id], onDelete: Cascade)
phoneNumberId String
}