1388 lines
43 KiB
Plaintext
1388 lines
43 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
}
|
|
|
|
model Tenant {
|
|
id String @id @default(cuid())
|
|
name String
|
|
code String @unique
|
|
status String @default("active")
|
|
certificationStatus String @default("approved")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
users User[]
|
|
enterpriseCertifications EnterpriseCertification[]
|
|
operationLogs OperationLog[]
|
|
fileObjects FileObject[]
|
|
enterpriseBlacklists EnterpriseBlacklist[]
|
|
accounts TenantAccount[]
|
|
accountTransactions AccountTransaction[]
|
|
rechargeOrders RechargeOrder[]
|
|
smsBillingRecords SmsBillingRecord[]
|
|
smsApplications SmsApplication[]
|
|
smsSignatures SmsSignature[]
|
|
smsDrainageInfos SmsDrainageInfo[]
|
|
smsTemplates SmsTemplate[]
|
|
auditRecords AuditRecord[]
|
|
riskRules RiskRule[]
|
|
smsSendTasks SmsSendTask[]
|
|
riskHitRecords RiskHitRecord[]
|
|
smsBatchTasks SmsBatchTask[]
|
|
smsMessageRecords SmsMessageRecord[]
|
|
smsApiRequests SmsApiRequest[]
|
|
smsSubmitRecords SmsSubmitRecord[]
|
|
smsReceiptRecords SmsReceiptRecord[]
|
|
smsMessageSegmentAudits SmsMessageSegmentAudit[]
|
|
smsUplinkMessages SmsUplinkMessage[]
|
|
smsUplinkMatchCandidates SmsUplinkMatchCandidate[]
|
|
cmppDownstreamDeliveries CmppDownstreamDelivery[]
|
|
cmppDownstreamConnections CmppDownstreamConnection[]
|
|
cmppConnectionStates CmppConnectionState[]
|
|
gatewayDownstreamRecoveryStatuses GatewayDownstreamRecoveryStatus[]
|
|
gatewaySubmitDeadLetters GatewaySubmitDeadLetter[]
|
|
}
|
|
|
|
model EnterpriseCertification {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
companyName String
|
|
licenseNo String?
|
|
contactName String?
|
|
contactPhone String?
|
|
materials Json?
|
|
status String @default("pending")
|
|
rejectReason String?
|
|
reviewerId String?
|
|
submittedAt DateTime @default(now())
|
|
reviewedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
|
|
@@index([tenantId, status, createdAt])
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
username String @unique
|
|
email String? @unique
|
|
phone String? @unique
|
|
displayName String
|
|
passwordHash String
|
|
status String @default("active")
|
|
sessionVersion Int @default(0)
|
|
failedLoginCount Int @default(0)
|
|
lockedUntil DateTime?
|
|
lastLoginAt DateTime?
|
|
deletedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
roles UserRole[]
|
|
operationLogs OperationLog[]
|
|
auditRecords AuditRecord[]
|
|
createdSmsSendTasks SmsSendTask[] @relation("SmsSendTaskCreator")
|
|
reviewedSmsSendTasks SmsSendTask[] @relation("SmsSendTaskReviewer")
|
|
createdSmsBatchTasks SmsBatchTask[] @relation("SmsBatchTaskCreator")
|
|
}
|
|
|
|
model Role {
|
|
id String @id @default(cuid())
|
|
code String @unique
|
|
name String
|
|
scope String @default("platform")
|
|
description String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
users UserRole[]
|
|
permissions RolePermission[]
|
|
}
|
|
|
|
model Permission {
|
|
id String @id @default(cuid())
|
|
code String @unique
|
|
name String
|
|
description String?
|
|
createdAt DateTime @default(now())
|
|
|
|
roles RolePermission[]
|
|
}
|
|
|
|
model UserRole {
|
|
userId String
|
|
roleId String
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([userId, roleId])
|
|
}
|
|
|
|
model RolePermission {
|
|
roleId String
|
|
permissionId String
|
|
|
|
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
|
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([roleId, permissionId])
|
|
}
|
|
|
|
model OperationLog {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
userId String?
|
|
action String
|
|
resource String
|
|
resourceId String?
|
|
ipAddress String?
|
|
userAgent String?
|
|
detail Json?
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
user User? @relation(fields: [userId], references: [id])
|
|
|
|
@@index([tenantId, createdAt])
|
|
@@index([userId, createdAt])
|
|
@@index([createdAt])
|
|
@@index([resource, createdAt])
|
|
}
|
|
|
|
model OperationLogArchive {
|
|
originalId String @id
|
|
tenantId String?
|
|
userId String?
|
|
action String
|
|
resource String
|
|
resourceId String?
|
|
ipAddress String?
|
|
userAgent String?
|
|
detail Json?
|
|
createdAt DateTime
|
|
archiveMonth String
|
|
archivedAt DateTime @default(now())
|
|
|
|
@@index([tenantId, createdAt])
|
|
@@index([userId, createdAt])
|
|
@@index([createdAt])
|
|
@@index([resource, createdAt])
|
|
@@index([archiveMonth])
|
|
}
|
|
|
|
model FileObject {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
bucket String
|
|
objectKey String @unique
|
|
fileName String
|
|
contentType String
|
|
sizeBytes BigInt
|
|
checksum String?
|
|
purpose String
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
}
|
|
|
|
model PhoneSegment {
|
|
id String @id @default(cuid())
|
|
prefix String @unique
|
|
carrier String
|
|
province String?
|
|
city String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model PhoneCarrierRule {
|
|
id String @id @default(cuid())
|
|
carrier String
|
|
pattern String
|
|
priority Int @default(100)
|
|
status String @default("active")
|
|
remark String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([status, priority])
|
|
}
|
|
|
|
model SensitiveWord {
|
|
id String @id @default(cuid())
|
|
word String @unique
|
|
level String @default("block")
|
|
status String @default("active")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model EnterpriseBlacklist {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
applicationId String
|
|
phoneNumber String
|
|
reason String?
|
|
status String @default("active")
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication @relation(fields: [applicationId], references: [id])
|
|
|
|
@@unique([applicationId, phoneNumber])
|
|
}
|
|
|
|
model GlobalBlacklist {
|
|
id String @id @default(cuid())
|
|
phoneNumber String @unique
|
|
reason String?
|
|
status String @default("active")
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model DrainageField {
|
|
id String @id @default(cuid())
|
|
code String @unique
|
|
name String
|
|
fieldType String
|
|
required Boolean @default(false)
|
|
status String @default("active")
|
|
description String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
channelReportFields ChannelReportField[]
|
|
commonReportFields CommonReportField[]
|
|
}
|
|
|
|
model TenantAccount {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
balanceCents Int @default(0)
|
|
creditCents Int @default(0)
|
|
status String @default("active")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
|
|
@@unique([tenantId])
|
|
}
|
|
|
|
model AccountTransaction {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
transactionType String
|
|
amountCents Int @default(0)
|
|
balanceAfter Int @default(0)
|
|
relatedType String?
|
|
relatedId String?
|
|
remark String?
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
|
|
@@index([tenantId, createdAt])
|
|
@@index([relatedType, relatedId])
|
|
}
|
|
|
|
model BillingRule {
|
|
id String @id @default(cuid())
|
|
code String @unique
|
|
name String
|
|
chargeBasis String @default("submit_success")
|
|
unitPrice Int
|
|
status String @default("active")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model RechargeOrder {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
orderNo String @unique
|
|
amountCents Int
|
|
status String @default("created")
|
|
payMethod String?
|
|
paidAt DateTime?
|
|
operatorId String?
|
|
remark String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
|
|
@@index([tenantId, createdAt])
|
|
}
|
|
|
|
model SmsBillingRecord {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
applicationId String?
|
|
taskId String?
|
|
messageId String?
|
|
phoneNumber String?
|
|
contentLength Int
|
|
billingUnits Int
|
|
unitPrice Int
|
|
amountCents Int
|
|
billingStatus String @default("estimated")
|
|
transactionId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
|
|
@@index([tenantId, createdAt])
|
|
@@index([taskId])
|
|
@@index([messageId])
|
|
}
|
|
|
|
model SmsApplication {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
scene String?
|
|
callbackUrl String?
|
|
cmppAccount String @unique
|
|
cmppEnterpriseCode String
|
|
secretHash String
|
|
interfaceEnabled Boolean @default(true)
|
|
interfaceType String @default("cmpp20")
|
|
cmppMaxConnections Int @default(1)
|
|
cmppWindowSize Int @default(16)
|
|
dailyLimit Int?
|
|
customerUnitPrice Int @default(0)
|
|
queuePriority String @default("normal")
|
|
maxPhonesPerTask Int @default(1000000)
|
|
templateMismatchMode String @default("reject")
|
|
downstreamReceiptRetryEnabled Boolean @default(true)
|
|
downstreamUplinkRetryEnabled Boolean @default(true)
|
|
status String @default("active")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
ipAllowlist SmsApplicationIpAllowlist[]
|
|
signatures SmsSignature[]
|
|
drainageInfos SmsDrainageInfo[]
|
|
templates SmsTemplate[]
|
|
enterpriseBlacklists EnterpriseBlacklist[]
|
|
sendTasks SmsSendTask[]
|
|
batchTasks SmsBatchTask[]
|
|
messageRecords SmsMessageRecord[]
|
|
uplinkMessages SmsUplinkMessage[]
|
|
uplinkMatchCandidates SmsUplinkMatchCandidate[]
|
|
downstreamDeliveries CmppDownstreamDelivery[]
|
|
downstreamConnections CmppDownstreamConnection[]
|
|
connectionStates CmppConnectionState[]
|
|
gatewayDownstreamRecoveryStatuses GatewayDownstreamRecoveryStatus[]
|
|
gatewaySubmitDeadLetters GatewaySubmitDeadLetter[]
|
|
|
|
@@index([tenantId, status])
|
|
}
|
|
|
|
model SmsApplicationIpAllowlist {
|
|
id String @id @default(cuid())
|
|
applicationId String
|
|
ipCidr String
|
|
remark String?
|
|
createdAt DateTime @default(now())
|
|
|
|
application SmsApplication @relation(fields: [applicationId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([applicationId, ipCidr])
|
|
}
|
|
|
|
model SmsSignature {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
applicationId String?
|
|
name String
|
|
purpose String?
|
|
drainageInfo Json?
|
|
auditStatus String @default("draft")
|
|
reportStatus String @default("waiting_material")
|
|
rejectReason String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication? @relation(fields: [applicationId], references: [id])
|
|
materials SignatureMaterial[]
|
|
templates SmsTemplate[]
|
|
reportMaterials SignatureReportMaterial[]
|
|
drainageReportMaterials DrainageReportMaterial[]
|
|
drainageItems SmsDrainageInfo[]
|
|
reportTasks ChannelSignatureReportTask[]
|
|
messageRecords SmsMessageRecord[]
|
|
|
|
@@index([tenantId, auditStatus])
|
|
@@index([tenantId, reportStatus])
|
|
}
|
|
|
|
model SmsDrainageInfo {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
signatureId String
|
|
applicationId String?
|
|
siteName String
|
|
url String
|
|
remark String?
|
|
reportValues Json?
|
|
auditStatus String @default("pending")
|
|
rejectReason String?
|
|
submittedAt DateTime @default(now())
|
|
reviewedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
signature SmsSignature @relation(fields: [signatureId], references: [id], onDelete: Cascade)
|
|
application SmsApplication? @relation(fields: [applicationId], references: [id])
|
|
reportTasks ChannelSignatureReportTask[]
|
|
messageRecords SmsMessageRecord[]
|
|
|
|
@@index([tenantId, auditStatus, updatedAt])
|
|
@@index([signatureId, auditStatus])
|
|
@@index([applicationId])
|
|
}
|
|
|
|
model SignatureMaterial {
|
|
id String @id @default(cuid())
|
|
signatureId String
|
|
fileObjectId String?
|
|
materialType String
|
|
title String
|
|
description String?
|
|
createdAt DateTime @default(now())
|
|
|
|
signature SmsSignature @relation(fields: [signatureId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model SmsTemplate {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
applicationId String
|
|
signatureId String?
|
|
name String
|
|
content String
|
|
category String?
|
|
auditStatus String @default("draft")
|
|
rejectReason String?
|
|
billingUnits Int @default(1)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication @relation(fields: [applicationId], references: [id])
|
|
signature SmsSignature? @relation(fields: [signatureId], references: [id])
|
|
variables TemplateVariable[]
|
|
sendTasks SmsSendTask[]
|
|
batchTasks SmsBatchTask[]
|
|
messageRecords SmsMessageRecord[]
|
|
|
|
@@index([tenantId, auditStatus])
|
|
@@index([applicationId])
|
|
}
|
|
|
|
model TemplateVariable {
|
|
id String @id @default(cuid())
|
|
templateId String
|
|
name String
|
|
example String?
|
|
required Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
|
|
template SmsTemplate @relation(fields: [templateId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([templateId, name])
|
|
}
|
|
|
|
model AuditRecord {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
targetType String
|
|
targetId String
|
|
action String
|
|
statusBefore String?
|
|
statusAfter String
|
|
reason String?
|
|
reviewerId String?
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
reviewer User? @relation(fields: [reviewerId], references: [id])
|
|
|
|
@@index([targetType, targetId])
|
|
@@index([tenantId, createdAt])
|
|
}
|
|
|
|
model SmsChannel {
|
|
id String @id @default(cuid())
|
|
code String @unique
|
|
name String
|
|
carrier String?
|
|
sendRegion String @default("全国")
|
|
protocol String @default("CMPP")
|
|
gatewayHost String
|
|
gatewayPort Int
|
|
enterpriseCode String?
|
|
account String
|
|
passwordCipher String
|
|
srcId String
|
|
cmppVersion String @default("2.0")
|
|
rateLimitPerSecond Int @default(100)
|
|
unitPrice Int @default(0)
|
|
status String @default("active")
|
|
config Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
groupItems SmsChannelGroupItem[]
|
|
routeRules ChannelRouteRule[]
|
|
healthMetrics ChannelHealthMetric[]
|
|
reportFields ChannelReportField[]
|
|
drainageReportMaterials DrainageReportMaterial[]
|
|
reportTasks ChannelSignatureReportTask[]
|
|
reportRecords ChannelSignatureReportRecord[]
|
|
messageRecords SmsMessageRecord[]
|
|
submitSessions CmppSubmitSession[]
|
|
submitRecords SmsSubmitRecord[]
|
|
receiptRecords SmsReceiptRecord[]
|
|
segmentAudits SmsMessageSegmentAudit[]
|
|
uplinkMessages SmsUplinkMessage[]
|
|
connectionStates CmppConnectionState[]
|
|
gatewaySubmitDeadLetters GatewaySubmitDeadLetter[]
|
|
|
|
@@index([status])
|
|
}
|
|
|
|
model CmppConnectionState {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
applicationId String?
|
|
channelId String
|
|
connectionId String
|
|
status String @default("disconnected")
|
|
desiredConnections Int @default(1)
|
|
currentConnections Int @default(0)
|
|
lastConnectedAt DateTime?
|
|
lastDisconnectedAt DateTime?
|
|
lastHeartbeatAt DateTime?
|
|
reconnectCount Int @default(0)
|
|
lastError String?
|
|
updatedAt DateTime @updatedAt
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication? @relation(fields: [applicationId], references: [id])
|
|
channel SmsChannel @relation(fields: [channelId], references: [id])
|
|
|
|
@@unique([applicationId, channelId, connectionId])
|
|
@@index([tenantId, status])
|
|
@@index([applicationId, status])
|
|
@@index([channelId, status])
|
|
}
|
|
|
|
model CmppDownstreamConnection {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
applicationId String
|
|
account String
|
|
enterpriseCode String
|
|
connectionId String @unique
|
|
remoteIp String?
|
|
protocol String?
|
|
status String @default("connected")
|
|
connectedAt DateTime @default(now())
|
|
lastHeartbeatAt DateTime?
|
|
lastSubmitAt DateTime?
|
|
lastDeliverAt DateTime?
|
|
disconnectedAt DateTime?
|
|
lastError String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication @relation(fields: [applicationId], references: [id])
|
|
|
|
@@index([applicationId, status, updatedAt])
|
|
@@index([tenantId, status, updatedAt])
|
|
@@index([account, status])
|
|
}
|
|
|
|
model SmsChannelGroup {
|
|
id String @id @default(cuid())
|
|
code String @unique
|
|
name String
|
|
description String?
|
|
carrier String @default("mobile")
|
|
status String @default("active")
|
|
retryEnabled Boolean @default(true)
|
|
retryTimeLimitHours Int @default(72)
|
|
retryTimeLimitMinutes Int @default(720)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
items SmsChannelGroupItem[]
|
|
routeRules ChannelRouteRule[]
|
|
}
|
|
|
|
model SmsChannelGroupItem {
|
|
id String @id @default(cuid())
|
|
groupId String
|
|
channelId String
|
|
carrier String?
|
|
province String?
|
|
priority Int @default(100)
|
|
weight Int @default(1)
|
|
isBackup Boolean @default(false)
|
|
rateLimitPerSecond Int?
|
|
createdAt DateTime @default(now())
|
|
|
|
group SmsChannelGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
|
channel SmsChannel @relation(fields: [channelId], references: [id])
|
|
|
|
@@unique([groupId, channelId, carrier, province])
|
|
@@unique([groupId, province])
|
|
@@index([channelId])
|
|
}
|
|
|
|
model ChannelRouteRule {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
applicationId String?
|
|
groupId String
|
|
channelId String?
|
|
carrier String?
|
|
province String?
|
|
priority Int @default(100)
|
|
status String @default("active")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
group SmsChannelGroup @relation(fields: [groupId], references: [id])
|
|
channel SmsChannel? @relation(fields: [channelId], references: [id])
|
|
|
|
@@index([tenantId, applicationId, status])
|
|
@@index([groupId, priority])
|
|
}
|
|
|
|
model ChannelHealthMetric {
|
|
id String @id @default(cuid())
|
|
channelId String
|
|
submitTotal Int @default(0)
|
|
submitSuccess Int @default(0)
|
|
submitFailed Int @default(0)
|
|
receiptSuccess Int @default(0)
|
|
receiptFailed Int @default(0)
|
|
unknownTotal Int @default(0)
|
|
windowStart DateTime
|
|
windowEnd DateTime
|
|
createdAt DateTime @default(now())
|
|
|
|
channel SmsChannel @relation(fields: [channelId], references: [id])
|
|
|
|
@@index([channelId, windowStart])
|
|
}
|
|
|
|
model ChannelReportField {
|
|
id String @id @default(cuid())
|
|
channelId String
|
|
drainageFieldId String?
|
|
reportType String @default("both")
|
|
code String
|
|
name String
|
|
fieldType String
|
|
required Boolean @default(false)
|
|
description String?
|
|
sortOrder Int @default(100)
|
|
status String @default("active")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
channel SmsChannel @relation(fields: [channelId], references: [id], onDelete: Cascade)
|
|
drainageField DrainageField? @relation(fields: [drainageFieldId], references: [id])
|
|
|
|
@@unique([channelId, code])
|
|
@@index([drainageFieldId, reportType])
|
|
}
|
|
|
|
model CommonReportField {
|
|
id String @id @default(cuid())
|
|
drainageFieldId String
|
|
reportType String
|
|
required Boolean @default(false)
|
|
sortOrder Int @default(100)
|
|
status String @default("active")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
drainageField DrainageField @relation(fields: [drainageFieldId], references: [id], onDelete: Restrict)
|
|
|
|
@@unique([drainageFieldId, reportType])
|
|
@@index([reportType, status, sortOrder])
|
|
}
|
|
|
|
model SignatureReportMaterial {
|
|
id String @id @default(cuid())
|
|
signatureId String
|
|
channelId String
|
|
fieldCode String
|
|
fieldValue String?
|
|
fileObjectId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
signature SmsSignature @relation(fields: [signatureId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([signatureId, channelId, fieldCode])
|
|
@@index([channelId])
|
|
}
|
|
|
|
model DrainageReportMaterial {
|
|
id String @id @default(cuid())
|
|
signatureId String
|
|
drainageItemId String
|
|
channelId String
|
|
fieldCode String
|
|
fieldValue String?
|
|
fileObjectId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
signature SmsSignature @relation(fields: [signatureId], references: [id], onDelete: Cascade)
|
|
channel SmsChannel @relation(fields: [channelId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([signatureId, drainageItemId, channelId, fieldCode])
|
|
@@index([channelId, fieldCode])
|
|
}
|
|
|
|
model ChannelSignatureReportTask {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
signatureId String
|
|
channelId String
|
|
reportType String @default("signature")
|
|
drainageItemId String?
|
|
status String @default("pending")
|
|
reason String?
|
|
createdById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
signature SmsSignature @relation(fields: [signatureId], references: [id])
|
|
channel SmsChannel @relation(fields: [channelId], references: [id])
|
|
drainageInfo SmsDrainageInfo? @relation(fields: [drainageItemId], references: [id])
|
|
records ChannelSignatureReportRecord[]
|
|
exportFiles ReportExportFile[]
|
|
receiptImports ReportReceiptImport[]
|
|
|
|
@@index([tenantId, status])
|
|
@@index([signatureId, channelId])
|
|
@@index([signatureId, drainageItemId, channelId])
|
|
@@index([reportType, status])
|
|
}
|
|
|
|
model ChannelSignatureReportRecord {
|
|
id String @id @default(cuid())
|
|
taskId String
|
|
channelId String
|
|
action String
|
|
statusBefore String?
|
|
statusAfter String
|
|
reason String?
|
|
operatorId String?
|
|
sourceEntry String @default("system")
|
|
createdAt DateTime @default(now())
|
|
|
|
task ChannelSignatureReportTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
|
channel SmsChannel @relation(fields: [channelId], references: [id])
|
|
|
|
@@index([taskId, createdAt])
|
|
@@index([channelId, createdAt])
|
|
}
|
|
|
|
model ReportExportFile {
|
|
id String @id @default(cuid())
|
|
taskId String
|
|
fileObjectId String?
|
|
fileName String
|
|
rowCount Int @default(0)
|
|
status String @default("generated")
|
|
createdAt DateTime @default(now())
|
|
|
|
task ChannelSignatureReportTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model ReportReceiptImport {
|
|
id String @id @default(cuid())
|
|
taskId String
|
|
fileObjectId String?
|
|
fileName String
|
|
rowCount Int @default(0)
|
|
successCount Int @default(0)
|
|
failedCount Int @default(0)
|
|
status String @default("imported")
|
|
result Json?
|
|
createdAt DateTime @default(now())
|
|
|
|
task ChannelSignatureReportTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model RiskRule {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
code String
|
|
name String
|
|
description String?
|
|
metric String
|
|
thresholdValue Float
|
|
action String @default("manual_review")
|
|
status String @default("active")
|
|
priority Int @default(100)
|
|
config Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
hits RiskHitRecord[]
|
|
|
|
@@unique([tenantId, code])
|
|
@@index([tenantId, status, priority])
|
|
}
|
|
|
|
model SmsSendTask {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
applicationId String?
|
|
templateId String?
|
|
taskNo String @unique
|
|
sourceType String @default("risk")
|
|
aggregationKey String? @unique
|
|
contentHash String?
|
|
windowStartedAt DateTime?
|
|
windowEndsAt DateTime?
|
|
content String
|
|
category String?
|
|
phoneTotal Int
|
|
uniquePhoneTotal Int
|
|
duplicateRatio Float @default(0)
|
|
illegalRatio Float @default(0)
|
|
blacklistHitRatio Float @default(0)
|
|
variableIssues Json?
|
|
status String @default("created")
|
|
riskDecision String @default("allow")
|
|
reviewReason String?
|
|
rejectReason String?
|
|
createdById String?
|
|
reviewedById String?
|
|
reviewedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication? @relation(fields: [applicationId], references: [id])
|
|
template SmsTemplate? @relation(fields: [templateId], references: [id])
|
|
createdBy User? @relation("SmsSendTaskCreator", fields: [createdById], references: [id])
|
|
reviewedBy User? @relation("SmsSendTaskReviewer", fields: [reviewedById], references: [id])
|
|
riskHits RiskHitRecord[]
|
|
messageRecords SmsMessageRecord[]
|
|
|
|
@@index([tenantId, status, createdAt])
|
|
@@index([applicationId, createdAt])
|
|
}
|
|
|
|
model RiskHitRecord {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
taskId String
|
|
ruleId String?
|
|
ruleCode String
|
|
ruleName String
|
|
thresholdValue Float
|
|
actualValue Float
|
|
action String
|
|
reason String
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
task SmsSendTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
|
rule RiskRule? @relation(fields: [ruleId], references: [id])
|
|
|
|
@@index([tenantId, createdAt])
|
|
@@index([taskId])
|
|
@@index([ruleCode])
|
|
}
|
|
|
|
model SmsBatchTask {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
applicationId String?
|
|
templateId String?
|
|
taskNo String @unique
|
|
sourceType String @default("client")
|
|
content String
|
|
category String?
|
|
phoneTotal Int
|
|
status String @default("created")
|
|
riskTaskId String?
|
|
auditStatus String @default("approved")
|
|
reviewReason String?
|
|
rejectReason String?
|
|
progressTotal Int @default(0)
|
|
submittedTotal Int @default(0)
|
|
successTotal Int @default(0)
|
|
failedTotal Int @default(0)
|
|
unknownTotal Int @default(0)
|
|
timeoutTotal Int @default(0)
|
|
scheduledAt DateTime?
|
|
canceledAt DateTime?
|
|
createdById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication? @relation(fields: [applicationId], references: [id])
|
|
template SmsTemplate? @relation(fields: [templateId], references: [id])
|
|
createdBy User? @relation("SmsBatchTaskCreator", fields: [createdById], references: [id])
|
|
apiRequests SmsApiRequest[]
|
|
messages SmsMessageRecord[]
|
|
submitRecords SmsSubmitRecord[]
|
|
receiptRecords SmsReceiptRecord[]
|
|
segmentAudits SmsMessageSegmentAudit[]
|
|
|
|
@@index([tenantId, status, createdAt])
|
|
@@index([status, scheduledAt])
|
|
@@index([applicationId, createdAt])
|
|
}
|
|
|
|
model SmsApiRequest {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
batchTaskId String
|
|
requestId String @unique
|
|
sourceIp String?
|
|
userAgent String?
|
|
payloadSummary Json?
|
|
status String @default("accepted")
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
batchTask SmsBatchTask @relation(fields: [batchTaskId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([tenantId, createdAt])
|
|
@@index([batchTaskId])
|
|
}
|
|
|
|
model SmsMessageRecord {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
batchTaskId String?
|
|
applicationId String?
|
|
templateId String?
|
|
signatureId String?
|
|
drainageInfoId String?
|
|
reviewTaskId String?
|
|
messageId String @unique
|
|
phoneNumber String
|
|
carrier String?
|
|
province String?
|
|
content String
|
|
billingUnits Int @default(1)
|
|
unitPrice Int @default(0)
|
|
amountCents Int @default(0)
|
|
queuePriority String @default("normal")
|
|
channelId String?
|
|
submitId String?
|
|
gatewayMessageId String?
|
|
cmppSubmitSequenceId String?
|
|
status String @default("queued")
|
|
submitStatus String?
|
|
receiptStatus String?
|
|
errorCode String?
|
|
errorMessage String?
|
|
queuedAt DateTime @default(now())
|
|
submittedAt DateTime?
|
|
deliveredAt DateTime?
|
|
timeoutAt DateTime?
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
batchTask SmsBatchTask? @relation(fields: [batchTaskId], references: [id], onDelete: Cascade)
|
|
application SmsApplication? @relation(fields: [applicationId], references: [id])
|
|
template SmsTemplate? @relation(fields: [templateId], references: [id])
|
|
signature SmsSignature? @relation(fields: [signatureId], references: [id])
|
|
drainageInfo SmsDrainageInfo? @relation(fields: [drainageInfoId], references: [id])
|
|
reviewTask SmsSendTask? @relation(fields: [reviewTaskId], references: [id])
|
|
channel SmsChannel? @relation(fields: [channelId], references: [id])
|
|
submitRecords SmsSubmitRecord[]
|
|
receiptRecords SmsReceiptRecord[]
|
|
segmentAudits SmsMessageSegmentAudit[]
|
|
matchedUplinks SmsUplinkMessage[] @relation("SmsUplinkMatchedMessage")
|
|
uplinkMatchCandidates SmsUplinkMatchCandidate[]
|
|
downstreamDeliveries CmppDownstreamDelivery[]
|
|
|
|
@@index([tenantId, status, queuedAt])
|
|
@@index([batchTaskId, status])
|
|
@@index([reviewTaskId, status])
|
|
@@index([phoneNumber])
|
|
@@index([gatewayMessageId])
|
|
@@index([drainageInfoId, queuedAt])
|
|
}
|
|
|
|
model CmppSubmitSession {
|
|
id String @id @default(cuid())
|
|
channelId String
|
|
sessionNo String @unique
|
|
status String @default("open")
|
|
submitTotal Int @default(0)
|
|
acceptedTotal Int @default(0)
|
|
rejectedTotal Int @default(0)
|
|
startedAt DateTime @default(now())
|
|
endedAt DateTime?
|
|
|
|
channel SmsChannel @relation(fields: [channelId], references: [id])
|
|
submitRecords SmsSubmitRecord[]
|
|
|
|
@@index([channelId, status])
|
|
}
|
|
|
|
model SmsSubmitRecord {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
batchTaskId String?
|
|
messageRecordId String
|
|
channelId String
|
|
sessionId String?
|
|
submitId String @unique
|
|
sequenceId Int?
|
|
gatewayMessageId String?
|
|
submitStatus String @default("queued")
|
|
costUnitPrice Int @default(0)
|
|
costAmountCents Int @default(0)
|
|
errorCode String?
|
|
errorMessage String?
|
|
submittedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
batchTask SmsBatchTask? @relation(fields: [batchTaskId], references: [id], onDelete: Cascade)
|
|
messageRecord SmsMessageRecord @relation(fields: [messageRecordId], references: [id], onDelete: Cascade)
|
|
channel SmsChannel @relation(fields: [channelId], references: [id])
|
|
session CmppSubmitSession? @relation(fields: [sessionId], references: [id])
|
|
segmentAudits SmsMessageSegmentAudit[]
|
|
|
|
@@index([tenantId, createdAt])
|
|
@@index([messageRecordId])
|
|
@@index([gatewayMessageId])
|
|
}
|
|
|
|
model DailyReconciliationReport {
|
|
id String @id @default(cuid())
|
|
reportDate DateTime @db.Date
|
|
tenantId String
|
|
tenantName String
|
|
applicationId String
|
|
applicationName String
|
|
sentUnits Int @default(0)
|
|
successUnits Int @default(0)
|
|
generatedAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([reportDate, tenantId, applicationId])
|
|
@@index([reportDate])
|
|
@@index([tenantId, reportDate])
|
|
@@index([applicationId, reportDate])
|
|
}
|
|
|
|
model DailyProfitReport {
|
|
id String @id @default(cuid())
|
|
reportDate DateTime @db.Date
|
|
dimensionType String
|
|
dimensionId String
|
|
dimensionName String
|
|
tenantId String?
|
|
tenantName String?
|
|
applicationId String?
|
|
channelId String?
|
|
sentUnits Int @default(0)
|
|
successUnits Int @default(0)
|
|
revenueCents Int @default(0)
|
|
costCents Int @default(0)
|
|
profitCents Int @default(0)
|
|
profitRateBps Int @default(0)
|
|
generatedAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([reportDate, dimensionType, dimensionId])
|
|
@@index([dimensionType, reportDate])
|
|
@@index([tenantId, reportDate])
|
|
@@index([applicationId, reportDate])
|
|
@@index([channelId, reportDate])
|
|
}
|
|
|
|
model DailyQualityReport {
|
|
id String @id @default(cuid())
|
|
reportDate DateTime @db.Date
|
|
dimensionType String
|
|
dimensionId String
|
|
dimensionName String
|
|
tenantId String?
|
|
tenantName String?
|
|
applicationId String?
|
|
channelId String?
|
|
signatureId String?
|
|
drainageInfoId String?
|
|
sentUnits Int @default(0)
|
|
successUnits Int @default(0)
|
|
successRateBps Int @default(0)
|
|
avgArrivalMs Int?
|
|
generatedAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([reportDate, dimensionType, dimensionId])
|
|
@@index([dimensionType, reportDate, sentUnits])
|
|
@@index([tenantId, reportDate])
|
|
@@index([applicationId, reportDate])
|
|
@@index([channelId, reportDate])
|
|
@@index([signatureId, reportDate])
|
|
@@index([drainageInfoId, reportDate])
|
|
}
|
|
|
|
model SmsMessageSegmentAudit {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
batchTaskId String?
|
|
messageRecordId String
|
|
submitRecordId String?
|
|
channelId String?
|
|
submitId String
|
|
attempt Int @default(0)
|
|
segmentTotal Int @default(1)
|
|
segmentIndex Int @default(1)
|
|
sequenceId Int?
|
|
gatewayMessageId String?
|
|
submitStatus String @default("queued")
|
|
receiptStatus String?
|
|
rawStatus String?
|
|
compensationType String?
|
|
errorCode String?
|
|
errorMessage String?
|
|
submittedAt DateTime?
|
|
deliveredAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
batchTask SmsBatchTask? @relation(fields: [batchTaskId], references: [id])
|
|
messageRecord SmsMessageRecord @relation(fields: [messageRecordId], references: [id], onDelete: Cascade)
|
|
submitRecord SmsSubmitRecord? @relation(fields: [submitRecordId], references: [id])
|
|
channel SmsChannel? @relation(fields: [channelId], references: [id])
|
|
|
|
@@unique([messageRecordId, submitId, segmentIndex])
|
|
@@index([tenantId, createdAt])
|
|
@@index([messageRecordId, segmentIndex])
|
|
@@index([submitRecordId])
|
|
@@index([gatewayMessageId])
|
|
@@index([submitStatus, receiptStatus])
|
|
}
|
|
|
|
model SmsReceiptRecord {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
batchTaskId String?
|
|
messageRecordId String?
|
|
channelId String?
|
|
messageId String
|
|
gatewayMessageId String
|
|
sequenceId Int?
|
|
receiptStatus String
|
|
rawStatus String
|
|
errorCode String?
|
|
deliveredAt DateTime
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
batchTask SmsBatchTask? @relation(fields: [batchTaskId], references: [id])
|
|
messageRecord SmsMessageRecord? @relation(fields: [messageRecordId], references: [id])
|
|
channel SmsChannel? @relation(fields: [channelId], references: [id])
|
|
|
|
@@index([tenantId, createdAt])
|
|
@@index([messageId])
|
|
@@index([gatewayMessageId])
|
|
}
|
|
|
|
model SmsUplinkMessage {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
applicationId String?
|
|
channelId String
|
|
messageRecordId String?
|
|
messageId String?
|
|
sequenceId Int?
|
|
phoneNumber String
|
|
destId String
|
|
content String
|
|
matchStatus String @default("unmatched")
|
|
matchReason String?
|
|
receivedAt DateTime
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication? @relation(fields: [applicationId], references: [id])
|
|
messageRecord SmsMessageRecord? @relation("SmsUplinkMatchedMessage", fields: [messageRecordId], references: [id])
|
|
channel SmsChannel @relation(fields: [channelId], references: [id])
|
|
matchCandidates SmsUplinkMatchCandidate[]
|
|
|
|
@@index([tenantId, createdAt])
|
|
@@index([applicationId, receivedAt])
|
|
@@index([channelId, receivedAt])
|
|
@@index([messageRecordId])
|
|
@@index([matchStatus])
|
|
@@index([phoneNumber])
|
|
}
|
|
|
|
model SmsUplinkMatchCandidate {
|
|
id String @id @default(cuid())
|
|
uplinkMessageId String
|
|
tenantId String
|
|
applicationId String
|
|
messageRecordId String?
|
|
matchSource String
|
|
confidence Int @default(50)
|
|
reason String?
|
|
status String @default("pending")
|
|
claimedAt DateTime?
|
|
claimedById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
uplinkMessage SmsUplinkMessage @relation(fields: [uplinkMessageId], references: [id], onDelete: Cascade)
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication @relation(fields: [applicationId], references: [id])
|
|
messageRecord SmsMessageRecord? @relation(fields: [messageRecordId], references: [id])
|
|
|
|
@@unique([uplinkMessageId, applicationId, messageRecordId])
|
|
@@index([uplinkMessageId, status])
|
|
@@index([tenantId, status, createdAt])
|
|
@@index([applicationId, status, createdAt])
|
|
@@index([messageRecordId])
|
|
}
|
|
|
|
model CmppDownstreamDelivery {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
applicationId String
|
|
messageRecordId String?
|
|
messageId String?
|
|
deliveryType String
|
|
status String @default("pending")
|
|
payload Json
|
|
retryEnabled Boolean @default(true)
|
|
retryCount Int @default(0)
|
|
manualRetryCount Int @default(0)
|
|
lastRetriedAt DateTime?
|
|
nextRetryAt DateTime?
|
|
sentAt DateTime?
|
|
acknowledgedAt DateTime?
|
|
ackDeadlineAt DateTime?
|
|
ackResult Int?
|
|
ackSequenceId String?
|
|
ackMessageId String?
|
|
connectionId String?
|
|
deliveredAt DateTime?
|
|
lastError String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication @relation(fields: [applicationId], references: [id])
|
|
messageRecord SmsMessageRecord? @relation(fields: [messageRecordId], references: [id])
|
|
|
|
@@index([tenantId, status, createdAt])
|
|
@@index([applicationId, status, createdAt])
|
|
@@index([messageId])
|
|
@@index([messageRecordId])
|
|
@@index([deliveryType, status])
|
|
@@index([status, ackDeadlineAt])
|
|
}
|
|
|
|
model GatewaySubmitDeadLetter {
|
|
id String @id @default(cuid())
|
|
streamMessageId String @unique
|
|
tenantId String?
|
|
applicationId String?
|
|
channelId String?
|
|
traceId String?
|
|
messageId String?
|
|
submitId String?
|
|
status String @default("pending")
|
|
failureCode String
|
|
failureMessage String
|
|
attempts Int @default(1)
|
|
maxAttempts Int @default(3)
|
|
commandPayload Json?
|
|
rawPayload String?
|
|
manualRetryCount Int @default(0)
|
|
lastRetryStreamId String?
|
|
lastRetriedAt DateTime?
|
|
resolvedAt DateTime?
|
|
resolvedStatus String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication? @relation(fields: [applicationId], references: [id])
|
|
channel SmsChannel? @relation(fields: [channelId], references: [id])
|
|
|
|
@@index([status, createdAt])
|
|
@@index([tenantId, status, createdAt])
|
|
@@index([applicationId, status, createdAt])
|
|
@@index([channelId, status, createdAt])
|
|
@@index([messageId])
|
|
@@index([submitId])
|
|
}
|
|
|
|
model GatewayDownstreamRecoveryStatus {
|
|
id String @id @default(cuid())
|
|
account String @unique
|
|
tenantId String?
|
|
applicationId String?
|
|
gatewayInstanceId String?
|
|
state String
|
|
lockOwner String?
|
|
lockExpiresAt DateTime?
|
|
lastAttemptAt DateTime?
|
|
lastSuccessAt DateTime?
|
|
lastFailureAt DateTime?
|
|
nextRetryAt DateTime?
|
|
attemptCount Int @default(0)
|
|
failureCategory String?
|
|
lastError String?
|
|
lastSkipReason String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
|
application SmsApplication? @relation(fields: [applicationId], references: [id])
|
|
|
|
@@index([tenantId, state, updatedAt])
|
|
@@index([applicationId, state, updatedAt])
|
|
@@index([failureCategory, updatedAt])
|
|
@@index([lockOwner, lockExpiresAt])
|
|
@@index([state, updatedAt])
|
|
@@index([nextRetryAt])
|
|
}
|