@dakkitor/api-contracts 1.7.0 → 1.8.0

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 (191) hide show
  1. package/dist/abilities/abilities.contract.spec.js +39 -19
  2. package/dist/abilities/interconnection.abilities.json +6 -0
  3. package/dist/abilities/outreach.abilities.json +0 -7
  4. package/dist/abilities/second-agent.abilities.json +2 -91
  5. package/dist/abilities/team-leads.json +1 -0
  6. package/dist/abilities/worker-curator.abilities.json +2 -0
  7. package/dist/actives/actives.contract.d.ts +2562 -2515
  8. package/dist/actives/actives.contract.d.ts.map +1 -1
  9. package/dist/agent-client-links/agent-client-links.contract.d.ts +908 -908
  10. package/dist/auth/auth.contract.d.ts +50 -44
  11. package/dist/auth/auth.contract.d.ts.map +1 -1
  12. package/dist/auth/auth.contract.js +1 -0
  13. package/dist/bookings/backdate-guard.spec.d.ts +2 -0
  14. package/dist/bookings/backdate-guard.spec.d.ts.map +1 -0
  15. package/dist/bookings/backdate-guard.spec.js +80 -0
  16. package/dist/bookings/bookings.contract.d.ts +4918 -4824
  17. package/dist/bookings/bookings.contract.d.ts.map +1 -1
  18. package/dist/bookings/bookings.contract.js +26 -2
  19. package/dist/call-history/call-history.contract.d.ts +434 -434
  20. package/dist/calls-feed/calls-feed.contract.d.ts +70 -70
  21. package/dist/client-contacts/client-contacts.contract.d.ts +290 -290
  22. package/dist/clients/clients.contract.d.ts +110 -110
  23. package/dist/collaboration-checkings/collaboration-checkings.contract.d.ts +1412 -1412
  24. package/dist/collaborations/collaborations.contract.d.ts +1278 -1278
  25. package/dist/common/common-schemas.d.ts +13 -13
  26. package/dist/common/common-schemas.d.ts.map +1 -1
  27. package/dist/common/common-schemas.js +1 -0
  28. package/dist/common/nino.d.ts +8 -0
  29. package/dist/common/nino.d.ts.map +1 -0
  30. package/dist/common/nino.js +26 -0
  31. package/dist/common/nino.spec.d.ts +2 -0
  32. package/dist/common/nino.spec.d.ts.map +1 -0
  33. package/dist/common/nino.spec.js +32 -0
  34. package/dist/companies/companies.contract.d.ts +30 -30
  35. package/dist/crews/crews.contract.d.ts +300 -300
  36. package/dist/cron-executions/cron-executions.contract.d.ts +19 -6
  37. package/dist/cron-executions/cron-executions.contract.d.ts.map +1 -1
  38. package/dist/cron-executions/cron-executions.contract.js +1 -0
  39. package/dist/cron-executions/cron-executions.contract.spec.d.ts +2 -0
  40. package/dist/cron-executions/cron-executions.contract.spec.d.ts.map +1 -0
  41. package/dist/cron-executions/cron-executions.contract.spec.js +27 -0
  42. package/dist/curated-worker-leads/candidate-booking-date-fields.spec.d.ts +2 -0
  43. package/dist/curated-worker-leads/candidate-booking-date-fields.spec.d.ts.map +1 -0
  44. package/dist/curated-worker-leads/candidate-booking-date-fields.spec.js +59 -0
  45. package/dist/curated-worker-leads/candidate-coordination.contract.d.ts +1255 -1188
  46. package/dist/curated-worker-leads/candidate-coordination.contract.d.ts.map +1 -1
  47. package/dist/curated-worker-leads/candidate-coordination.contract.js +22 -6
  48. package/dist/curated-worker-leads/candidate-coordination.contract.spec.js +11 -0
  49. package/dist/curated-worker-leads/candidate-edit-session.contract.d.ts +347 -304
  50. package/dist/curated-worker-leads/candidate-edit-session.contract.d.ts.map +1 -1
  51. package/dist/curated-worker-leads/contact-history.spec.js +1 -0
  52. package/dist/curated-worker-leads/curated-worker-lead-config.contract.d.ts +2 -85
  53. package/dist/curated-worker-leads/curated-worker-lead-config.contract.d.ts.map +1 -1
  54. package/dist/curated-worker-leads/curated-worker-lead-config.contract.js +17 -41
  55. package/dist/curated-worker-leads/curated-worker-lead-config.contract.spec.d.ts +2 -0
  56. package/dist/curated-worker-leads/curated-worker-lead-config.contract.spec.d.ts.map +1 -0
  57. package/dist/curated-worker-leads/curated-worker-lead-config.contract.spec.js +30 -0
  58. package/dist/curated-worker-leads/job-feed-match-counts.contract.spec.js +30 -0
  59. package/dist/curated-worker-leads/jobs-tab.contract.d.ts +6058 -5381
  60. package/dist/curated-worker-leads/jobs-tab.contract.d.ts.map +1 -1
  61. package/dist/curated-worker-leads/jobs-tab.contract.js +64 -12
  62. package/dist/curated-worker-leads/owned-jobs-tab.contract.d.ts +88 -88
  63. package/dist/curated-workers/curated-workers.contract.d.ts +1173 -962
  64. package/dist/curated-workers/curated-workers.contract.d.ts.map +1 -1
  65. package/dist/curated-workers/curated-workers.contract.js +37 -6
  66. package/dist/dashboards/dashboard-widgets.contract.d.ts +43 -73
  67. package/dist/dashboards/dashboard-widgets.contract.d.ts.map +1 -1
  68. package/dist/dashboards/dashboard-widgets.contract.js +1 -11
  69. package/dist/dashboards/dashboard-widgets.retirement.spec.d.ts +2 -0
  70. package/dist/dashboards/dashboard-widgets.retirement.spec.d.ts.map +1 -0
  71. package/dist/dashboards/dashboard-widgets.retirement.spec.js +22 -0
  72. package/dist/document-intake/document-intake.automation.spec.d.ts +2 -0
  73. package/dist/document-intake/document-intake.automation.spec.d.ts.map +1 -0
  74. package/dist/document-intake/document-intake.automation.spec.js +469 -0
  75. package/dist/document-intake/document-intake.card-side.spec.d.ts +2 -0
  76. package/dist/document-intake/document-intake.card-side.spec.d.ts.map +1 -0
  77. package/dist/document-intake/document-intake.card-side.spec.js +51 -0
  78. package/dist/document-intake/document-intake.contract.d.ts +9421 -1071
  79. package/dist/document-intake/document-intake.contract.d.ts.map +1 -1
  80. package/dist/document-intake/document-intake.contract.js +219 -5
  81. package/dist/document-intake/document-intake.contract.spec.d.ts +2 -0
  82. package/dist/document-intake/document-intake.contract.spec.d.ts.map +1 -0
  83. package/dist/document-intake/document-intake.contract.spec.js +37 -0
  84. package/dist/document-intake/document-intake.nino.spec.d.ts +2 -0
  85. package/dist/document-intake/document-intake.nino.spec.d.ts.map +1 -0
  86. package/dist/document-intake/document-intake.nino.spec.js +42 -0
  87. package/dist/export-jobs/export-jobs.contract.d.ts +426 -426
  88. package/dist/files/files.contract.d.ts +36 -36
  89. package/dist/index.d.ts +17 -9
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +17 -9
  92. package/dist/job-clusters/job-clusters.contract.d.ts +52 -52
  93. package/dist/jobs/jobs.contract.d.ts +3610 -3610
  94. package/dist/kpi-impersonation/kpi-impersonation.contract.d.ts +56 -56
  95. package/dist/lead-assignments/lead-assignments.contract.d.ts +706 -706
  96. package/dist/lead-distribution/agent-lead-distribution.contract.d.ts +220 -220
  97. package/dist/lead-distribution/lead-distribution-config.contract.d.ts +10 -10
  98. package/dist/leads/leads.contract.d.ts +86 -86
  99. package/dist/locations/locations.contract.d.ts +46 -46
  100. package/dist/notifications/notifications.contract.d.ts +18 -18
  101. package/dist/offices/offices.contract.d.ts +24 -24
  102. package/dist/outreach/__tests__/outreach-contract-additions.spec.js +27 -0
  103. package/dist/outreach/lab-outreach.contract.d.ts +48 -48
  104. package/dist/outreach/outreach-requests.contract.d.ts +272 -272
  105. package/dist/outreach/outreach-requests.schemas.d.ts +14 -14
  106. package/dist/outreach/outreach.contract.d.ts +12 -12
  107. package/dist/outreach/outreach.schemas.d.ts +2 -2
  108. package/dist/outreach/relay-hub-outreach.contract.d.ts +1156 -0
  109. package/dist/outreach/relay-hub-outreach.contract.d.ts.map +1 -0
  110. package/dist/outreach/relay-hub-outreach.contract.js +103 -0
  111. package/dist/outreach/relay-hub-outreach.contract.spec.d.ts +2 -0
  112. package/dist/outreach/relay-hub-outreach.contract.spec.d.ts.map +1 -0
  113. package/dist/outreach/relay-hub-outreach.contract.spec.js +119 -0
  114. package/dist/own-research/own-research.contract.d.ts +708 -708
  115. package/dist/proofs/proofs.contract.d.ts +196 -196
  116. package/dist/proofs/proofs.dtos.d.ts +104 -104
  117. package/dist/qualifications/qualifications.contract.d.ts +22 -22
  118. package/dist/realtime/realtime-telemetry.contract.d.ts +181 -0
  119. package/dist/realtime/realtime-telemetry.contract.d.ts.map +1 -0
  120. package/dist/realtime/realtime-telemetry.contract.js +81 -0
  121. package/dist/realtime/realtime-telemetry.contract.spec.d.ts +2 -0
  122. package/dist/realtime/realtime-telemetry.contract.spec.d.ts.map +1 -0
  123. package/dist/realtime/realtime-telemetry.contract.spec.js +41 -0
  124. package/dist/relay-pods/build-relay-pod-membership-rules.d.ts +9 -0
  125. package/dist/relay-pods/build-relay-pod-membership-rules.d.ts.map +1 -0
  126. package/dist/relay-pods/build-relay-pod-membership-rules.js +17 -0
  127. package/dist/relay-pods/build-relay-pod-membership-rules.spec.d.ts +2 -0
  128. package/dist/relay-pods/build-relay-pod-membership-rules.spec.d.ts.map +1 -0
  129. package/dist/relay-pods/build-relay-pod-membership-rules.spec.js +20 -0
  130. package/dist/relay-pods/relay-hub.contract.d.ts +1463 -0
  131. package/dist/relay-pods/relay-hub.contract.d.ts.map +1 -0
  132. package/dist/relay-pods/relay-hub.contract.js +140 -0
  133. package/dist/relay-pods/relay-hub.contract.spec.d.ts +2 -0
  134. package/dist/relay-pods/relay-hub.contract.spec.d.ts.map +1 -0
  135. package/dist/relay-pods/relay-hub.contract.spec.js +180 -0
  136. package/dist/relay-pods/relay-hub.schemas.d.ts +577 -0
  137. package/dist/relay-pods/relay-hub.schemas.d.ts.map +1 -0
  138. package/dist/relay-pods/relay-hub.schemas.js +158 -0
  139. package/dist/relay-pods/relay-lab-fleet.contract.d.ts +115 -86
  140. package/dist/relay-pods/relay-lab-fleet.contract.d.ts.map +1 -1
  141. package/dist/relay-pods/relay-lab-fleet.contract.spec.js +16 -0
  142. package/dist/relay-pods/relay-lab-fleet.schemas.d.ts +87 -58
  143. package/dist/relay-pods/relay-lab-fleet.schemas.d.ts.map +1 -1
  144. package/dist/relay-pods/relay-lab-fleet.schemas.js +22 -5
  145. package/dist/{curated-worker-leads/lead-agent-area.contract.d.ts → relay-pods/relay-pod-members.contract.d.ts} +233 -126
  146. package/dist/relay-pods/relay-pod-members.contract.d.ts.map +1 -0
  147. package/dist/relay-pods/relay-pod-members.contract.js +73 -0
  148. package/dist/relay-pods/relay-pod-sessions.contract.d.ts +58 -58
  149. package/dist/relay-pods/relay-pods.contract.d.ts +169 -169
  150. package/dist/relay-pods/relay-pods.schemas.d.ts +46 -46
  151. package/dist/shared/summary-schemas.d.ts +10 -10
  152. package/dist/sheets-sync/__tests__/sheets-sync-events.schemas.test.js +22 -2
  153. package/dist/sheets-sync/sheets-sync-events.schemas.d.ts +30 -0
  154. package/dist/sheets-sync/sheets-sync-events.schemas.d.ts.map +1 -1
  155. package/dist/sheets-sync/sheets-sync-events.schemas.js +16 -1
  156. package/dist/sheets-sync/sheets-sync.contract.d.ts +829 -262
  157. package/dist/sheets-sync/sheets-sync.contract.d.ts.map +1 -1
  158. package/dist/sheets-sync/sheets-sync.contract.js +156 -34
  159. package/dist/telegram/telegram.contract.d.ts +12 -12
  160. package/dist/trades/trades.contract.d.ts +16 -16
  161. package/dist/user-access-grants/user-access-grants.contract.d.ts +226 -226
  162. package/dist/users/__tests__/assignable-roles.spec.js +1 -1
  163. package/dist/users/users.contract.d.ts +327 -325
  164. package/dist/users/users.contract.d.ts.map +1 -1
  165. package/dist/users/users.contract.js +10 -7
  166. package/dist/users/users.contract.spec.js +15 -0
  167. package/dist/voice-screener/voice-screener.contract.d.ts +237 -0
  168. package/dist/voice-screener/voice-screener.contract.d.ts.map +1 -0
  169. package/dist/voice-screener/voice-screener.contract.js +89 -0
  170. package/dist/worker-identity-cases/worker-identity-cases.contract.d.ts +500 -260
  171. package/dist/worker-identity-cases/worker-identity-cases.contract.d.ts.map +1 -1
  172. package/dist/worker-identity-cases/worker-identity-cases.contract.js +17 -1
  173. package/dist/worker-merge-proposals/worker-merge-proposals.contract.d.ts +130 -130
  174. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.d.ts +35 -35
  175. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.schemas.d.ts +15 -15
  176. package/dist/workers/do-not-contact.contract.d.ts +4 -4
  177. package/dist/workers/qualification-back-proof.spec.d.ts +2 -0
  178. package/dist/workers/qualification-back-proof.spec.d.ts.map +1 -0
  179. package/dist/workers/qualification-back-proof.spec.js +39 -0
  180. package/dist/workers/workers.contract.d.ts +1969 -1775
  181. package/dist/workers/workers.contract.d.ts.map +1 -1
  182. package/dist/workers/workers.contract.js +5 -0
  183. package/package.json +1 -1
  184. package/dist/curated-worker-leads/consent-queue.contract.d.ts +0 -4527
  185. package/dist/curated-worker-leads/consent-queue.contract.d.ts.map +0 -1
  186. package/dist/curated-worker-leads/consent-queue.contract.js +0 -201
  187. package/dist/curated-worker-leads/curated-worker-leads.contract.d.ts +0 -135
  188. package/dist/curated-worker-leads/curated-worker-leads.contract.d.ts.map +0 -1
  189. package/dist/curated-worker-leads/curated-worker-leads.contract.js +0 -32
  190. package/dist/curated-worker-leads/lead-agent-area.contract.d.ts.map +0 -1
  191. package/dist/curated-worker-leads/lead-agent-area.contract.js +0 -51
