feat: add DISC profiles and a sales copilot as an org module

Help reps capture a customer's likely behavior style and get negotiation guidance, with the feature gated from super admin.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-18 21:04:26 +03:30
co-authored by Cursor
parent 96befd3867
commit 002f697dfe
27 changed files with 2838 additions and 26 deletions
+80
View File
@@ -161,6 +161,8 @@ model Organization {
teams Team[]
companies Company[]
people Person[]
discAssessments DiscAssessment[]
salesCopilotSessions SalesCopilotSession[]
pipelines Pipeline[]
deals Deal[]
activities Activity[]
@@ -311,6 +313,8 @@ model User {
routineTaskEvents RoutineTaskEvent[]
routineSettings RoutineUserSettings[]
deletionArchives DeletionArchive[] @relation("DeletionActor")
discAssessments DiscAssessment[] @relation("DiscAssessor")
salesCopilotSessions SalesCopilotSession[] @relation("CopilotAuthor")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -554,6 +558,11 @@ model Person {
routineTasks RoutineTask[]
outboundSmsLogs OutboundSmsLog[]
financialDocuments FinancialDocument[]
discLabel String?
discReliable Boolean @default(false)
discAssessedAt DateTime?
discAssessments DiscAssessment[]
salesCopilotSessions SalesCopilotSession[]
financialReceivables FinancialReceivable[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -569,6 +578,7 @@ model Person {
@@index([companyId])
@@index([ownerId])
@@index([loyaltyTierId])
@@index([organizationId, discLabel])
}
model Pipeline {
@@ -640,6 +650,7 @@ model Deal {
expectedCloseAt DateTime?
personId String?
person Person? @relation(fields: [personId], references: [id], onDelete: SetNull)
salesCopilotSessions SalesCopilotSession[]
companyId String?
company Company? @relation(fields: [companyId], references: [id], onDelete: SetNull)
ownerId String?
@@ -2766,6 +2777,7 @@ model Lead {
convertedAt DateTime?
archivedAt DateTime?
events LeadEvent[]
salesCopilotSessions SalesCopilotSession[]
trackingLinks TrackingLink[]
trackingEvents TrackingEvent[]
routineTasks RoutineTask[]
@@ -3337,3 +3349,71 @@ model GamificationBonus {
@@index([organizationId, isActive])
}
/// ارزیابی رفتاری DISC؛ هر بار یک رکورد تازه است و تاریخچه پاک نمی‌شود.
model DiscAssessment {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
personId String
person Person @relation(fields: [personId], references: [id], onDelete: Cascade)
assessorId String
assessor User @relation("DiscAssessor", fields: [assessorId], references: [id], onDelete: Restrict)
answers Json
scoreD Int
scoreI Int
scoreS Int
scoreC Int
percentD Int
percentI Int
percentS Int
percentC Int
validCount Int
primaryTypes String[] @default([])
secondaryTypes String[] @default([])
label String
secondaryLabel String?
reliable Boolean
confidence String
note String?
status String @default("confirmed")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([organizationId, personId, createdAt])
@@index([personId])
}
/// نتیجهٔ تأییدشدهٔ دستیار فروش. پیشنهاد خام بدون تأیید کارشناس اینجا ذخیره نمی‌شود.
model SalesCopilotSession {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
personId String?
person Person? @relation(fields: [personId], references: [id], onDelete: Cascade)
leadId String?
lead Lead? @relation(fields: [leadId], references: [id], onDelete: SetNull)
dealId String?
deal Deal? @relation(fields: [dealId], references: [id], onDelete: SetNull)
userId String
user User @relation("CopilotAuthor", fields: [userId], references: [id], onDelete: Restrict)
topic String
goal String
customerStatement String
behaviorNotes String?
analysis Json
confirmedResponse String?
nextAction String?
followUpAt DateTime?
callOutcome String?
agentNote String?
status String
messageDraft String?
activityId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([organizationId, personId, createdAt])
@@index([organizationId, leadId])
@@index([dealId])
}