Files
BizOne-portal/prisma/schema.prisma

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")
}