234 lines
8.5 KiB
Plaintext
234 lines
8.5 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
enum UserStatus {
|
|
invited
|
|
active
|
|
inactive
|
|
suspended
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(uuid())
|
|
name String
|
|
email String @unique
|
|
passwordHash String? @map("password_hash")
|
|
refreshTokenHash String? @map("refresh_token_hash")
|
|
refreshTokenExpiresAt DateTime? @map("refresh_token_expires_at")
|
|
sessionVersion Int @default(0) @map("session_version")
|
|
status UserStatus @default(invited)
|
|
roleId String? @map("role_id")
|
|
inviteTokenHash String? @map("invite_token_hash")
|
|
inviteTokenExpiresAt DateTime? @map("invite_token_expires_at")
|
|
passwordResetTokenHash String? @map("password_reset_token_hash")
|
|
passwordResetTokenExpiresAt DateTime? @map("password_reset_token_expires_at")
|
|
twoFactorEnabled Boolean @default(false) @map("two_factor_enabled")
|
|
twoFactorSecretEncrypted String? @map("two_factor_secret_encrypted")
|
|
twoFactorPendingSecretEncrypted String? @map("two_factor_pending_secret_encrypted")
|
|
twoFactorRecoveryCodesHashJson Json? @map("two_factor_recovery_codes_hash_json")
|
|
twoFactorConfirmedAt DateTime? @map("two_factor_confirmed_at")
|
|
emailVerifiedAt DateTime? @map("email_verified_at")
|
|
lastLoginAt DateTime? @map("last_login_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
role Role? @relation(fields: [roleId], references: [id])
|
|
|
|
@@index([passwordResetTokenHash])
|
|
@@map("users")
|
|
}
|
|
|
|
model Role {
|
|
id String @id @default(uuid())
|
|
key String @unique
|
|
name String
|
|
summary String
|
|
badge String
|
|
tone String
|
|
icon String
|
|
permissionsJson Json @map("permissions_json")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
users User[]
|
|
|
|
@@map("roles")
|
|
}
|
|
|
|
model Contact {
|
|
id String @id @default(uuid())
|
|
name String
|
|
phoneNumber String @unique @map("phone_number")
|
|
email String?
|
|
company String?
|
|
notes String?
|
|
isBlacklisted Boolean @default(false) @map("is_blacklisted")
|
|
assignedUserId String? @map("assigned_user_id")
|
|
assignedUserName String? @map("assigned_user_name")
|
|
assignedAt DateTime? @map("assigned_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
conversationMessages ConversationMessage[]
|
|
|
|
@@map("contacts")
|
|
}
|
|
|
|
model ConversationMessage {
|
|
id String @id @default(uuid())
|
|
contactId String @map("contact_id")
|
|
direction String
|
|
messageType String @default("text") @map("message_type")
|
|
source String @default("agent")
|
|
body String
|
|
status String @default("sent")
|
|
senderUserId String? @map("sender_user_id")
|
|
senderName String? @map("sender_name")
|
|
externalMessageId String? @map("external_message_id")
|
|
webhookEventId String? @unique @map("webhook_event_id")
|
|
occurredAt DateTime @default(now()) @map("occurred_at")
|
|
readAt DateTime? @map("read_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([contactId, occurredAt])
|
|
@@map("conversation_messages")
|
|
}
|
|
|
|
model WebhookEvent {
|
|
id String @id @default(uuid())
|
|
provider String
|
|
eventId String @unique @map("event_id")
|
|
eventType String @map("event_type")
|
|
senderPhone String? @map("sender_phone")
|
|
recipientPhone String? @map("recipient_phone")
|
|
externalMessageId String? @map("external_message_id")
|
|
eventTimestamp DateTime @map("event_timestamp")
|
|
payloadJson Json @map("payload_json")
|
|
verified Boolean @default(false)
|
|
processingStatus String @default("received") @map("processing_status")
|
|
processingNotes String? @map("processing_notes")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@map("webhook_events")
|
|
}
|
|
|
|
model IntegrationConfig {
|
|
id String @id @default(uuid())
|
|
configKey String @unique @map("config_key")
|
|
provider String
|
|
isEnabled Boolean @default(true) @map("is_enabled")
|
|
configJson Json @map("config_json")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@map("integration_configs")
|
|
}
|
|
|
|
model Job {
|
|
id String @id @default(uuid())
|
|
queueName String @map("queue_name")
|
|
jobType String @map("job_type")
|
|
status String @default("queued")
|
|
payloadJson Json @map("payload_json")
|
|
attempts Int @default(0)
|
|
maxAttempts Int @default(3) @map("max_attempts")
|
|
availableAt DateTime @default(now()) @map("available_at")
|
|
processedAt DateTime? @map("processed_at")
|
|
failedAt DateTime? @map("failed_at")
|
|
errorMessage String? @map("error_message")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@index([queueName, status, availableAt])
|
|
@@map("jobs")
|
|
}
|
|
|
|
model AuditLog {
|
|
id String @id @default(uuid())
|
|
actorUserId String? @map("actor_user_id")
|
|
actorName String @map("actor_name")
|
|
actorEmail String? @map("actor_email")
|
|
actionType String @map("action_type")
|
|
module String
|
|
ipAddress String? @map("ip_address")
|
|
severity String @default("default")
|
|
details String
|
|
metadataJson Json? @map("metadata_json")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
@@index([createdAt])
|
|
@@index([actorName])
|
|
@@index([actionType])
|
|
@@index([module])
|
|
@@map("audit_logs")
|
|
}
|
|
|
|
model MessageTemplate {
|
|
id String @id @default(uuid())
|
|
name String @unique
|
|
category String
|
|
status String
|
|
language String
|
|
headerText String? @map("header_text")
|
|
bodyText String @map("body_text")
|
|
footerText String? @map("footer_text")
|
|
buttonsJson Json? @map("buttons_json")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@index([status, category, language])
|
|
@@map("message_templates")
|
|
}
|
|
|
|
model Campaign {
|
|
id String @id @default(uuid())
|
|
code String @unique
|
|
name String
|
|
audienceLabel String @map("audience_label")
|
|
audienceGroup String @map("audience_group")
|
|
status String
|
|
totalRecipients Int @default(0) @map("total_recipients")
|
|
deliveredCount Int @default(0) @map("delivered_count")
|
|
readCount Int @default(0) @map("read_count")
|
|
failedCount Int @default(0) @map("failed_count")
|
|
deliveryRate Float? @map("delivery_rate")
|
|
readRate Float? @map("read_rate")
|
|
sentAt DateTime? @map("sent_at")
|
|
scheduledAt DateTime? @map("scheduled_at")
|
|
templateName String? @map("template_name")
|
|
language String?
|
|
messageTitle String? @map("message_title")
|
|
messageBody String? @map("message_body")
|
|
primaryButton String? @map("primary_button")
|
|
secondaryButton String? @map("secondary_button")
|
|
bannerImageUrl String? @map("banner_image_url")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
recipients CampaignRecipient[]
|
|
|
|
@@map("campaigns")
|
|
}
|
|
|
|
model CampaignRecipient {
|
|
id String @id @default(uuid())
|
|
campaignId String @map("campaign_id")
|
|
phoneNumber String @map("phone_number")
|
|
status String
|
|
sentAt DateTime? @map("sent_at")
|
|
errorReason String? @map("error_reason")
|
|
deviceOs String? @map("device_os")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
campaign Campaign @relation(fields: [campaignId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([campaignId, status])
|
|
@@index([campaignId, sentAt])
|
|
@@map("campaign_recipients")
|
|
}
|