feat: add per-org SMS wallet with adm panel and header credit
Bill all platform SMS (including OTP), allow negative balance with manual/auto cutoffs, and support own-panel bypass without wallet debit.
This commit is contained in:
@@ -206,6 +206,7 @@ model Organization {
|
||||
webhookEndpoints WebhookEndpoint[]
|
||||
smsCampaigns SmsCampaign[]
|
||||
outboundSmsLogs OutboundSmsLog[]
|
||||
smsAccount SmsAccount?
|
||||
financialAccounts FinancialAccount[]
|
||||
financialCategories FinancialCategory[]
|
||||
financialDocuments FinancialDocument[]
|
||||
@@ -2290,6 +2291,78 @@ model FinancialInstallment {
|
||||
@@index([dueDate])
|
||||
}
|
||||
|
||||
/// کیفپول و تنظیمات پیامک هر محیط (الگوی همکار / سوپرادمین آبشُده)
|
||||
model SmsAccount {
|
||||
id String @id @default(cuid())
|
||||
organizationId String @unique
|
||||
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
||||
balanceRials Int @default(0)
|
||||
pricePerPartRials Int @default(2500)
|
||||
isBlocked Boolean @default(false)
|
||||
/// اگر ست باشد: وقتی موجودی < این مقدار، ارسال قطع میشود (میتواند منفی باشد). null = فقط کلید دستی
|
||||
autoBlockBelowRials Int?
|
||||
alertCriticalRials Int @default(10000)
|
||||
alertWarningRials Int @default(100000)
|
||||
/// platform = سامانهٔ ما | own = پنل اختصاصی مشتری (بدون کسر/لاگ کیف)
|
||||
panelMode String @default("platform")
|
||||
/// وقتی panelMode=own: 0098 | asanak | trez
|
||||
ownPanelType String @default("0098")
|
||||
ownPanelUsername String?
|
||||
ownPanelPassword String?
|
||||
ownPanelFrom String?
|
||||
chargeCard String?
|
||||
chargeIban String?
|
||||
chargeHolder String?
|
||||
chargeInstruction String?
|
||||
alertDaysSent Int @default(0)
|
||||
lastAlertDate DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
ledgers SmsLedger[]
|
||||
sendLogs SmsBillingSendLog[]
|
||||
|
||||
@@index([isBlocked])
|
||||
@@index([balanceRials])
|
||||
}
|
||||
|
||||
model SmsLedger {
|
||||
id String @id @default(cuid())
|
||||
smsAccountId String
|
||||
smsAccount SmsAccount @relation(fields: [smsAccountId], references: [id], onDelete: Cascade)
|
||||
/// charge | debit | alert_debit
|
||||
type String
|
||||
amountRials Int
|
||||
balanceAfterRials Int
|
||||
parts Int?
|
||||
pricePerPartRials Int?
|
||||
note String?
|
||||
smsSendLogId String?
|
||||
createdById String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([smsAccountId, createdAt])
|
||||
@@index([type])
|
||||
}
|
||||
|
||||
/// لاگ ارسال صورتحسابشده (همهٔ مسیرها وقتی panelMode=platform)
|
||||
model SmsBillingSendLog {
|
||||
id String @id @default(cuid())
|
||||
smsAccountId String
|
||||
smsAccount SmsAccount @relation(fields: [smsAccountId], references: [id], onDelete: Cascade)
|
||||
receiver String
|
||||
body String
|
||||
parts Int
|
||||
pricePerPartRials Int
|
||||
totalAmountRials Int
|
||||
provider String?
|
||||
source String?
|
||||
isAlert Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([smsAccountId, createdAt])
|
||||
@@index([source])
|
||||
}
|
||||
|
||||
/// لاگ یکپارچهٔ پیامک خروجی (دستی / کمپین / اتوماسیون)
|
||||
model OutboundSmsLog {
|
||||
id String @id @default(cuid())
|
||||
|
||||
Reference in New Issue
Block a user