@@ -0,0 +1,469 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const bun_test_1 = require("bun:test");
37
+ const DocumentIntakeContract = __importStar(require("./document-intake.contract"));
38
+ const document_intake_contract_1 = require("./document-intake.contract");
39
+ const RECORD_ID = '11111111-1111-4111-8111-111111111111';
40
+ const FILE_ID = '22222222-2222-4222-8222-222222222222';
41
+ const SUBJECT_ID = '33333333-3333-4333-8333-333333333333';
42
+ const AUTO_DECISION = {
43
+ outcome: 'AUTO_APPLY',
44
+ reasonCodes: [],
45
+ policyVersion: 'document-auto-apply-v1',
46
+ mode: 'LIVE',
47
+ evaluatedSourceHash: 'a'.repeat(64),
48
+ evaluatedAt: '2026-08-16T12:00:00.000Z',
49
+ };
50
+ const FIELD_DECISION = {
51
+ field: 'firstName',
52
+ status: 'ELIGIBLE',
53
+ confidences: [0.95, 1],
54
+ evidenceTags: [['HOLDER_IDENTITY_PANEL'], ['HOLDER_IDENTITY_PANEL']],
55
+ validationReasons: [],
56
+ };
57
+ const EXTRACTED_FIELDS = {
58
+ documentType: 'qualification_certificate',
59
+ firstName: null,
60
+ lastName: null,
61
+ dateOfBirth: null,
62
+ expiryDate: null,
63
+ issueDate: null,
64
+ referenceNumber: null,
65
+ shareCode: null,
66
+ nino: null,
67
+ nationality: null,
68
+ confidence: 0,
69
+ };
70
+ const PARTIAL_READING = {
71
+ readingOrdinal: 1,
72
+ reading: {
73
+ documentType: {
74
+ value: 'cscs_card',
75
+ confidence: 0.99,
76
+ evidence: ['HOLDER_IDENTITY_PANEL'],
77
+ },
78
+ firstName: { value: 'Bounded', confidence: 0.98, evidence: [] },
79
+ lastName: { value: null, confidence: 0.7, evidence: [] },
80
+ dateOfBirth: { value: null, confidence: 0.7, evidence: [] },
81
+ expiryDate: {
82
+ value: '2027-01-01',
83
+ confidence: 0.97,
84
+ evidence: ['REGISTRATION_AND_EXPIRY_PANEL'],
85
+ },
86
+ issueDate: { value: null, confidence: 0.7, evidence: [] },
87
+ referenceNumber: { value: null, confidence: 0.7, evidence: [] },
88
+ shareCode: { value: null, confidence: 0.7, evidence: [] },
89
+ nino: { value: null, confidence: 0.7, evidence: [] },
90
+ nationality: { value: null, confidence: 0.7, evidence: [] },
91
+ qualificationName: { value: null, confidence: 0.7, evidence: [] },
92
+ qualificationTypeName: {
93
+ value: null,
94
+ confidence: 0.7,
95
+ evidence: [],
96
+ },
97
+ qualificationIssuerText: {
98
+ value: null,
99
+ confidence: 0.7,
100
+ evidence: [],
101
+ },
102
+ qualificationCardColour: {
103
+ value: null,
104
+ confidence: 0.7,
105
+ evidence: [],
106
+ },
107
+ qualificationRoleText: {
108
+ value: null,
109
+ confidence: 0.7,
110
+ evidence: [],
111
+ },
112
+ cardSide: { value: null, confidence: 0.7, evidence: [] },
113
+ cardLayout: 'SINGLE_FACE',
114
+ },
115
+ };
116
+ const INTAKE_RECORD = {
117
+ id: RECORD_ID,
118
+ fileId: FILE_ID,
119
+ workerId: SUBJECT_ID,
120
+ curatedWorkerId: null,
121
+ classification: 'qualification_certificate',
122
+ destinationSuggested: 'QUALIFICATION',
123
+ destinationFinal: null,
124
+ extracted: null,
125
+ confidence: 0,
126
+ overridden: false,
127
+ status: 'PENDING_CONFIRM',
128
+ };
129
+ const BACKFILL_SUBJECT_DOCUMENT = {
130
+ recordId: RECORD_ID,
131
+ fileId: FILE_ID,
132
+ originalName: null,
133
+ mimeType: null,
134
+ sourceType: 'QUALIFICATION_PROOF',
135
+ sourceId: RECORD_ID,
136
+ actor: 'HUMAN',
137
+ status: 'PENDING_CONFIRM',
138
+ reviewable: true,
139
+ evaluatedAt: null,
140
+ currentlyFiledAs: 'QUALIFICATION',
141
+ classification: 'qualification_certificate',
142
+ destinationSuggested: 'QUALIFICATION',
143
+ confidence: 0,
144
+ extracted: null,
145
+ currentQualificationId: null,
146
+ currentQualificationName: null,
147
+ sourceRow: null,
148
+ createdAt: '2026-08-16T12:00:00.000Z',
149
+ };
150
+ const BACKFILL_AUDIT_RECORD = {
151
+ recordId: RECORD_ID,
152
+ fileId: FILE_ID,
153
+ workerId: SUBJECT_ID,
154
+ curatedWorkerId: null,
155
+ subjectName: 'Worker',
156
+ originalName: null,
157
+ sourceType: 'QUALIFICATION_PROOF',
158
+ sourceId: RECORD_ID,
159
+ actor: 'HUMAN',
160
+ status: 'PENDING_CONFIRM',
161
+ classification: 'qualification_certificate',
162
+ confidence: 0,
163
+ failureKind: null,
164
+ evaluatedAt: null,
165
+ createdAt: '2026-08-16T12:00:00.000Z',
166
+ supersedesRecordId: null,
167
+ supersededByRecordId: null,
168
+ isCurrent: true,
169
+ extractorFingerprint: null,
170
+ evaluationFingerprint: null,
171
+ };
172
+ const automationExports = DocumentIntakeContract;
173
+ const automationSchema = (name) => {
174
+ const schema = automationExports[name];
175
+ (0, bun_test_1.expect)(schema).toBeDefined();
176
+ return schema;
177
+ };
178
+ (0, bun_test_1.describe)('document intake consensus contract', () => {
179
+ (0, bun_test_1.it)('accepts exact qualification sources and source slots', () => {
180
+ (0, bun_test_1.expect)(document_intake_contract_1.IntakeSourceTypeSchema.parse('CURATED_QUALIFICATION_PROOF')).toBe('CURATED_QUALIFICATION_PROOF');
181
+ (0, bun_test_1.expect)(automationSchema('IntakeSourceSlotSchema').options).toEqual([
182
+ 'PRIMARY',
183
+ 'BACK',
184
+ ]);
185
+ });
186
+ (0, bun_test_1.it)('accepts every field-decision status', () => {
187
+ for (const status of [
188
+ 'ELIGIBLE',
189
+ 'ABSENT',
190
+ 'ONE_SIDED',
191
+ 'LOW_CONFIDENCE',
192
+ 'DISAGREEMENT',
193
+ 'INVALID',
194
+ ]) {
195
+ (0, bun_test_1.expect)(automationSchema('DocumentFieldDecisionStatusSchema').parse(status)).toBe(status);
196
+ }
197
+ });
198
+ (0, bun_test_1.it)('accepts every automatic outcome and reason', () => {
199
+ for (const outcome of [
200
+ 'AUTO_APPLY',
201
+ 'HUMAN_REVIEW_CONFLICT',
202
+ 'HUMAN_REVIEW_INCOMPLETE_CONSENSUS',
203
+ 'HUMAN_REVIEW_LOW_CONFIDENCE',
204
+ 'HUMAN_REVIEW_DESTINATION',
205
+ 'HUMAN_REVIEW_NINO_OWNERSHIP',
206
+ 'HUMAN_REVIEW_OCCUPIED_SLOT',
207
+ 'HUMAN_REVIEW_UNSUPPORTED_CARD_SCHEME',
208
+ 'NO_CHANGE',
209
+ 'SHADOW_ONLY',
210
+ ]) {
211
+ (0, bun_test_1.expect)(automationSchema('DocumentAutoDecisionOutcomeSchema').parse(outcome)).toBe(outcome);
212
+ }
213
+ for (const reason of [
214
+ 'FIELD_CONFLICT',
215
+ 'INCOMPLETE_CONSENSUS',
216
+ 'LOW_CONFIDENCE',
217
+ 'INVALID_VALUE',
218
+ 'DESTINATION_AMBIGUOUS',
219
+ 'NINO_OWNED_BY_ANOTHER_IDENTITY',
220
+ 'QUALIFICATION_AMBIGUOUS',
221
+ 'TARGET_SLOT_OCCUPIED',
222
+ 'CARD_SCHEME_UNSUPPORTED',
223
+ 'CARD_SIDE_AMBIGUOUS',
224
+ 'MULTIPLE_CARD_FACES',
225
+ 'SOURCE_CHANGED',
226
+ 'AUTO_APPLY_DISABLED',
227
+ 'AUTO_OVERWRITE_DISABLED',
228
+ 'NO_CHANGE',
229
+ ]) {
230
+ (0, bun_test_1.expect)(automationSchema('DocumentAutoDecisionReasonSchema').parse(reason)).toBe(reason);
231
+ }
232
+ });
233
+ (0, bun_test_1.it)('accepts a privacy-safe policy fingerprint while preserving legacy decisions', () => {
234
+ const schema = automationSchema('DocumentAutoDecisionSchema');
235
+ (0, bun_test_1.expect)(schema.parse(AUTO_DECISION)).toEqual(AUTO_DECISION);
236
+ (0, bun_test_1.expect)(schema.parse({ ...AUTO_DECISION, policyFingerprint: 'b'.repeat(64) })).toEqual({ ...AUTO_DECISION, policyFingerprint: 'b'.repeat(64) });
237
+ (0, bun_test_1.expect)(schema.safeParse({ ...AUTO_DECISION, policyFingerprint: 'CSCS' }).success).toBe(false);
238
+ });
239
+ (0, bun_test_1.it)('parses controlled field decisions and rejects out-of-range confidences', () => {
240
+ (0, bun_test_1.expect)(automationSchema('DocumentFieldDecisionSchema').parse(FIELD_DECISION)).toEqual(FIELD_DECISION);
241
+ (0, bun_test_1.expect)(automationSchema('DocumentFieldDecisionSchema').safeParse({
242
+ ...FIELD_DECISION,
243
+ confidences: [-0.01, 1],
244
+ }).success).toBe(false);
245
+ (0, bun_test_1.expect)(automationSchema('DocumentFieldDecisionSchema').safeParse({
246
+ ...FIELD_DECISION,
247
+ confidences: [0.95, 1.01],
248
+ }).success).toBe(false);
249
+ });
250
+ (0, bun_test_1.it)('rejects out-of-range confidences on every exposed document response', () => {
251
+ const responseSchemas = [
252
+ { schema: document_intake_contract_1.ExtractedDocumentFieldsSchema, value: EXTRACTED_FIELDS },
253
+ { schema: document_intake_contract_1.IntakeRecordResponseSchema, value: INTAKE_RECORD },
254
+ {
255
+ schema: document_intake_contract_1.BackfillSubjectDocumentSchema,
256
+ value: BACKFILL_SUBJECT_DOCUMENT,
257
+ },
258
+ { schema: document_intake_contract_1.BackfillAuditRecordSchema, value: BACKFILL_AUDIT_RECORD },
259
+ ];
260
+ for (const confidence of [-0.1, 1.1]) {
261
+ for (const { schema, value } of responseSchemas) {
262
+ (0, bun_test_1.expect)(schema.safeParse({ ...value, confidence }).success).toBe(false);
263
+ }
264
+ }
265
+ });
266
+ (0, bun_test_1.it)('defaults omitted legacy source and review metadata', () => {
267
+ const intake = document_intake_contract_1.IntakeRecordResponseSchema.parse(INTAKE_RECORD);
268
+ (0, bun_test_1.expect)(intake.sourceSlot).toBe('PRIMARY');
269
+ (0, bun_test_1.expect)(intake.requiresIdentityReview).toBe(false);
270
+ const queue = document_intake_contract_1.BackfillSubjectSummarySchema.parse({
271
+ subjectType: 'CURATED_WORKER',
272
+ subjectId: SUBJECT_ID,
273
+ subjectName: 'Worker',
274
+ documentCount: 1,
275
+ pendingKinds: ['FILL'],
276
+ oldestDocumentAt: '2026-08-16T12:00:00.000Z',
277
+ });
278
+ (0, bun_test_1.expect)(queue.reviewReasons).toEqual([]);
279
+ const detail = document_intake_contract_1.BackfillSubjectDocumentSchema.parse(BACKFILL_SUBJECT_DOCUMENT);
280
+ (0, bun_test_1.expect)(detail.sourceSlot).toBe('PRIMARY');
281
+ (0, bun_test_1.expect)(detail.requiresIdentityReview).toBe(false);
282
+ const history = document_intake_contract_1.BackfillAuditRecordSchema.parse(BACKFILL_AUDIT_RECORD);
283
+ (0, bun_test_1.expect)(history.sourceSlot).toBe('PRIMARY');
284
+ (0, bun_test_1.expect)(history.reviewReasons).toEqual([]);
285
+ (0, bun_test_1.expect)(history.requiresIdentityReview).toBe(false);
286
+ });
287
+ (0, bun_test_1.it)('parses queue review reasons without exposing extracted values', () => {
288
+ const parsed = document_intake_contract_1.BackfillSubjectSummarySchema.parse({
289
+ subjectType: 'CURATED_WORKER',
290
+ subjectId: SUBJECT_ID,
291
+ subjectName: 'Worker',
292
+ documentCount: 1,
293
+ pendingKinds: ['FILL'],
294
+ oldestDocumentAt: '2026-08-16T12:00:00.000Z',
295
+ reviewReasons: ['CARD_SIDE_AMBIGUOUS'],
296
+ extracted: { firstName: 'Must not survive queue parsing' },
297
+ partialReading: PARTIAL_READING,
298
+ });
299
+ (0, bun_test_1.expect)(parsed).not.toHaveProperty('extracted');
300
+ (0, bun_test_1.expect)(parsed).not.toHaveProperty('partialReading');
301
+ (0, bun_test_1.expect)(parsed.reviewReasons).toEqual(['CARD_SIDE_AMBIGUOUS']);
302
+ });
303
+ (0, bun_test_1.it)('exposes one bounded partial reading only on authorized detail and history', () => {
304
+ for (const [schema, value] of [
305
+ [document_intake_contract_1.BackfillSubjectDocumentSchema, BACKFILL_SUBJECT_DOCUMENT],
306
+ [document_intake_contract_1.BackfillAuditRecordSchema, BACKFILL_AUDIT_RECORD],
307
+ ]) {
308
+ const parsed = schema.parse({
309
+ ...value,
310
+ partialReading: PARTIAL_READING,
311
+ });
312
+ (0, bun_test_1.expect)(parsed).toHaveProperty('partialReading', PARTIAL_READING);
313
+ (0, bun_test_1.expect)(schema.safeParse({
314
+ ...value,
315
+ partialReading: {
316
+ ...PARTIAL_READING,
317
+ reading: {
318
+ ...PARTIAL_READING.reading,
319
+ firstName: {
320
+ value: 'Unbounded',
321
+ confidence: 1.1,
322
+ evidence: [],
323
+ },
324
+ },
325
+ },
326
+ }).success).toBe(false);
327
+ (0, bun_test_1.expect)(schema.safeParse({
328
+ ...value,
329
+ partialReading: {
330
+ ...PARTIAL_READING,
331
+ reading: {
332
+ ...PARTIAL_READING.reading,
333
+ cardSide: {
334
+ value: 'front',
335
+ confidence: 0.9,
336
+ evidence: ['raw provider prose'],
337
+ },
338
+ },
339
+ },
340
+ }).success).toBe(false);
341
+ }
342
+ });
343
+ (0, bun_test_1.it)('parses nullable automation metadata on detail and history records', () => {
344
+ const detail = document_intake_contract_1.BackfillSubjectDocumentSchema.parse({
345
+ recordId: RECORD_ID,
346
+ fileId: FILE_ID,
347
+ originalName: null,
348
+ mimeType: null,
349
+ sourceType: 'QUALIFICATION_PROOF',
350
+ sourceId: RECORD_ID,
351
+ sourceSlot: 'PRIMARY',
352
+ actor: 'HUMAN',
353
+ status: 'VERIFIED_NO_CHANGE',
354
+ reviewable: false,
355
+ evaluatedAt: null,
356
+ currentlyFiledAs: 'QUALIFICATION',
357
+ classification: 'qualification_certificate',
358
+ destinationSuggested: 'QUALIFICATION',
359
+ confidence: null,
360
+ extracted: {
361
+ documentType: 'qualification_certificate',
362
+ firstName: null,
363
+ lastName: null,
364
+ dateOfBirth: null,
365
+ expiryDate: null,
366
+ issueDate: null,
367
+ referenceNumber: null,
368
+ shareCode: null,
369
+ nino: null,
370
+ nationality: null,
371
+ confidence: 0,
372
+ },
373
+ fieldDecisions: [],
374
+ requiresIdentityReview: false,
375
+ currentQualificationId: null,
376
+ currentQualificationName: null,
377
+ sourceRow: null,
378
+ createdAt: '2026-08-16T12:00:00.000Z',
379
+ });
380
+ (0, bun_test_1.expect)(detail).not.toHaveProperty('autoDecision');
381
+ (0, bun_test_1.expect)(detail.fieldDecisions).toEqual([]);
382
+ const history = document_intake_contract_1.BackfillAuditRecordSchema.parse({
383
+ recordId: RECORD_ID,
384
+ fileId: FILE_ID,
385
+ workerId: SUBJECT_ID,
386
+ curatedWorkerId: null,
387
+ subjectName: 'Worker',
388
+ originalName: null,
389
+ sourceType: 'CURATED_QUALIFICATION_PROOF',
390
+ sourceId: RECORD_ID,
391
+ sourceSlot: 'PRIMARY',
392
+ actor: 'AUTOMATIC',
393
+ status: 'APPLIED',
394
+ classification: 'cscs_card',
395
+ confidence: 1,
396
+ failureKind: null,
397
+ reviewReasons: [],
398
+ autoDecision: AUTO_DECISION,
399
+ fieldDecisions: [FIELD_DECISION],
400
+ consensusVersion: 'consensus-v1',
401
+ requiresIdentityReview: false,
402
+ evaluatedAt: '2026-08-16T12:00:00.000Z',
403
+ createdAt: '2026-08-16T12:00:00.000Z',
404
+ supersedesRecordId: null,
405
+ supersededByRecordId: null,
406
+ isCurrent: true,
407
+ extractorFingerprint: 'extractor-v1',
408
+ evaluationFingerprint: 'evaluation-v1',
409
+ });
410
+ (0, bun_test_1.expect)(automationSchema('DocumentAutoDecisionSchema').parse(history.autoDecision)).toEqual(AUTO_DECISION);
411
+ });
412
+ (0, bun_test_1.it)('requires legacy final-actor metadata to be omitted rather than fabricated as null', () => {
413
+ (0, bun_test_1.expect)(document_intake_contract_1.BackfillSubjectDocumentSchema.safeParse({
414
+ ...BACKFILL_SUBJECT_DOCUMENT,
415
+ actor: null,
416
+ }).success).toBe(false);
417
+ (0, bun_test_1.expect)(document_intake_contract_1.BackfillAuditRecordSchema.safeParse({
418
+ ...BACKFILL_AUDIT_RECORD,
419
+ actor: null,
420
+ }).success).toBe(false);
421
+ });
422
+ (0, bun_test_1.it)('exposes only exact source/target provenance, not document values, for authorized detail and history records', () => {
423
+ const provenance = {
424
+ before: {
425
+ kind: 'QUALIFICATION',
426
+ id: RECORD_ID,
427
+ slot: 'BACK',
428
+ fileId: null,
429
+ },
430
+ after: {
431
+ kind: 'QUALIFICATION',
432
+ id: SUBJECT_ID,
433
+ slot: 'PRIMARY',
434
+ fileId: FILE_ID,
435
+ },
436
+ };
437
+ (0, bun_test_1.expect)(automationSchema('DocumentMutationProvenanceSchema').parse(provenance)).toEqual(provenance);
438
+ (0, bun_test_1.expect)(automationSchema('DocumentReviewActorSchema').options).toEqual([
439
+ 'HUMAN',
440
+ 'AUTOMATIC',
441
+ ]);
442
+ });
443
+ (0, bun_test_1.it)('bounds authorized before/after audit changes to known document fields and preserves stored extraction metadata', () => {
444
+ const parsed = automationSchema('DocumentAuditChangeSchema').parse({
445
+ field: 'fileId',
446
+ slot: 'BACK',
447
+ from: null,
448
+ to: FILE_ID,
449
+ });
450
+ (0, bun_test_1.expect)(parsed).toMatchObject({ field: 'fileId', slot: 'BACK' });
451
+ (0, bun_test_1.expect)(automationSchema('DocumentAuditChangeSchema').safeParse({
452
+ field: 'unbounded_private_key',
453
+ from: 'before',
454
+ to: 'after',
455
+ }).success).toBe(false);
456
+ const detail = document_intake_contract_1.BackfillSubjectDocumentSchema.parse({
457
+ ...BACKFILL_SUBJECT_DOCUMENT,
458
+ actor: 'AUTOMATIC',
459
+ requiresIdentityReview: true,
460
+ auditChanges: [{ field: 'firstName', from: 'Before', to: 'After' }],
461
+ extractionModel: 'gemini-3.1-flash-lite',
462
+ promptVersion: '2026-08-16.1',
463
+ });
464
+ (0, bun_test_1.expect)(detail.requiresIdentityReview).toBe(true);
465
+ (0, bun_test_1.expect)(detail.auditChanges).toHaveLength(1);
466
+ (0, bun_test_1.expect)(detail.extractionModel).toBe('gemini-3.1-flash-lite');
467
+ (0, bun_test_1.expect)(detail.promptVersion).toBe('2026-08-16.1');
468
+ });
469
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=document-intake.card-side.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-intake.card-side.spec.d.ts","sourceRoot":"","sources":["../../contracts/document-intake/document-intake.card-side.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const bun_test_1 = require("bun:test");
4
+ const index_1 = require("../index");
5
+ const BASE_FIELDS = {
6
+ documentType: 'cscs_card',
7
+ firstName: null,
8
+ lastName: null,
9
+ dateOfBirth: null,
10
+ expiryDate: null,
11
+ issueDate: null,
12
+ referenceNumber: null,
13
+ shareCode: null,
14
+ nino: null,
15
+ nationality: null,
16
+ confidence: 0.9,
17
+ };
18
+ (0, bun_test_1.describe)('ExtractedDocumentFieldsSchema.cardSide', () => {
19
+ (0, bun_test_1.it)('accepts "front"', () => {
20
+ const parsed = index_1.ExtractedDocumentFieldsSchema.parse({
21
+ ...BASE_FIELDS,
22
+ cardSide: 'front',
23
+ });
24
+ (0, bun_test_1.expect)(parsed.cardSide).toBe('front');
25
+ });
26
+ (0, bun_test_1.it)('accepts "back"', () => {
27
+ const parsed = index_1.ExtractedDocumentFieldsSchema.parse({
28
+ ...BASE_FIELDS,
29
+ cardSide: 'back',
30
+ });
31
+ (0, bun_test_1.expect)(parsed.cardSide).toBe('back');
32
+ });
33
+ (0, bun_test_1.it)('accepts null', () => {
34
+ const parsed = index_1.ExtractedDocumentFieldsSchema.parse({
35
+ ...BASE_FIELDS,
36
+ cardSide: null,
37
+ });
38
+ (0, bun_test_1.expect)(parsed.cardSide).toBeNull();
39
+ });
40
+ (0, bun_test_1.it)('is optional (omitting it still parses)', () => {
41
+ const parsed = index_1.ExtractedDocumentFieldsSchema.parse({ ...BASE_FIELDS });
42
+ (0, bun_test_1.expect)(parsed.cardSide).toBeUndefined();
43
+ });
44
+ (0, bun_test_1.it)('rejects any other value', () => {
45
+ const result = index_1.ExtractedDocumentFieldsSchema.safeParse({
46
+ ...BASE_FIELDS,
47
+ cardSide: 'sideways',
48
+ });
49
+ (0, bun_test_1.expect)(result.success).toBe(false);
50
+ });
51
+ });