feat(activities): split customer column, wider search, custom activity types with type-specific fields

- Table: separate assignee and customer columns; search by assignee and activity type
- ActivityTypeDef model with per-type field definitions (text, select, checklist, participants, ...)
- Default types incl. meeting subject/participants and task checklist; admins manage types
- Participants see activities in their lists and get notified

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-07 12:29:23 +03:30
co-authored by Cursor
parent aa2f39256a
commit 13668c4ba4
17 changed files with 3371 additions and 147 deletions
+33
View File
@@ -207,6 +207,7 @@ model Organization {
leads Lead[]
leadStages LeadStage[]
activityStages ActivityStage[]
activityTypeDefs ActivityTypeDef[]
leadEvents LeadEvent[]
leadImportJobs LeadImportJob[]
conversationSettings ConversationSettings?
@@ -646,6 +647,30 @@ model ActivityStage {
@@index([organizationId, position])
}
/// نوع فعالیت قابل تعریف توسط سازمان با فیلدهای اختصاصی
model ActivityTypeDef {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
name String
/// نوع پایه — مبنای گزارش‌ها، یادآورها و سازگاری
baseType ActivityType @default(task)
icon String @default("check")
color String @default("green")
/// تعریف فیلدها: [{ key, label, type, options?, required?, placeholder? }]
fields Json @default("[]")
position Int @default(0)
isActive Boolean @default(true)
/// نوع اصلیِ هر baseType — حذف‌شدنی نیست
isSystem Boolean @default(false)
activities Activity[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([organizationId, name])
@@index([organizationId, position])
}
model Activity {
id String @id @default(cuid())
organizationId String
@@ -683,10 +708,18 @@ model Activity {
/// مرحله (ستون کانبان)؛ null یا مرحلهٔ ناهم‌نوع با status → اولین مرحلهٔ هم‌نوع
stageId String?
stage ActivityStage? @relation(fields: [stageId], references: [id], onDelete: SetNull)
/// نوع سفارشی؛ null → نوع اصلیِ همان type
typeDefId String?
typeDef ActivityTypeDef? @relation(fields: [typeDefId], references: [id], onDelete: SetNull)
/// مقادیر فیلدهای اختصاصی نوع (کلید فیلد → مقدار)
fields Json?
/// کاربران شرکت‌کننده؛ فعالیت در لیست آن‌ها هم دیده می‌شود
participantIds String[] @default([])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([stageId])
@@index([typeDefId])
@@index([organizationId, status, dueAt])
@@index([organizationId, assigneeId])
@@index([organizationId, createdById])