Add VoIP webhook connector for call logging, notifications, and optional click-to-call; align brand to Montact.

This commit is contained in:
2026-09-27 08:47:11 +03:30
parent 26085b54a9
commit db65b55660
17 changed files with 1385 additions and 14 deletions
@@ -0,0 +1,61 @@
-- CreateTable
CREATE TABLE "VoipConnection" (
"id" TEXT NOT NULL,
"organizationId" TEXT NOT NULL,
"label" TEXT NOT NULL,
"enabled" BOOLEAN NOT NULL DEFAULT true,
"webhookSecretCiphertext" TEXT,
"webhookSecretIv" TEXT,
"webhookSecretTag" TEXT,
"clickToCallUrl" TEXT,
"lastEventAt" TIMESTAMP(3),
"lastError" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "VoipConnection_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "VoipCallLog" (
"id" TEXT NOT NULL,
"organizationId" TEXT NOT NULL,
"connectionId" TEXT NOT NULL,
"externalCallId" TEXT NOT NULL,
"direction" TEXT NOT NULL DEFAULT 'inbound',
"status" TEXT NOT NULL DEFAULT 'completed',
"fromNumber" TEXT,
"toNumber" TEXT,
"personId" TEXT,
"activityId" TEXT,
"durationSec" INTEGER,
"startedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"endedAt" TIMESTAMP(3),
"rawPayload" JSONB,
"syncedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "VoipCallLog_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "VoipConnection_organizationId_enabled_idx" ON "VoipConnection"("organizationId", "enabled");
-- CreateIndex
CREATE INDEX "VoipCallLog_organizationId_syncedAt_idx" ON "VoipCallLog"("organizationId", "syncedAt");
-- CreateIndex
CREATE INDEX "VoipCallLog_personId_idx" ON "VoipCallLog"("personId");
-- CreateIndex
CREATE INDEX "VoipCallLog_activityId_idx" ON "VoipCallLog"("activityId");
-- CreateIndex
CREATE UNIQUE INDEX "VoipCallLog_connectionId_externalCallId_key" ON "VoipCallLog"("connectionId", "externalCallId");
-- AddForeignKey
ALTER TABLE "VoipConnection" ADD CONSTRAINT "VoipConnection_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "VoipCallLog" ADD CONSTRAINT "VoipCallLog_connectionId_fkey" FOREIGN KEY ("connectionId") REFERENCES "VoipConnection"("id") ON DELETE CASCADE ON UPDATE CASCADE;
+50
View File
@@ -199,6 +199,7 @@ model Organization {
webhookEndpoints WebhookEndpoint[]
smsCampaigns SmsCampaign[]
wooCommerceConnections WooCommerceConnection[]
voipConnections VoipConnection[]
}
model User {
@@ -1780,3 +1781,52 @@ model WooCommerceOrderLink {
@@index([organizationId, syncedAt])
@@index([invoiceId])
}
/// اتصال تلفن سازمانی / سانترال (وب‌هوک عمومی)
model VoipConnection {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
label String
enabled Boolean @default(true)
webhookSecretCiphertext String?
webhookSecretIv String?
webhookSecretTag String?
/// قالب URL شروع تماس؛ جای {number} شماره می‌نشیند
clickToCallUrl String?
lastEventAt DateTime?
lastError String?
calls VoipCallLog[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([organizationId, enabled])
}
model VoipCallLog {
id String @id @default(cuid())
organizationId String
connectionId String
connection VoipConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
externalCallId String
/// inbound | outbound
direction String @default("inbound")
/// ringing | answered | missed | completed | failed
status String @default("completed")
fromNumber String?
toNumber String?
personId String?
activityId String?
durationSec Int?
startedAt DateTime @default(now())
endedAt DateTime?
rawPayload Json?
syncedAt DateTime @default(now())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([connectionId, externalCallId])
@@index([organizationId, syncedAt])
@@index([personId])
@@index([activityId])
}