@adaptware/eagles-db 0.4.13 → 0.4.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/client/wasm.js CHANGED
@@ -163,22 +163,6 @@ exports.Prisma.ActionScalarFieldEnum = {
163
163
  is_active: 'is_active'
164
164
  };
165
165
 
166
- exports.Prisma.ActivityEventScalarFieldEnum = {
167
- id: 'id',
168
- organisation_id: 'organisation_id',
169
- event_type: 'event_type',
170
- entity_type: 'entity_type',
171
- entity_id: 'entity_id',
172
- actor_id: 'actor_id',
173
- actor_type: 'actor_type',
174
- related_entities: 'related_entities',
175
- snapshot: 'snapshot',
176
- payload: 'payload',
177
- schema_version: 'schema_version',
178
- occurred_at: 'occurred_at',
179
- created_at: 'created_at'
180
- };
181
-
182
166
  exports.Prisma.ActivityLogScalarFieldEnum = {
183
167
  id: 'id',
184
168
  application_id: 'application_id',
@@ -201,7 +185,6 @@ exports.Prisma.ApplicationScalarFieldEnum = {
201
185
  applied_at: 'applied_at',
202
186
  evaluation_plan_id: 'evaluation_plan_id',
203
187
  fit_check_id: 'fit_check_id',
204
- recruiter_id: 'recruiter_id',
205
188
  round_no: 'round_no',
206
189
  on_notice_period: 'on_notice_period',
207
190
  expected_joining_date: 'expected_joining_date',
@@ -386,6 +369,70 @@ exports.Prisma.CandidateProfileScalarFieldEnum = {
386
369
  is_active: 'is_active'
387
370
  };
388
371
 
372
+ exports.Prisma.ChannelProviderConfigScalarFieldEnum = {
373
+ id: 'id',
374
+ organisation_id: 'organisation_id',
375
+ channel: 'channel',
376
+ provider: 'provider',
377
+ credentials: 'credentials',
378
+ metadata: 'metadata',
379
+ is_active: 'is_active',
380
+ is_default: 'is_default',
381
+ created_at: 'created_at',
382
+ updated_at: 'updated_at',
383
+ created_by: 'created_by',
384
+ updated_by: 'updated_by'
385
+ };
386
+
387
+ exports.Prisma.ConversationScalarFieldEnum = {
388
+ id: 'id',
389
+ organisation_id: 'organisation_id',
390
+ channel: 'channel',
391
+ provider: 'provider',
392
+ channel_provider_id: 'channel_provider_id',
393
+ external_id: 'external_id',
394
+ contact_user_id: 'contact_user_id',
395
+ application_id: 'application_id',
396
+ job_description_id: 'job_description_id',
397
+ provider_thread_id: 'provider_thread_id',
398
+ subject: 'subject',
399
+ status: 'status',
400
+ unread_count: 'unread_count',
401
+ last_message_at: 'last_message_at',
402
+ metadata: 'metadata',
403
+ created_at: 'created_at',
404
+ updated_at: 'updated_at',
405
+ created_by: 'created_by',
406
+ updated_by: 'updated_by'
407
+ };
408
+
409
+ exports.Prisma.CommunicationMessageScalarFieldEnum = {
410
+ id: 'id',
411
+ conversation_id: 'conversation_id',
412
+ organisation_id: 'organisation_id',
413
+ channel: 'channel',
414
+ provider: 'provider',
415
+ channel_provider_id: 'channel_provider_id',
416
+ direction: 'direction',
417
+ status: 'status',
418
+ body: 'body',
419
+ from_identifier: 'from_identifier',
420
+ to_identifier: 'to_identifier',
421
+ sender_user_id: 'sender_user_id',
422
+ application_id: 'application_id',
423
+ job_description_id: 'job_description_id',
424
+ provider_message_id: 'provider_message_id',
425
+ template_name: 'template_name',
426
+ attachments: 'attachments',
427
+ metadata: 'metadata',
428
+ error: 'error',
429
+ sent_at: 'sent_at',
430
+ delivered_at: 'delivered_at',
431
+ read_at: 'read_at',
432
+ created_at: 'created_at',
433
+ updated_at: 'updated_at'
434
+ };
435
+
389
436
  exports.Prisma.ContactUsScalarFieldEnum = {
390
437
  id: 'id',
391
438
  name: 'name',
@@ -419,7 +466,6 @@ exports.Prisma.EvaluationPlanScalarFieldEnum = {
419
466
  duration: 'duration',
420
467
  duration_unit: 'duration_unit',
421
468
  deadline: 'deadline',
422
- category: 'category',
423
469
  created_by: 'created_by',
424
470
  updated_by: 'updated_by',
425
471
  created_at: 'created_at',
@@ -603,10 +649,6 @@ exports.Prisma.JobDescriptionScalarFieldEnum = {
603
649
  summary: 'summary',
604
650
  ai_insight: 'ai_insight',
605
651
  job_fit_comparison: 'job_fit_comparison',
606
- target_closing_date: 'target_closing_date',
607
- closing_date: 'closing_date',
608
- job_number: 'job_number',
609
- job_code: 'job_code',
610
652
  created_at: 'created_at',
611
653
  updated_at: 'updated_at',
612
654
  created_by: 'created_by',
@@ -747,8 +789,6 @@ exports.Prisma.OrganisationScalarFieldEnum = {
747
789
  is_active: 'is_active',
748
790
  alias: 'alias',
749
791
  logo: 'logo',
750
- org_code: 'org_code',
751
- job_sequence: 'job_sequence',
752
792
  timezone: 'timezone'
753
793
  };
754
794
 
@@ -1015,56 +1055,6 @@ exports.ActionStatus = exports.$Enums.ActionStatus = {
1015
1055
  CANCELLED: 'CANCELLED'
1016
1056
  };
1017
1057
 
1018
- exports.ActivityEventType = exports.$Enums.ActivityEventType = {
1019
- APPLICATION_CREATED: 'APPLICATION_CREATED',
1020
- APPLICATION_STARTED: 'APPLICATION_STARTED',
1021
- APPLICATION_REJECTED: 'APPLICATION_REJECTED',
1022
- APPLICATION_SHORTLISTED: 'APPLICATION_SHORTLISTED',
1023
- ROUND_ASSIGNED: 'ROUND_ASSIGNED',
1024
- ROUND_STARTED: 'ROUND_STARTED',
1025
- ROUND_COMPLETED: 'ROUND_COMPLETED',
1026
- ROUND_PASSED: 'ROUND_PASSED',
1027
- ROUND_FAILED: 'ROUND_FAILED',
1028
- ROUND_SKIPPED: 'ROUND_SKIPPED',
1029
- INTERVIEW_SCHEDULED: 'INTERVIEW_SCHEDULED',
1030
- INTERVIEW_RESCHEDULED: 'INTERVIEW_RESCHEDULED',
1031
- INTERVIEW_CANCELLED: 'INTERVIEW_CANCELLED',
1032
- INTERVIEW_COMPLETED: 'INTERVIEW_COMPLETED',
1033
- INTERVIEW_NO_SHOW: 'INTERVIEW_NO_SHOW',
1034
- INTERVIEW_EVALUATION_PENDING: 'INTERVIEW_EVALUATION_PENDING',
1035
- INTERVIEW_EVALUATED: 'INTERVIEW_EVALUATED',
1036
- FEEDBACK_SUBMITTED: 'FEEDBACK_SUBMITTED',
1037
- JOB_CREATED: 'JOB_CREATED',
1038
- JOB_PUBLISHED: 'JOB_PUBLISHED',
1039
- JOB_CLOSED: 'JOB_CLOSED',
1040
- JOB_DEACTIVATED: 'JOB_DEACTIVATED',
1041
- EVALUATION_PLAN_CREATED: 'EVALUATION_PLAN_CREATED',
1042
- EVALUATION_PLAN_PUBLISHED: 'EVALUATION_PLAN_PUBLISHED',
1043
- EVALUATION_PLAN_DELETED: 'EVALUATION_PLAN_DELETED',
1044
- EVALUATION_PLAN_UPDATED: 'EVALUATION_PLAN_UPDATED',
1045
- STATUS_CHANGED: 'STATUS_CHANGED',
1046
- CUSTOM: 'CUSTOM'
1047
- };
1048
-
1049
- exports.ActivityEntityType = exports.$Enums.ActivityEntityType = {
1050
- APPLICATION: 'APPLICATION',
1051
- CANDIDATE: 'CANDIDATE',
1052
- JOB: 'JOB',
1053
- ONGOING_EVALUATION: 'ONGOING_EVALUATION',
1054
- EVALUATION_PLAN: 'EVALUATION_PLAN',
1055
- INTERVIEW: 'INTERVIEW',
1056
- ASSESSMENT: 'ASSESSMENT',
1057
- ORGANISATION: 'ORGANISATION',
1058
- USER: 'USER'
1059
- };
1060
-
1061
- exports.ActivityEntityActorType = exports.$Enums.ActivityEntityActorType = {
1062
- USER: 'USER',
1063
- SYSTEM: 'SYSTEM',
1064
- AI_AGENT: 'AI_AGENT',
1065
- WEBHOOK: 'WEBHOOK'
1066
- };
1067
-
1068
1058
  exports.ActivityActorType = exports.$Enums.ActivityActorType = {
1069
1059
  USER: 'USER',
1070
1060
  AI: 'AI',
@@ -1112,6 +1102,39 @@ exports.JDCreationType = exports.$Enums.JDCreationType = {
1112
1102
  Create_From_Profile: 'Create_From_Profile'
1113
1103
  };
1114
1104
 
1105
+ exports.CommChannel = exports.$Enums.CommChannel = {
1106
+ WHATSAPP: 'WHATSAPP',
1107
+ EMAIL: 'EMAIL',
1108
+ SMS: 'SMS',
1109
+ CALL: 'CALL'
1110
+ };
1111
+
1112
+ exports.CommProvider = exports.$Enums.CommProvider = {
1113
+ META_WHATSAPP: 'META_WHATSAPP',
1114
+ TWILIO: 'TWILIO',
1115
+ GUPSHUP: 'GUPSHUP',
1116
+ MTALKZ: 'MTALKZ',
1117
+ THREE_SIXTY_DIALOG: 'THREE_SIXTY_DIALOG',
1118
+ GMAIL: 'GMAIL',
1119
+ OUTLOOK: 'OUTLOOK',
1120
+ GENERIC_SMTP: 'GENERIC_SMTP',
1121
+ GENERIC: 'GENERIC'
1122
+ };
1123
+
1124
+ exports.CommDirection = exports.$Enums.CommDirection = {
1125
+ INBOUND: 'INBOUND',
1126
+ OUTBOUND: 'OUTBOUND'
1127
+ };
1128
+
1129
+ exports.CommMessageStatus = exports.$Enums.CommMessageStatus = {
1130
+ QUEUED: 'QUEUED',
1131
+ SENT: 'SENT',
1132
+ DELIVERED: 'DELIVERED',
1133
+ READ: 'READ',
1134
+ FAILED: 'FAILED',
1135
+ RECEIVED: 'RECEIVED'
1136
+ };
1137
+
1115
1138
  exports.EvaluationRoundFormat = exports.$Enums.EvaluationRoundFormat = {
1116
1139
  PHONE_CALL: 'PHONE_CALL',
1117
1140
  VIDEO_CALL_AI_ASSISTED: 'VIDEO_CALL_AI_ASSISTED',
@@ -1152,14 +1175,6 @@ exports.DurationUnit = exports.$Enums.DurationUnit = {
1152
1175
  DAYS: 'DAYS'
1153
1176
  };
1154
1177
 
1155
- exports.EvaluationCategory = exports.$Enums.EvaluationCategory = {
1156
- EXPERIENCE_SCREENING: 'EXPERIENCE_SCREENING',
1157
- TECHNICAL_SCREENING: 'TECHNICAL_SCREENING',
1158
- TECHNICAL_INTERVIEW: 'TECHNICAL_INTERVIEW',
1159
- BUSINESS_ROUND: 'BUSINESS_ROUND',
1160
- BEHAVIORAL_ROUND: 'BEHAVIORAL_ROUND'
1161
- };
1162
-
1163
1178
  exports.IntegrationProvider = exports.$Enums.IntegrationProvider = {
1164
1179
  NAUKRI: 'NAUKRI',
1165
1180
  ZOHO_RECRUIT: 'ZOHO_RECRUIT',
@@ -1297,7 +1312,6 @@ exports.Prisma.ModelName = {
1297
1312
  CandidateQuestionResponse: 'CandidateQuestionResponse',
1298
1313
  UserRole: 'UserRole',
1299
1314
  Action: 'Action',
1300
- ActivityEvent: 'ActivityEvent',
1301
1315
  ActivityLog: 'ActivityLog',
1302
1316
  Application: 'Application',
1303
1317
  Approval: 'Approval',
@@ -1310,6 +1324,9 @@ exports.Prisma.ModelName = {
1310
1324
  Budget: 'Budget',
1311
1325
  Calendly: 'Calendly',
1312
1326
  CandidateProfile: 'CandidateProfile',
1327
+ ChannelProviderConfig: 'ChannelProviderConfig',
1328
+ Conversation: 'Conversation',
1329
+ CommunicationMessage: 'CommunicationMessage',
1313
1330
  ContactUs: 'ContactUs',
1314
1331
  EvaluationPlan: 'EvaluationPlan',
1315
1332
  Feedback: 'Feedback',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptware/eagles-db",
3
- "version": "0.4.13",
3
+ "version": "0.4.17",
4
4
  "description": "A Prisma client package for Treadspace database operations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -16,7 +16,6 @@ model Application {
16
16
  applied_at DateTime @default(now())
17
17
  evaluation_plan_id String?
18
18
  fit_check_id String? @unique
19
- recruiter_id String?
20
19
  round_no Int @default(0)
21
20
  //Screening fields
22
21
  on_notice_period Boolean @default(false)
@@ -34,12 +33,13 @@ model Application {
34
33
  resume Resume @relation(fields: [resume_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
35
34
  job_description JobDescription @relation(fields: [job_description_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
36
35
  fit_check FitCheck? @relation(fields: [fit_check_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
37
- recruiter User? @relation("ApplicationRecruiter", fields: [recruiter_id], references: [id])
38
36
  interviews Interview[]
39
37
  assignments Assignment[]
40
38
  ongoing_evaluations OngoingEvaluation[]
41
39
  activity_logs ActivityLog[]
42
40
  notes Notes[]
41
+ conversations Conversation[]
42
+ communication_messages CommunicationMessage[]
43
43
  // Audit fields
44
44
  created_at DateTime @default(now())
45
45
  updated_at DateTime @updatedAt
@@ -1,20 +1,20 @@
1
1
  /// Defines how an assessment is conducted.
2
2
 
3
3
  model AssessmentLibrary {
4
- id String @id @default(uuid())
5
- title String
6
- time_required Int
7
- passing_score Float?
8
- max_score Float?
9
- organisation_id String
10
- created_at DateTime @default(now())
11
- updated_at DateTime @updatedAt
12
- created_by String
13
- updated_by String
14
- is_active Boolean @default(true)
15
- organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
16
- questions Question[] // One assessment → many questions
17
- assessments Assessment[]
4
+ id String @id @default(uuid())
5
+ title String
6
+ time_required Int
7
+ passing_score Float?
8
+ max_score Float?
9
+ organisation_id String
10
+ created_at DateTime @default(now())
11
+ updated_at DateTime @updatedAt
12
+ created_by String
13
+ updated_by String
14
+ is_active Boolean @default(true)
15
+ organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
16
+ questions Question[] // One assessment → many questions
17
+ assessments Assessment[]
18
18
  evaluation_Plans EvaluationPlan[]
19
19
 
20
20
  @@index([organisation_id])
@@ -1,42 +1,42 @@
1
1
  enum AssignmentStatus {
2
- AVAILABLE
3
- SCHEDULED
4
- CANCELLED
2
+ AVAILABLE
3
+ SCHEDULED
4
+ CANCELLED
5
5
  }
6
6
 
7
7
  model Assignment {
8
- id String @id @default(uuid())
9
- candidate_id String
10
- assignment_library_id String
11
- reviewer_id String?
12
- application_id String?
13
- job_description_id String
14
- organisation_id String
15
- ongoing_evaluation_id String? @unique
16
- overallScore Int?
17
- feedback Json?
18
- status AssignmentStatus @default(AVAILABLE)
19
- cancel_reason String?
20
- solution_url String?
21
- zip_url String?
22
- scheduled_start_time DateTime?
23
- scheduled_end_time DateTime?
24
- created_at DateTime @default(now())
25
- updated_at DateTime @updatedAt
26
- created_by String
27
- updated_by String
28
- is_active Boolean @default(true)
29
- // Relations
30
- candidate User? @relation("CandidateAssignments", fields: [candidate_id], references: [id], onDelete: Cascade)
31
- assignment_library AssignmentLibrary @relation(fields: [assignment_library_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
32
- reviewer User? @relation("AssignmentReviewer", fields: [reviewer_id], references: [id], onDelete: SetNull)
33
- organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
34
- job_description JobDescription @relation(fields: [job_description_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
35
- application Application? @relation(fields: [application_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
36
- ongoing_evaluation OngoingEvaluation? @relation(fields: [ongoing_evaluation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
8
+ id String @id @default(uuid())
9
+ candidate_id String
10
+ assignment_library_id String
11
+ reviewer_id String?
12
+ application_id String?
13
+ job_description_id String
14
+ organisation_id String
15
+ ongoing_evaluation_id String? @unique
16
+ overallScore Int?
17
+ feedback Json?
18
+ status AssignmentStatus @default(AVAILABLE)
19
+ cancel_reason String?
20
+ solution_url String?
21
+ zip_url String?
22
+ scheduled_start_time DateTime?
23
+ scheduled_end_time DateTime?
24
+ created_at DateTime @default(now())
25
+ updated_at DateTime @updatedAt
26
+ created_by String
27
+ updated_by String
28
+ is_active Boolean @default(true)
29
+ // Relations
30
+ candidate User? @relation("CandidateAssignments", fields: [candidate_id], references: [id], onDelete: Cascade)
31
+ assignment_library AssignmentLibrary @relation(fields: [assignment_library_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
32
+ reviewer User? @relation("AssignmentReviewer", fields: [reviewer_id], references: [id], onDelete: SetNull)
33
+ organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
34
+ job_description JobDescription @relation(fields: [job_description_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
35
+ application Application? @relation(fields: [application_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
36
+ ongoing_evaluation OngoingEvaluation? @relation(fields: [ongoing_evaluation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
37
37
 
38
- @@unique([candidate_id, ongoing_evaluation_id])
39
- @@index([candidate_id])
40
- @@index([reviewer_id])
41
- @@index([job_description_id])
38
+ @@unique([candidate_id, ongoing_evaluation_id])
39
+ @@index([candidate_id])
40
+ @@index([reviewer_id])
41
+ @@index([job_description_id])
42
42
  }
@@ -1,18 +1,18 @@
1
1
  model Calendly {
2
- id String @id @default(uuid())
3
- user_id String @unique
2
+ id String @id @default(uuid())
3
+ user_id String @unique
4
4
 
5
- access_token String
6
- refresh_token String
7
- expires_at DateTime
8
- calendly_user_uri String
9
- scope String?
5
+ access_token String
6
+ refresh_token String
7
+ expires_at DateTime
8
+ calendly_user_uri String
9
+ scope String?
10
10
 
11
- user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
11
+ user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
12
12
 
13
- created_at DateTime @default(now())
14
- updated_at DateTime @updatedAt
15
- created_by String
16
- updated_by String
17
- is_active Boolean @default(true)
13
+ created_at DateTime @default(now())
14
+ updated_at DateTime @updatedAt
15
+ created_by String
16
+ updated_by String
17
+ is_active Boolean @default(true)
18
18
  }
@@ -0,0 +1,156 @@
1
+ // Multi-channel communication (WhatsApp, Email, SMS, Call) with provider abstraction.
2
+ // Strategy: typed columns for everything stable; JSON only for genuinely variable data.
3
+
4
+ enum CommChannel {
5
+ WHATSAPP
6
+ EMAIL
7
+ SMS
8
+ CALL
9
+ }
10
+
11
+ enum CommProvider {
12
+ META_WHATSAPP
13
+ TWILIO
14
+ GUPSHUP
15
+ MTALKZ
16
+ THREE_SIXTY_DIALOG
17
+ GMAIL
18
+ OUTLOOK
19
+ GENERIC_SMTP
20
+ GENERIC
21
+ }
22
+
23
+ enum CommDirection {
24
+ INBOUND
25
+ OUTBOUND
26
+ }
27
+
28
+ enum CommMessageStatus {
29
+ QUEUED
30
+ SENT
31
+ DELIVERED
32
+ READ
33
+ FAILED
34
+ RECEIVED
35
+ }
36
+
37
+ /// Per-organisation provider selection + (encrypted) credentials for one channel.
38
+ /// `metadata` stores non-secret provider settings (e.g. phone_number_id, waba_id, webhook_verify_token).
39
+ model ChannelProviderConfig {
40
+ id String @id @default(uuid())
41
+ organisation_id String
42
+ channel CommChannel
43
+ provider CommProvider
44
+ /// Encrypted JSON blob of secrets (token, app_secret, …) using integrationTokenCrypto.
45
+ credentials String?
46
+ metadata Json @default("{}")
47
+ is_active Boolean @default(true)
48
+ is_default Boolean @default(true)
49
+
50
+ organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade)
51
+
52
+ conversations Conversation[]
53
+ messages CommunicationMessage[]
54
+
55
+ created_at DateTime @default(now())
56
+ updated_at DateTime @updatedAt
57
+ created_by String
58
+ updated_by String
59
+
60
+ @@unique([organisation_id, channel, provider])
61
+ @@index([organisation_id, channel])
62
+ @@index([organisation_id, channel, is_active])
63
+ }
64
+
65
+ /// A logical conversation thread with one external party on one channel.
66
+ /// `external_id` is the channel-native identifier (E.164 phone for WhatsApp/SMS, email address for email).
67
+ ///
68
+ /// `application_id` / `job_description_id` are the *current* recruiting scope
69
+ /// the thread is bound to (the recruiter can switch context, but individual
70
+ /// `CommunicationMessage` rows record the scope they were sent under so the
71
+ /// audit trail is preserved). Both nullable so pre-application sourcing
72
+ /// (no application yet, just a JD) still works.
73
+ model Conversation {
74
+ id String @id @default(uuid())
75
+ organisation_id String
76
+ channel CommChannel
77
+ provider CommProvider
78
+ channel_provider_id String?
79
+ external_id String
80
+ contact_user_id String?
81
+ application_id String?
82
+ job_description_id String?
83
+ provider_thread_id String?
84
+ subject String?
85
+ status String @default("open")
86
+ unread_count Int @default(0)
87
+ last_message_at DateTime?
88
+ metadata Json @default("{}")
89
+
90
+ organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade)
91
+ channel_provider ChannelProviderConfig? @relation(fields: [channel_provider_id], references: [id], onDelete: SetNull)
92
+ application Application? @relation(fields: [application_id], references: [id], onDelete: SetNull)
93
+ job_description JobDescription? @relation(fields: [job_description_id], references: [id], onDelete: SetNull)
94
+ messages CommunicationMessage[]
95
+
96
+ created_at DateTime @default(now())
97
+ updated_at DateTime @updatedAt
98
+ created_by String
99
+ updated_by String
100
+
101
+ @@unique([organisation_id, channel, provider, external_id])
102
+ @@index([organisation_id, channel])
103
+ @@index([organisation_id, last_message_at])
104
+ @@index([external_id])
105
+ @@index([organisation_id, application_id])
106
+ @@index([organisation_id, job_description_id])
107
+ }
108
+
109
+ /// Individual message in a conversation. Inbound + outbound share the same model.
110
+ /// `body` is plain text. `attachments` is a JSON array of media descriptors (no binaries persisted).
111
+ /// `metadata` stores raw provider payloads + interactive payloads for audit/debug.
112
+ ///
113
+ /// `application_id` / `job_description_id` are the recruiting scope this
114
+ /// specific message was sent/received under, captured at the time of the
115
+ /// event (not derived from the parent conversation, since a recruiter may
116
+ /// reuse a thread across multiple applications). Both nullable.
117
+ model CommunicationMessage {
118
+ id String @id @default(uuid())
119
+ conversation_id String
120
+ organisation_id String
121
+ channel CommChannel
122
+ provider CommProvider
123
+ channel_provider_id String?
124
+ direction CommDirection
125
+ status CommMessageStatus
126
+ body String?
127
+ from_identifier String
128
+ to_identifier String
129
+ sender_user_id String?
130
+ application_id String?
131
+ job_description_id String?
132
+ provider_message_id String?
133
+ template_name String?
134
+ attachments Json @default("[]")
135
+ metadata Json @default("{}")
136
+ error String?
137
+ sent_at DateTime?
138
+ delivered_at DateTime?
139
+ read_at DateTime?
140
+
141
+ conversation Conversation @relation(fields: [conversation_id], references: [id], onDelete: Cascade)
142
+ organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade)
143
+ channel_provider ChannelProviderConfig? @relation(fields: [channel_provider_id], references: [id], onDelete: SetNull)
144
+ application Application? @relation(fields: [application_id], references: [id], onDelete: SetNull)
145
+ job_description JobDescription? @relation(fields: [job_description_id], references: [id], onDelete: SetNull)
146
+
147
+ created_at DateTime @default(now())
148
+ updated_at DateTime @updatedAt
149
+
150
+ @@unique([provider, provider_message_id])
151
+ @@index([conversation_id, created_at])
152
+ @@index([organisation_id, channel, created_at])
153
+ @@index([organisation_id, status])
154
+ @@index([organisation_id, application_id])
155
+ @@index([organisation_id, job_description_id])
156
+ }
@@ -5,14 +5,6 @@ enum RoundType {
5
5
  SCREENING
6
6
  }
7
7
 
8
- enum EvaluationCategory {
9
- EXPERIENCE_SCREENING
10
- TECHNICAL_SCREENING
11
- TECHNICAL_INTERVIEW
12
- BUSINESS_ROUND
13
- BEHAVIORAL_ROUND
14
- }
15
-
16
8
  enum EvaluationRoundFormat {
17
9
  // ────────────────
18
10
  // Screening formats
@@ -82,7 +74,6 @@ model EvaluationPlan {
82
74
  duration Int?
83
75
  duration_unit DurationUnit?
84
76
  deadline Int?
85
- category EvaluationCategory?
86
77
  created_by String
87
78
  updated_by String
88
79
  created_at DateTime @default(now())
@@ -1,16 +1,16 @@
1
1
  model Google {
2
- id String @id @default(uuid())
3
- user_id String @unique
2
+ id String @id @default(uuid())
3
+ user_id String @unique
4
4
 
5
- google_email String
6
- refresh_token String
7
- scope String?
5
+ google_email String
6
+ refresh_token String
7
+ scope String?
8
8
 
9
- user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
9
+ user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
10
10
 
11
- created_at DateTime @default(now())
12
- updated_at DateTime @updatedAt
13
- created_by String
14
- updated_by String
15
- is_active Boolean @default(true)
11
+ created_at DateTime @default(now())
12
+ updated_at DateTime @updatedAt
13
+ created_by String
14
+ updated_by String
15
+ is_active Boolean @default(true)
16
16
  }