@dakkitor/api-contracts 1.8.0 → 1.9.2

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.
Files changed (139) hide show
  1. package/dist/abilities/abilities.contract.d.ts +28 -1
  2. package/dist/abilities/abilities.contract.d.ts.map +1 -1
  3. package/dist/abilities/abilities.contract.js +32 -1
  4. package/dist/abilities/abilities.contract.spec.js +63 -3
  5. package/dist/abilities/admin-dashboard.abilities.test.js +1 -0
  6. package/dist/abilities/automatic-caller.abilities.json +1 -0
  7. package/dist/abilities/first-agent.abilities.json +14 -0
  8. package/dist/abilities/interconnection.abilities.json +17 -1
  9. package/dist/abilities/office-manager.abilities.json +4 -0
  10. package/dist/abilities/second-agent.abilities.json +48 -1
  11. package/dist/abilities/worker-curator.abilities.json +17 -1
  12. package/dist/actives/actives.contract.d.ts +6959 -6547
  13. package/dist/actives/actives.contract.d.ts.map +1 -1
  14. package/dist/agent-client-links/agent-client-links.contract.d.ts +1275 -1173
  15. package/dist/agent-client-links/agent-client-links.contract.d.ts.map +1 -1
  16. package/dist/auth/auth.contract.d.ts +102 -102
  17. package/dist/bookings/backdate-guard.spec.js +24 -32
  18. package/dist/bookings/bookings.contract.d.ts +9963 -9305
  19. package/dist/bookings/bookings.contract.d.ts.map +1 -1
  20. package/dist/bookings/bookings.contract.js +2 -16
  21. package/dist/call-history/call-history.contract.d.ts +1040 -828
  22. package/dist/call-history/call-history.contract.d.ts.map +1 -1
  23. package/dist/calls-feed/calls-feed.contract.d.ts +138 -98
  24. package/dist/calls-feed/calls-feed.contract.d.ts.map +1 -1
  25. package/dist/candidate-calling/candidate-calling.contract.d.ts +18372 -0
  26. package/dist/candidate-calling/candidate-calling.contract.d.ts.map +1 -0
  27. package/dist/candidate-calling/candidate-calling.contract.js +494 -0
  28. package/dist/candidate-calling/candidate-calling.contract.spec.d.ts +2 -0
  29. package/dist/candidate-calling/candidate-calling.contract.spec.d.ts.map +1 -0
  30. package/dist/candidate-calling/candidate-calling.contract.spec.js +357 -0
  31. package/dist/candidate-calling/candidate-dialpad-call.schemas.d.ts +10 -0
  32. package/dist/candidate-calling/candidate-dialpad-call.schemas.d.ts.map +1 -0
  33. package/dist/candidate-calling/candidate-dialpad-call.schemas.js +33 -0
  34. package/dist/client-contacts/client-contacts.contract.d.ts +622 -622
  35. package/dist/clients/clients.contract.d.ts +289 -289
  36. package/dist/collaboration-checkings/collaboration-checkings.contract.d.ts +3108 -3004
  37. package/dist/collaboration-checkings/collaboration-checkings.contract.d.ts.map +1 -1
  38. package/dist/collaborations/collaborations.contract.d.ts +2604 -2507
  39. package/dist/collaborations/collaborations.contract.d.ts.map +1 -1
  40. package/dist/common/callback-slots.d.ts +4 -0
  41. package/dist/common/callback-slots.d.ts.map +1 -0
  42. package/dist/common/callback-slots.js +20 -0
  43. package/dist/common/common-schemas.d.ts +10 -4
  44. package/dist/common/common-schemas.d.ts.map +1 -1
  45. package/dist/common/common-schemas.js +6 -0
  46. package/dist/companies/companies.contract.d.ts +120 -120
  47. package/dist/crews/crews.contract.d.ts +278 -278
  48. package/dist/cron-executions/cron-executions.contract.d.ts +245 -245
  49. package/dist/cron-executions/cron-executions.contract.d.ts.map +1 -1
  50. package/dist/cron-executions/cron-executions.contract.js +1 -0
  51. package/dist/curated-worker-leads/candidate-coordination.contract.d.ts +3830 -2354
  52. package/dist/curated-worker-leads/candidate-coordination.contract.d.ts.map +1 -1
  53. package/dist/curated-worker-leads/candidate-coordination.contract.js +73 -7
  54. package/dist/curated-worker-leads/candidate-edit-session.contract.d.ts +94 -94
  55. package/dist/curated-worker-leads/contact-history.spec.js +141 -0
  56. package/dist/curated-worker-leads/job-candidate-cards.spec.js +19 -0
  57. package/dist/curated-worker-leads/job-candidates.spec.js +179 -0
  58. package/dist/curated-worker-leads/jobs-tab.contract.d.ts +8185 -2106
  59. package/dist/curated-worker-leads/jobs-tab.contract.d.ts.map +1 -1
  60. package/dist/curated-worker-leads/jobs-tab.contract.js +126 -1
  61. package/dist/curated-worker-leads/owned-jobs-tab.contract.d.ts +110 -110
  62. package/dist/curated-workers/curated-workers.contract.d.ts +2033 -1951
  63. package/dist/curated-workers/curated-workers.contract.d.ts.map +1 -1
  64. package/dist/dashboards/dashboard-widgets.contact-history.spec.d.ts +2 -0
  65. package/dist/dashboards/dashboard-widgets.contact-history.spec.d.ts.map +1 -0
  66. package/dist/dashboards/dashboard-widgets.contact-history.spec.js +160 -0
  67. package/dist/dashboards/dashboard-widgets.contract.d.ts +1027 -284
  68. package/dist/dashboards/dashboard-widgets.contract.d.ts.map +1 -1
  69. package/dist/dashboards/dashboard-widgets.contract.js +46 -1
  70. package/dist/dashboards/dashboard.contract.d.ts +8 -8
  71. package/dist/document-intake/document-intake.contract.d.ts +1145 -1145
  72. package/dist/export-jobs/export-jobs.contract.d.ts +755 -755
  73. package/dist/exports-events/exports-events.schemas.d.ts +6 -6
  74. package/dist/index.d.ts +5 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +5 -0
  77. package/dist/jobs/jobs.contract.d.ts +8507 -6044
  78. package/dist/jobs/jobs.contract.d.ts.map +1 -1
  79. package/dist/jobs/jobs.contract.js +95 -2
  80. package/dist/jobs/jobs.contract.spec.js +231 -1
  81. package/dist/kpi-impersonation/kpi-impersonation.contract.d.ts +102 -102
  82. package/dist/lead-assignments/lead-assignments.contract.d.ts +2985 -1139
  83. package/dist/lead-assignments/lead-assignments.contract.d.ts.map +1 -1
  84. package/dist/lead-assignments/lead-assignments.contract.js +102 -2
  85. package/dist/lead-assignments/lead-assignments.contract.spec.d.ts +2 -0
  86. package/dist/lead-assignments/lead-assignments.contract.spec.d.ts.map +1 -0
  87. package/dist/lead-assignments/lead-assignments.contract.spec.js +51 -0
  88. package/dist/lead-distribution/agent-lead-distribution.contract.d.ts +341 -317
  89. package/dist/lead-distribution/agent-lead-distribution.contract.d.ts.map +1 -1
  90. package/dist/leads/leads.contract.d.ts +282 -282
  91. package/dist/locations/location-enrichment.contract.spec.d.ts +2 -0
  92. package/dist/locations/location-enrichment.contract.spec.d.ts.map +1 -0
  93. package/dist/locations/location-enrichment.contract.spec.js +50 -0
  94. package/dist/locations/locations.contract.d.ts +132 -98
  95. package/dist/locations/locations.contract.d.ts.map +1 -1
  96. package/dist/locations/locations.contract.js +10 -0
  97. package/dist/notifications/notifications.contract.d.ts +579 -107
  98. package/dist/notifications/notifications.contract.d.ts.map +1 -1
  99. package/dist/notifications/notifications.contract.js +36 -2
  100. package/dist/notifications/notifications.contract.spec.d.ts +2 -0
  101. package/dist/notifications/notifications.contract.spec.d.ts.map +1 -0
  102. package/dist/notifications/notifications.contract.spec.js +39 -0
  103. package/dist/outreach/__tests__/outreach-claim.test.js +33 -0
  104. package/dist/outreach/__tests__/outreach-routes.test.js +8 -0
  105. package/dist/outreach/outreach.contract.d.ts +583 -162
  106. package/dist/outreach/outreach.contract.d.ts.map +1 -1
  107. package/dist/outreach/outreach.contract.js +50 -1
  108. package/dist/outreach/relay-hub-outreach.contract.d.ts +299 -121
  109. package/dist/outreach/relay-hub-outreach.contract.d.ts.map +1 -1
  110. package/dist/outreach/relay-hub-outreach.contract.js +10 -0
  111. package/dist/outreach/relay-hub-outreach.contract.spec.js +26 -0
  112. package/dist/outreach/relay-hub-outreach.schemas.d.ts +94 -0
  113. package/dist/outreach/relay-hub-outreach.schemas.d.ts.map +1 -0
  114. package/dist/outreach/relay-hub-outreach.schemas.js +15 -0
  115. package/dist/own-research/check-phone-response.spec.d.ts +2 -0
  116. package/dist/own-research/check-phone-response.spec.d.ts.map +1 -0
  117. package/dist/own-research/check-phone-response.spec.js +54 -0
  118. package/dist/own-research/own-research.contract.d.ts +971 -820
  119. package/dist/own-research/own-research.contract.d.ts.map +1 -1
  120. package/dist/own-research/own-research.contract.js +6 -1
  121. package/dist/proofs/proofs.contract.d.ts +356 -356
  122. package/dist/proofs/proofs.dtos.d.ts +148 -148
  123. package/dist/realtime/job-call-priority-updated.d.ts +18 -0
  124. package/dist/realtime/job-call-priority-updated.d.ts.map +1 -0
  125. package/dist/realtime/job-call-priority-updated.js +17 -0
  126. package/dist/shared/summary-schemas.d.ts +36 -27
  127. package/dist/shared/summary-schemas.d.ts.map +1 -1
  128. package/dist/shared/summary-schemas.js +7 -0
  129. package/dist/sheets-sync/sheets-sync.contract.d.ts +683 -683
  130. package/dist/user-access-grants/user-access-grants.contract.d.ts +216 -216
  131. package/dist/users/users.contract.d.ts +365 -336
  132. package/dist/users/users.contract.d.ts.map +1 -1
  133. package/dist/users/users.contract.js +9 -1
  134. package/dist/users/users.contract.spec.js +39 -0
  135. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.d.ts +150 -150
  136. package/dist/workers/workers.contract.d.ts +4505 -4261
  137. package/dist/workers/workers.contract.d.ts.map +1 -1
  138. package/dist/workers/workers.contract.js +12 -0
  139. package/package.json +1 -1
@@ -0,0 +1,357 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const candidate_calling_contract_1 = require("./candidate-calling.contract");
4
+ describe('candidate calling ring target', () => {
5
+ it('accepts only DESKTOP and PHONE', () => {
6
+ expect(candidate_calling_contract_1.CandidateCallingRingTargetSchema.parse('DESKTOP')).toBe('DESKTOP');
7
+ expect(candidate_calling_contract_1.CandidateCallingRingTargetSchema.parse('PHONE')).toBe('PHONE');
8
+ expect(candidate_calling_contract_1.CandidateCallingRingTargetSchema.safeParse('FAX').success).toBe(false);
9
+ });
10
+ it('reports the ring target on availability', () => {
11
+ const parsed = candidate_calling_contract_1.CandidateCallingAvailabilitySchema.parse({
12
+ enabled: true,
13
+ reason: null,
14
+ ringTarget: 'PHONE',
15
+ });
16
+ expect(parsed.ringTarget).toBe('PHONE');
17
+ });
18
+ it('exposes a route to change the ring target', () => {
19
+ expect(candidate_calling_contract_1.candidateCallingContract.setRingTarget.method).toBe('PATCH');
20
+ expect(candidate_calling_contract_1.candidateCallingContract.setRingTarget.path).toBe('/v2/candidate-calling-queues/ring-target');
21
+ });
22
+ });
23
+ describe('candidate calling contract', () => {
24
+ it('pins the application routes', () => {
25
+ expect(candidate_calling_contract_1.candidateCallingContract.availability).toMatchObject({
26
+ method: 'GET',
27
+ path: '/v2/candidate-calling-queues/availability',
28
+ });
29
+ expect(candidate_calling_contract_1.candidateCallingContract.createQueue).toMatchObject({
30
+ method: 'POST',
31
+ path: '/v2/jobs/:jobId/candidate-calling-queues',
32
+ });
33
+ expect(candidate_calling_contract_1.candidateCallingContract.activeQueue).toMatchObject({
34
+ method: 'GET',
35
+ path: '/v2/candidate-calling-queues/active',
36
+ });
37
+ expect(candidate_calling_contract_1.candidateCallingContract.nextCandidate).toMatchObject({
38
+ method: 'POST',
39
+ path: '/v2/candidate-calling-queues/:queueSessionId/next',
40
+ });
41
+ expect(candidate_calling_contract_1.candidateCallingContract.endCall).toMatchObject({
42
+ method: 'POST',
43
+ path: '/v2/candidate-dialpad-calls/:callId/end',
44
+ });
45
+ expect(candidate_calling_contract_1.candidateCallingContract.stopQueue).toMatchObject({
46
+ method: 'DELETE',
47
+ path: '/v2/candidate-calling-queues/:queueSessionId',
48
+ });
49
+ expect(candidate_calling_contract_1.candidateCallingContract.reviewArtifact).toMatchObject({
50
+ method: 'GET',
51
+ path: '/v2/candidate-dialpad-calls/:callId/review-artifact',
52
+ });
53
+ expect(candidate_calling_contract_1.candidateCallingContract.getCallReview).toMatchObject({
54
+ method: 'GET',
55
+ path: '/v2/candidate-dialpad-calls/:callId/review',
56
+ });
57
+ expect(candidate_calling_contract_1.candidateCallingContract.resolveProfileFact).toMatchObject({
58
+ method: 'POST',
59
+ path: '/v2/candidate-dialpad-calls/:callId/profile-facts/:field/resolve',
60
+ });
61
+ });
62
+ it('validates every route path parameter as a UUID', () => {
63
+ const uuid = '88888888-8888-4888-8888-888888888888';
64
+ expect('pathParams' in candidate_calling_contract_1.candidateCallingContract.availability).toBe(false);
65
+ expect('pathParams' in candidate_calling_contract_1.candidateCallingContract.activeQueue).toBe(false);
66
+ expect(candidate_calling_contract_1.candidateCallingContract.createQueue.pathParams.safeParse({ jobId: uuid })
67
+ .success).toBe(true);
68
+ expect(candidate_calling_contract_1.candidateCallingContract.createQueue.pathParams.safeParse({
69
+ jobId: 'not-a-uuid',
70
+ }).success).toBe(false);
71
+ expect(candidate_calling_contract_1.candidateCallingContract.nextCandidate.pathParams.safeParse({
72
+ queueSessionId: uuid,
73
+ }).success).toBe(true);
74
+ expect(candidate_calling_contract_1.candidateCallingContract.nextCandidate.pathParams.safeParse({
75
+ queueSessionId: 'not-a-uuid',
76
+ }).success).toBe(false);
77
+ expect(candidate_calling_contract_1.candidateCallingContract.endCall.pathParams.safeParse({ callId: uuid })
78
+ .success).toBe(true);
79
+ expect(candidate_calling_contract_1.candidateCallingContract.endCall.pathParams.safeParse({
80
+ callId: 'not-a-uuid',
81
+ }).success).toBe(false);
82
+ expect(candidate_calling_contract_1.candidateCallingContract.stopQueue.pathParams.safeParse({
83
+ queueSessionId: uuid,
84
+ }).success).toBe(true);
85
+ expect(candidate_calling_contract_1.candidateCallingContract.stopQueue.pathParams.safeParse({
86
+ queueSessionId: 'not-a-uuid',
87
+ }).success).toBe(false);
88
+ expect(candidate_calling_contract_1.candidateCallingContract.reviewArtifact.pathParams.safeParse({
89
+ callId: uuid,
90
+ }).success).toBe(true);
91
+ expect(candidate_calling_contract_1.candidateCallingContract.reviewArtifact.pathParams.safeParse({
92
+ callId: 'not-a-uuid',
93
+ }).success).toBe(false);
94
+ expect(candidate_calling_contract_1.candidateCallingContract.reviewArtifact.pathParams.safeParse({
95
+ callId: uuid,
96
+ objectKey: 'private',
97
+ }).success).toBe(false);
98
+ });
99
+ it('pins every route response status set', () => {
100
+ expect(Object.keys(candidate_calling_contract_1.candidateCallingContract.availability.responses).map(Number)).toEqual([200]);
101
+ expect(Object.keys(candidate_calling_contract_1.candidateCallingContract.createQueue.responses).map(Number)).toEqual([200, 403, 404, 409, 503]);
102
+ expect(Object.keys(candidate_calling_contract_1.candidateCallingContract.activeQueue.responses).map(Number)).toEqual([200, 403]);
103
+ expect(Object.keys(candidate_calling_contract_1.candidateCallingContract.nextCandidate.responses).map(Number)).toEqual([200, 403, 404, 409, 429, 503]);
104
+ expect(Object.keys(candidate_calling_contract_1.candidateCallingContract.endCall.responses).map(Number)).toEqual([200, 403, 404, 409]);
105
+ expect(Object.keys(candidate_calling_contract_1.candidateCallingContract.stopQueue.responses).map(Number)).toEqual([200, 403, 404, 409]);
106
+ expect(Object.keys(candidate_calling_contract_1.candidateCallingContract.reviewArtifact.responses).map(Number)).toEqual([200, 403, 404, 409, 410]);
107
+ expect(Object.keys(candidate_calling_contract_1.candidateCallingContract.getCallReview.responses).map(Number)).toEqual([200, 403, 404]);
108
+ expect(Object.keys(candidate_calling_contract_1.candidateCallingContract.resolveProfileFact.responses).map(Number)).toEqual([200, 403, 404, 409]);
109
+ });
110
+ it('uses strict end intent and complete managed states', () => {
111
+ expect(candidate_calling_contract_1.candidateCallingContract.endCall.body.safeParse({
112
+ continueWithNext: true,
113
+ extra: true,
114
+ }).success).toBe(false);
115
+ expect(candidate_calling_contract_1.CandidateDialpadCallStatusSchema.options).toEqual([
116
+ 'CLAIMED',
117
+ 'INITIATING',
118
+ 'INITIATION_UNCERTAIN',
119
+ 'RINGING',
120
+ 'CONNECTED',
121
+ 'ENDING',
122
+ 'PROCESSING',
123
+ 'FEEDBACK_RECORDED',
124
+ 'NEEDS_REVIEW',
125
+ 'INITIATION_FAILED',
126
+ 'CANCELLED',
127
+ ]);
128
+ });
129
+ it('accepts only live queue, historical import, and automatic probe call sources', () => {
130
+ expect(candidate_calling_contract_1.CandidateDialpadCallSourceSchema.safeParse('LIVE_QUEUE').success).toBe(true);
131
+ expect(candidate_calling_contract_1.CandidateDialpadCallSourceSchema.safeParse('HISTORICAL_IMPORT').success).toBe(true);
132
+ expect(candidate_calling_contract_1.CandidateDialpadCallSourceSchema.safeParse('AUTOMATIC_PROBE').success).toBe(true);
133
+ expect(candidate_calling_contract_1.CandidateDialpadCallSourceSchema.safeParse('MANUAL_IMPORT').success).toBe(false);
134
+ });
135
+ it('keeps candidate and active-queue wrappers strict', () => {
136
+ const candidate = {
137
+ subjectKind: 'OWNED',
138
+ card: {
139
+ id: '77777777-7777-4777-8777-777777777777',
140
+ firstName: 'Ana',
141
+ hasTools: true,
142
+ hasPpe: true,
143
+ offerOpenness: 'OPEN',
144
+ createdAt: '2026-08-19T10:00:00.000Z',
145
+ updatedAt: '2026-08-19T10:00:00.000Z',
146
+ hasPhoneNumber: true,
147
+ },
148
+ };
149
+ expect(candidate_calling_contract_1.CandidateCallingCandidateSchema.options[0].safeParse(candidate).success).toBe(true);
150
+ expect(candidate_calling_contract_1.CandidateCallingCandidateSchema.options[0].safeParse({
151
+ ...candidate,
152
+ extra: true,
153
+ }).success).toBe(false);
154
+ expect(candidate_calling_contract_1.candidateCallingContract.activeQueue.responses[200].safeParse({
155
+ queue: null,
156
+ extra: true,
157
+ }).success).toBe(false);
158
+ });
159
+ it('does not expose provider or artifact secrets', () => {
160
+ const candidate = candidate_calling_contract_1.CandidateCallingCandidateSchema.parse({
161
+ subjectKind: 'OWNED',
162
+ card: {
163
+ id: '77777777-7777-4777-8777-777777777777',
164
+ firstName: 'Ana',
165
+ hasTools: true,
166
+ hasPpe: true,
167
+ offerOpenness: 'OPEN',
168
+ createdAt: '2026-08-19T10:00:00.000Z',
169
+ updatedAt: '2026-08-19T10:00:00.000Z',
170
+ hasPhoneNumber: true,
171
+ phone: '+441234567890',
172
+ phoneNumbers: [{ phoneNumber: '+441234567890' }],
173
+ },
174
+ });
175
+ expect(candidate.card).not.toHaveProperty('phone');
176
+ expect(candidate.card).not.toHaveProperty('phoneNumbers');
177
+ const parsed = candidate_calling_contract_1.CandidateCallingQueueViewSchema.parse({
178
+ id: '55555555-5555-4555-8555-555555555555',
179
+ jobId: '66666666-6666-4666-8666-666666666666',
180
+ status: 'PAUSED',
181
+ pauseReason: 'AGENT_ENDED',
182
+ eligibleCount: 0,
183
+ sandbox: { enabled: true, maskedDestination: '******1234' },
184
+ currentCall: null,
185
+ recentCalls: [],
186
+ retryAt: null,
187
+ createdAt: '2026-08-19T10:00:00.000Z',
188
+ updatedAt: '2026-08-19T10:00:00.000Z',
189
+ });
190
+ expect(parsed).not.toHaveProperty('dialpadToken');
191
+ expect(parsed).not.toHaveProperty('recordingUrl');
192
+ expect(parsed).not.toHaveProperty('transcript');
193
+ });
194
+ it('keeps the on-demand review response strict and private by shape', () => {
195
+ const response = {
196
+ url: 'https://private.example.test/signed-review',
197
+ expiresAt: '2026-08-19T12:05:00.000Z',
198
+ };
199
+ expect(candidate_calling_contract_1.CandidateCallReviewArtifactResponseSchema.parse(response)).toEqual(response);
200
+ expect(candidate_calling_contract_1.CandidateCallReviewArtifactResponseSchema.safeParse({
201
+ ...response,
202
+ objectKey: 'candidate-calls/private/recording',
203
+ }).success).toBe(false);
204
+ expect(candidate_calling_contract_1.CandidateCallReviewArtifactResponseSchema.safeParse({
205
+ ...response,
206
+ transcript: 'private transcript',
207
+ }).success).toBe(false);
208
+ expect(candidate_calling_contract_1.CandidateCallReviewArtifactResponseSchema.safeParse({
209
+ ...response,
210
+ modelOutput: { outcome: 'INTERESTED' },
211
+ }).success).toBe(false);
212
+ });
213
+ it('models the complete profile fact and typed analysis review results', () => {
214
+ const response = {
215
+ workerState: { result: { kind: 'ACTIVELY_LOOKING' } },
216
+ jobs: [{ jobId: '11111111-1111-4111-8111-111111111111' }],
217
+ profileFacts: [
218
+ 'APPLIED',
219
+ 'CONFLICT',
220
+ 'PENDING',
221
+ 'FAILED',
222
+ 'OVERRIDDEN',
223
+ 'ALREADY_AGREES',
224
+ 'PENDING_REVIEW',
225
+ 'SUPERSEDED',
226
+ ].map((status) => ({
227
+ field: 'englishLevel',
228
+ value: 'ADVANCED',
229
+ status,
230
+ agentValue: 'BASIC',
231
+ evidence: ['She said her English is very good'],
232
+ evidenceReferences: [
233
+ {
234
+ quote: 'She said her English is very good',
235
+ turnId: null,
236
+ startMs: null,
237
+ endMs: null,
238
+ },
239
+ ],
240
+ })),
241
+ referral: null,
242
+ callback: null,
243
+ reviewReason: null,
244
+ employmentObservation: {
245
+ status: 'WORKING',
246
+ elapsedDuration: { value: 2, unit: 'WEEK' },
247
+ confidence: 0.92,
248
+ evidence: ['She has worked there for two weeks'],
249
+ },
250
+ phoneAssessment: {
251
+ result: 'CONFIRMED_WORKER',
252
+ confidence: 0.97,
253
+ evidence: ['The worker confirmed their identity'],
254
+ },
255
+ };
256
+ expect(candidate_calling_contract_1.CandidateCallReviewResponseSchema.parse(response)).toEqual(response);
257
+ const legacyProfileFactResponse = {
258
+ ...response,
259
+ profileFacts: response.profileFacts.map(({ evidenceReferences: _evidenceReferences, ...fact }) => fact),
260
+ };
261
+ expect(candidate_calling_contract_1.CandidateCallReviewResponseSchema.parse(legacyProfileFactResponse)).toEqual(legacyProfileFactResponse);
262
+ expect(candidate_calling_contract_1.CandidateCallProfileFactStatusSchema.safeParse('SUPERSEDED').success).toBe(true);
263
+ expect(candidate_calling_contract_1.CandidateCallReviewResponseSchema.safeParse({
264
+ ...response,
265
+ extra: true,
266
+ }).success).toBe(false);
267
+ expect(candidate_calling_contract_1.CandidateCallReviewResponseSchema.safeParse({
268
+ ...response,
269
+ profileFacts: [{ ...response.profileFacts[0], status: 'NOT_A_STATUS' }],
270
+ }).success).toBe(false);
271
+ });
272
+ it('accepts only inbound and outbound Dialpad call directions', () => {
273
+ expect(candidate_calling_contract_1.CandidateDialpadCallDirectionSchema.parse('INBOUND')).toBe('INBOUND');
274
+ expect(candidate_calling_contract_1.CandidateDialpadCallDirectionSchema.parse('OUTBOUND')).toBe('OUTBOUND');
275
+ expect(candidate_calling_contract_1.CandidateDialpadCallDirectionSchema.safeParse('SIDEWAYS').success).toBe(false);
276
+ });
277
+ it('parses timed and legacy-normalized transcript rows and rejects invalid timings', () => {
278
+ const timedTranscript = {
279
+ outcome: 'TRANSCRIPT',
280
+ languages: ['en', 'ro'],
281
+ turns: [
282
+ {
283
+ id: 'turn-0001',
284
+ speaker: 'AGENT',
285
+ text: 'Hello, this is Lorena.',
286
+ startMs: 840,
287
+ endMs: 2470,
288
+ },
289
+ ],
290
+ };
291
+ expect(candidate_calling_contract_1.CandidateDialpadCallTranscriptResponseSchema.parse(timedTranscript)).toEqual(timedTranscript);
292
+ expect(candidate_calling_contract_1.CandidateDialpadCallTranscriptResponseSchema.parse({
293
+ ...timedTranscript,
294
+ turns: [{ ...timedTranscript.turns[0], startMs: null, endMs: null }],
295
+ })).toBeDefined();
296
+ expect(() => candidate_calling_contract_1.CandidateDialpadCallTranscriptResponseSchema.parse({
297
+ ...timedTranscript,
298
+ turns: [{ ...timedTranscript.turns[0], startMs: -1 }],
299
+ })).toThrow();
300
+ expect(() => candidate_calling_contract_1.CandidateDialpadCallTranscriptResponseSchema.parse({
301
+ ...timedTranscript,
302
+ turns: [{ ...timedTranscript.turns[0], startMs: 840.5 }],
303
+ })).toThrow();
304
+ });
305
+ it('parses linked and unlinked evidence and rejects incomplete or reversed links', () => {
306
+ expect(candidate_calling_contract_1.CandidateCallReviewEvidenceSchema.parse({
307
+ quote: 'I can start on Monday.',
308
+ turnId: 'turn-0007',
309
+ startMs: 18200,
310
+ endMs: 19540,
311
+ })).toBeDefined();
312
+ expect(candidate_calling_contract_1.CandidateCallReviewEvidenceSchema.parse({
313
+ quote: 'I can start on Monday.',
314
+ turnId: null,
315
+ startMs: null,
316
+ endMs: null,
317
+ })).toBeDefined();
318
+ expect(() => candidate_calling_contract_1.CandidateCallReviewEvidenceSchema.parse({
319
+ quote: 'I can start on Monday.',
320
+ turnId: 'turn-0007',
321
+ startMs: null,
322
+ endMs: null,
323
+ })).toThrow();
324
+ expect(() => candidate_calling_contract_1.CandidateCallReviewEvidenceSchema.parse({
325
+ quote: 'I can start on Monday.',
326
+ turnId: 'turn-0007',
327
+ startMs: 19540,
328
+ endMs: 18200,
329
+ })).toThrow();
330
+ });
331
+ it('accepts only KEEP_AGENT or APPLY_AI as a profile-fact resolution', () => {
332
+ expect(candidate_calling_contract_1.ResolveProfileFactBodySchema.safeParse({ resolution: 'APPLY_AI' })
333
+ .success).toBe(true);
334
+ expect(candidate_calling_contract_1.ResolveProfileFactBodySchema.safeParse({ resolution: 'KEEP_AGENT' })
335
+ .success).toBe(true);
336
+ expect(candidate_calling_contract_1.ResolveProfileFactBodySchema.safeParse({ resolution: 'DISCARD' }).success).toBe(false);
337
+ expect(candidate_calling_contract_1.ResolveProfileFactBodySchema.safeParse({
338
+ resolution: 'APPLY_AI',
339
+ extra: true,
340
+ }).success).toBe(false);
341
+ });
342
+ it('publishes only queue identity and change time', () => {
343
+ const payload = {
344
+ queueSessionId: '55555555-5555-4555-8555-555555555555',
345
+ updatedAt: '2026-08-19T12:00:00.000Z',
346
+ };
347
+ expect(candidate_calling_contract_1.CandidateCallingQueueChangedSchema.parse(payload)).toEqual(payload);
348
+ expect(candidate_calling_contract_1.CandidateCallingQueueChangedSchema.safeParse({
349
+ ...payload,
350
+ phoneNumber: '+447700900123',
351
+ }).success).toBe(false);
352
+ expect(candidate_calling_contract_1.CandidateCallingQueueChangedSchema.safeParse({
353
+ ...payload,
354
+ transcript: 'private transcript',
355
+ }).success).toBe(false);
356
+ });
357
+ });
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ export declare const CandidateDialpadCallStatusSchema: z.ZodEnum<["CLAIMED", "INITIATING", "INITIATION_UNCERTAIN", "RINGING", "CONNECTED", "ENDING", "PROCESSING", "FEEDBACK_RECORDED", "NEEDS_REVIEW", "INITIATION_FAILED", "CANCELLED"]>;
3
+ export type CandidateDialpadCallStatus = z.infer<typeof CandidateDialpadCallStatusSchema>;
4
+ export declare const CandidateDialpadCallSourceSchema: z.ZodEnum<["LIVE_QUEUE", "HISTORICAL_IMPORT", "AUTOMATIC_PROBE"]>;
5
+ export type CandidateDialpadCallSource = z.infer<typeof CandidateDialpadCallSourceSchema>;
6
+ export declare const CandidateDialpadCallDirectionSchema: z.ZodEnum<["INBOUND", "OUTBOUND"]>;
7
+ export type CandidateDialpadCallDirection = z.infer<typeof CandidateDialpadCallDirectionSchema>;
8
+ export declare const CandidateContactHistoryConnectionSchema: z.ZodEnum<["CONNECTED", "NO_ANSWER", "BUSY", "INVALID_NUMBER", "FAILED"]>;
9
+ export type CandidateContactHistoryConnection = z.infer<typeof CandidateContactHistoryConnectionSchema>;
10
+ //# sourceMappingURL=candidate-dialpad-call.schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidate-dialpad-call.schemas.d.ts","sourceRoot":"","sources":["../../contracts/candidate-calling/candidate-dialpad-call.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gCAAgC,qLAY3C,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAC9C,OAAO,gCAAgC,CACxC,CAAC;AAEF,eAAO,MAAM,gCAAgC,mEAI3C,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAC9C,OAAO,gCAAgC,CACxC,CAAC;AAEF,eAAO,MAAM,mCAAmC,oCAG9C,CAAC;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CACjD,OAAO,mCAAmC,CAC3C,CAAC;AAEF,eAAO,MAAM,uCAAuC,2EAMlD,CAAC;AACH,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CACrD,OAAO,uCAAuC,CAC/C,CAAC"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CandidateContactHistoryConnectionSchema = exports.CandidateDialpadCallDirectionSchema = exports.CandidateDialpadCallSourceSchema = exports.CandidateDialpadCallStatusSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.CandidateDialpadCallStatusSchema = zod_1.z.enum([
6
+ 'CLAIMED',
7
+ 'INITIATING',
8
+ 'INITIATION_UNCERTAIN',
9
+ 'RINGING',
10
+ 'CONNECTED',
11
+ 'ENDING',
12
+ 'PROCESSING',
13
+ 'FEEDBACK_RECORDED',
14
+ 'NEEDS_REVIEW',
15
+ 'INITIATION_FAILED',
16
+ 'CANCELLED',
17
+ ]);
18
+ exports.CandidateDialpadCallSourceSchema = zod_1.z.enum([
19
+ 'LIVE_QUEUE',
20
+ 'HISTORICAL_IMPORT',
21
+ 'AUTOMATIC_PROBE',
22
+ ]);
23
+ exports.CandidateDialpadCallDirectionSchema = zod_1.z.enum([
24
+ 'INBOUND',
25
+ 'OUTBOUND',
26
+ ]);
27
+ exports.CandidateContactHistoryConnectionSchema = zod_1.z.enum([
28
+ 'CONNECTED',
29
+ 'NO_ANSWER',
30
+ 'BUSY',
31
+ 'INVALID_NUMBER',
32
+ 'FAILED',
33
+ ]);