@dakkitor/api-contracts 1.1.154 → 1.4.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 (340) hide show
  1. package/dist/abilities/abilities.contract.d.ts +53 -1
  2. package/dist/abilities/abilities.contract.d.ts.map +1 -1
  3. package/dist/abilities/abilities.contract.js +92 -1
  4. package/dist/abilities/abilities.contract.spec.d.ts +2 -0
  5. package/dist/abilities/abilities.contract.spec.d.ts.map +1 -0
  6. package/dist/abilities/abilities.contract.spec.js +145 -0
  7. package/dist/abilities/admin-dashboard.abilities.test.d.ts +2 -0
  8. package/dist/abilities/admin-dashboard.abilities.test.d.ts.map +1 -0
  9. package/dist/abilities/admin-dashboard.abilities.test.js +33 -0
  10. package/dist/abilities/admin.abilities.json +19 -0
  11. package/dist/abilities/bot.abilities.json +13 -4
  12. package/dist/abilities/first-agent.abilities.json +317 -70
  13. package/dist/abilities/interconnection.abilities.json +75 -0
  14. package/dist/abilities/kpi.abilities.json +68 -0
  15. package/dist/abilities/office-manager.abilities.json +111 -0
  16. package/dist/abilities/second-agent.abilities.json +417 -43
  17. package/dist/abilities/team-leads.json +71 -6
  18. package/dist/abilities/worker-curator.abilities.json +233 -0
  19. package/dist/actives/actives.contract.d.ts +19379 -23651
  20. package/dist/actives/actives.contract.d.ts.map +1 -1
  21. package/dist/actives/actives.contract.js +517 -114
  22. package/dist/agent-client-links/agent-client-links.contract.d.ts +1431 -291
  23. package/dist/agent-client-links/agent-client-links.contract.d.ts.map +1 -1
  24. package/dist/auth/auth.contract.d.ts +1050 -81
  25. package/dist/auth/auth.contract.d.ts.map +1 -1
  26. package/dist/auth/auth.contract.js +115 -3
  27. package/dist/bookings/booking-worker-summary.spec.d.ts +2 -0
  28. package/dist/bookings/booking-worker-summary.spec.d.ts.map +1 -0
  29. package/dist/bookings/booking-worker-summary.spec.js +25 -0
  30. package/dist/bookings/bookings.contract.d.ts +20643 -26117
  31. package/dist/bookings/bookings.contract.d.ts.map +1 -1
  32. package/dist/bookings/bookings.contract.js +383 -91
  33. package/dist/bookings/bookings.contract.spec.d.ts +2 -0
  34. package/dist/bookings/bookings.contract.spec.d.ts.map +1 -0
  35. package/dist/bookings/bookings.contract.spec.js +11 -0
  36. package/dist/bookings/job-lock.spec.d.ts +2 -0
  37. package/dist/bookings/job-lock.spec.d.ts.map +1 -0
  38. package/dist/bookings/job-lock.spec.js +56 -0
  39. package/dist/bot-parse-cache/bot-parse-cache.contract.d.ts +232 -0
  40. package/dist/bot-parse-cache/bot-parse-cache.contract.d.ts.map +1 -0
  41. package/dist/bot-parse-cache/bot-parse-cache.contract.js +64 -0
  42. package/dist/call-history/call-history.contract.d.ts +1336 -767
  43. package/dist/call-history/call-history.contract.d.ts.map +1 -1
  44. package/dist/call-history/call-history.contract.js +86 -10
  45. package/dist/calls-feed/calls-feed.contract.d.ts +417 -0
  46. package/dist/calls-feed/calls-feed.contract.d.ts.map +1 -0
  47. package/dist/calls-feed/calls-feed.contract.js +32 -0
  48. package/dist/client-contacts/client-contacts.contract.d.ts +410 -226
  49. package/dist/client-contacts/client-contacts.contract.d.ts.map +1 -1
  50. package/dist/client-contacts/client-contacts.contract.js +35 -4
  51. package/dist/clients/clients.contract.d.ts +227 -73
  52. package/dist/clients/clients.contract.d.ts.map +1 -1
  53. package/dist/clients/clients.contract.js +45 -21
  54. package/dist/collaboration-checkings/collaboration-checkings.contract.d.ts +2908 -1834
  55. package/dist/collaboration-checkings/collaboration-checkings.contract.d.ts.map +1 -1
  56. package/dist/collaboration-checkings/collaboration-checkings.contract.js +14 -9
  57. package/dist/collaborations/collaborations.contract.d.ts +2676 -1409
  58. package/dist/collaborations/collaborations.contract.d.ts.map +1 -1
  59. package/dist/collaborations/collaborations.contract.js +33 -9
  60. package/dist/common/call-rating.schema.d.ts.map +1 -1
  61. package/dist/common/call-rating.schema.js +4 -2
  62. package/dist/common/common-schemas.d.ts +59 -11
  63. package/dist/common/common-schemas.d.ts.map +1 -1
  64. package/dist/common/common-schemas.js +55 -29
  65. package/dist/common/error-schemas.d.ts +2 -2
  66. package/dist/common/pagination-query.schema.d.ts +13 -2
  67. package/dist/common/pagination-query.schema.d.ts.map +1 -1
  68. package/dist/common/pagination-query.schema.js +21 -2
  69. package/dist/common/pagination-query.schema.spec.d.ts +2 -0
  70. package/dist/common/pagination-query.schema.spec.d.ts.map +1 -0
  71. package/dist/common/pagination-query.schema.spec.js +53 -0
  72. package/dist/companies/companies.contract.d.ts +53 -28
  73. package/dist/companies/companies.contract.d.ts.map +1 -1
  74. package/dist/companies/companies.contract.js +11 -10
  75. package/dist/crews/crews.contract.d.ts +1010 -196
  76. package/dist/crews/crews.contract.d.ts.map +1 -1
  77. package/dist/crews/crews.contract.js +98 -17
  78. package/dist/crews/crews.contract.spec.d.ts +2 -0
  79. package/dist/crews/crews.contract.spec.d.ts.map +1 -0
  80. package/dist/crews/crews.contract.spec.js +67 -0
  81. package/dist/cron-executions/cron-executions.contract.d.ts +988 -59
  82. package/dist/cron-executions/cron-executions.contract.d.ts.map +1 -1
  83. package/dist/cron-executions/cron-executions.contract.js +127 -7
  84. package/dist/curated-worker-leads/__tests__/disposition-reason.spec.d.ts +2 -0
  85. package/dist/curated-worker-leads/__tests__/disposition-reason.spec.d.ts.map +1 -0
  86. package/dist/curated-worker-leads/__tests__/disposition-reason.spec.js +40 -0
  87. package/dist/curated-worker-leads/candidate-coordination-snapshot.spec.d.ts +2 -0
  88. package/dist/curated-worker-leads/candidate-coordination-snapshot.spec.d.ts.map +1 -0
  89. package/dist/curated-worker-leads/candidate-coordination-snapshot.spec.js +16 -0
  90. package/dist/curated-worker-leads/candidate-coordination.contract.d.ts +21650 -0
  91. package/dist/curated-worker-leads/candidate-coordination.contract.d.ts.map +1 -0
  92. package/dist/curated-worker-leads/candidate-coordination.contract.js +921 -0
  93. package/dist/curated-worker-leads/candidate-coordination.contract.spec.d.ts +2 -0
  94. package/dist/curated-worker-leads/candidate-coordination.contract.spec.d.ts.map +1 -0
  95. package/dist/curated-worker-leads/candidate-coordination.contract.spec.js +51 -0
  96. package/dist/curated-worker-leads/candidate-edit-session.contract.d.ts +2364 -0
  97. package/dist/curated-worker-leads/candidate-edit-session.contract.d.ts.map +1 -0
  98. package/dist/curated-worker-leads/candidate-edit-session.contract.js +173 -0
  99. package/dist/curated-worker-leads/consent-queue.contract.d.ts +4497 -0
  100. package/dist/curated-worker-leads/consent-queue.contract.d.ts.map +1 -0
  101. package/dist/curated-worker-leads/consent-queue.contract.js +201 -0
  102. package/dist/curated-worker-leads/contact-history.spec.d.ts +2 -0
  103. package/dist/curated-worker-leads/contact-history.spec.d.ts.map +1 -0
  104. package/dist/curated-worker-leads/contact-history.spec.js +88 -0
  105. package/dist/curated-worker-leads/contact-session.contract.spec.d.ts +2 -0
  106. package/dist/curated-worker-leads/contact-session.contract.spec.d.ts.map +1 -0
  107. package/dist/curated-worker-leads/contact-session.contract.spec.js +315 -0
  108. package/dist/curated-worker-leads/curated-worker-lead-config.contract.d.ts +489 -0
  109. package/dist/curated-worker-leads/curated-worker-lead-config.contract.d.ts.map +1 -0
  110. package/dist/curated-worker-leads/curated-worker-lead-config.contract.js +88 -0
  111. package/dist/curated-worker-leads/curated-worker-leads.contract.d.ts +135 -0
  112. package/dist/curated-worker-leads/curated-worker-leads.contract.d.ts.map +1 -0
  113. package/dist/curated-worker-leads/curated-worker-leads.contract.js +32 -0
  114. package/dist/curated-worker-leads/job-candidate-cards.spec.d.ts +2 -0
  115. package/dist/curated-worker-leads/job-candidate-cards.spec.d.ts.map +1 -0
  116. package/dist/curated-worker-leads/job-candidate-cards.spec.js +157 -0
  117. package/dist/curated-worker-leads/job-candidates.spec.d.ts +2 -0
  118. package/dist/curated-worker-leads/job-candidates.spec.d.ts.map +1 -0
  119. package/dist/curated-worker-leads/job-candidates.spec.js +140 -0
  120. package/dist/curated-worker-leads/job-feed-match-counts.contract.spec.d.ts +2 -0
  121. package/dist/curated-worker-leads/job-feed-match-counts.contract.spec.d.ts.map +1 -0
  122. package/dist/curated-worker-leads/job-feed-match-counts.contract.spec.js +19 -0
  123. package/dist/curated-worker-leads/jobs-tab.contract.d.ts +18365 -0
  124. package/dist/curated-worker-leads/jobs-tab.contract.d.ts.map +1 -0
  125. package/dist/curated-worker-leads/jobs-tab.contract.js +642 -0
  126. package/dist/curated-worker-leads/lead-agent-area.contract.d.ts +348 -0
  127. package/dist/curated-worker-leads/lead-agent-area.contract.d.ts.map +1 -0
  128. package/dist/curated-worker-leads/lead-agent-area.contract.js +51 -0
  129. package/dist/curated-worker-leads/owned-jobs-tab.contract.d.ts +1116 -0
  130. package/dist/curated-worker-leads/owned-jobs-tab.contract.d.ts.map +1 -0
  131. package/dist/curated-worker-leads/owned-jobs-tab.contract.js +93 -0
  132. package/dist/curated-workers/curated-filter-additions.spec.d.ts +2 -0
  133. package/dist/curated-workers/curated-filter-additions.spec.d.ts.map +1 -0
  134. package/dist/curated-workers/curated-filter-additions.spec.js +17 -0
  135. package/dist/curated-workers/curated-job-seeking.spec.d.ts +2 -0
  136. package/dist/curated-workers/curated-job-seeking.spec.d.ts.map +1 -0
  137. package/dist/curated-workers/curated-job-seeking.spec.js +53 -0
  138. package/dist/curated-workers/curated-workers-id-documents.spec.d.ts +2 -0
  139. package/dist/curated-workers/curated-workers-id-documents.spec.d.ts.map +1 -0
  140. package/dist/curated-workers/curated-workers-id-documents.spec.js +38 -0
  141. package/dist/curated-workers/curated-workers.contract.d.ts +6160 -1906
  142. package/dist/curated-workers/curated-workers.contract.d.ts.map +1 -1
  143. package/dist/curated-workers/curated-workers.contract.js +333 -51
  144. package/dist/dashboards/agent-daily-metrics.contract.d.ts +10 -10
  145. package/dist/dashboards/agent-daily-metrics.contract.js +1 -1
  146. package/dist/dashboards/dashboard-widgets.contract.d.ts +3800 -496
  147. package/dist/dashboards/dashboard-widgets.contract.d.ts.map +1 -1
  148. package/dist/dashboards/dashboard-widgets.contract.js +527 -29
  149. package/dist/dashboards/dashboard.contract.d.ts +8 -8
  150. package/dist/document-intake/document-intake.contract.d.ts +3132 -0
  151. package/dist/document-intake/document-intake.contract.d.ts.map +1 -0
  152. package/dist/document-intake/document-intake.contract.js +418 -0
  153. package/dist/export-jobs/export-jobs.contract.d.ts +3918 -0
  154. package/dist/export-jobs/export-jobs.contract.d.ts.map +1 -0
  155. package/dist/export-jobs/export-jobs.contract.js +240 -0
  156. package/dist/exports-events/exports-events.schemas.d.ts +90 -0
  157. package/dist/exports-events/exports-events.schemas.d.ts.map +1 -0
  158. package/dist/exports-events/exports-events.schemas.js +56 -0
  159. package/dist/files/files.contract.d.ts +133 -126
  160. package/dist/files/files.contract.d.ts.map +1 -1
  161. package/dist/files/files.contract.js +8 -0
  162. package/dist/health/health.contract.d.ts +4 -4
  163. package/dist/index.d.ts +82 -0
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js +87 -1
  166. package/dist/interactions/interactions.contract.d.ts +162 -0
  167. package/dist/interactions/interactions.contract.d.ts.map +1 -0
  168. package/dist/interactions/interactions.contract.js +42 -0
  169. package/dist/job-clusters/job-clusters.contract.d.ts +1584 -0
  170. package/dist/job-clusters/job-clusters.contract.d.ts.map +1 -0
  171. package/dist/job-clusters/job-clusters.contract.js +133 -0
  172. package/dist/jobs/jobs.contract.d.ts +16517 -8495
  173. package/dist/jobs/jobs.contract.d.ts.map +1 -1
  174. package/dist/jobs/jobs.contract.js +394 -190
  175. package/dist/jobs/jobs.contract.spec.d.ts +2 -0
  176. package/dist/jobs/jobs.contract.spec.d.ts.map +1 -0
  177. package/dist/jobs/jobs.contract.spec.js +70 -0
  178. package/dist/kpi-impersonation/kpi-impersonation.contract.d.ts +75 -75
  179. package/dist/lead-assignments/lead-assignments.contract.d.ts +2933 -1122
  180. package/dist/lead-assignments/lead-assignments.contract.d.ts.map +1 -1
  181. package/dist/lead-assignments/lead-assignments.contract.js +29 -7
  182. package/dist/lead-distribution/agent-lead-distribution.contract.d.ts +328 -64
  183. package/dist/lead-distribution/agent-lead-distribution.contract.d.ts.map +1 -1
  184. package/dist/lead-distribution/agent-lead-distribution.contract.js +1 -1
  185. package/dist/lead-distribution/lead-distribution-config.contract.d.ts +31 -31
  186. package/dist/leads/leads.contract.d.ts +830 -368
  187. package/dist/leads/leads.contract.d.ts.map +1 -1
  188. package/dist/leads/leads.contract.js +106 -26
  189. package/dist/locations/locations.contract.d.ts +36 -36
  190. package/dist/notifications/notifications.contract.d.ts +1039 -0
  191. package/dist/notifications/notifications.contract.d.ts.map +1 -0
  192. package/dist/notifications/notifications.contract.js +110 -0
  193. package/dist/offices/offices.contract.d.ts +210 -60
  194. package/dist/offices/offices.contract.d.ts.map +1 -1
  195. package/dist/offices/offices.contract.js +18 -4
  196. package/dist/outreach/__tests__/outreach-claim.test.d.ts +2 -0
  197. package/dist/outreach/__tests__/outreach-claim.test.d.ts.map +1 -0
  198. package/dist/outreach/__tests__/outreach-claim.test.js +97 -0
  199. package/dist/outreach/__tests__/outreach-confirm-release.test.d.ts +2 -0
  200. package/dist/outreach/__tests__/outreach-confirm-release.test.d.ts.map +1 -0
  201. package/dist/outreach/__tests__/outreach-confirm-release.test.js +98 -0
  202. package/dist/outreach/__tests__/outreach-routes.test.d.ts +2 -0
  203. package/dist/outreach/__tests__/outreach-routes.test.d.ts.map +1 -0
  204. package/dist/outreach/__tests__/outreach-routes.test.js +57 -0
  205. package/dist/outreach/__tests__/outreach.schemas.test.d.ts +2 -0
  206. package/dist/outreach/__tests__/outreach.schemas.test.d.ts.map +1 -0
  207. package/dist/outreach/__tests__/outreach.schemas.test.js +140 -0
  208. package/dist/outreach/outreach.contract.d.ts +809 -0
  209. package/dist/outreach/outreach.contract.d.ts.map +1 -0
  210. package/dist/outreach/outreach.contract.js +195 -0
  211. package/dist/outreach/outreach.schemas.d.ts +113 -0
  212. package/dist/outreach/outreach.schemas.d.ts.map +1 -0
  213. package/dist/outreach/outreach.schemas.js +132 -0
  214. package/dist/own-research/own-research.contract.d.ts +1356 -552
  215. package/dist/own-research/own-research.contract.d.ts.map +1 -1
  216. package/dist/own-research/own-research.contract.js +14 -3
  217. package/dist/postcodes/postcodes.contract.d.ts +16 -16
  218. package/dist/proofs/proof-category.enum.d.ts +4 -0
  219. package/dist/proofs/proof-category.enum.d.ts.map +1 -0
  220. package/dist/proofs/proof-category.enum.js +5 -0
  221. package/dist/proofs/proof-entity-type.enum.d.ts +4 -0
  222. package/dist/proofs/proof-entity-type.enum.d.ts.map +1 -0
  223. package/dist/proofs/proof-entity-type.enum.js +5 -0
  224. package/dist/proofs/proof-type.enum.d.ts +28 -0
  225. package/dist/proofs/proof-type.enum.d.ts.map +1 -0
  226. package/dist/proofs/proof-type.enum.js +14 -0
  227. package/dist/proofs/proofs.contract.d.ts +3009 -0
  228. package/dist/proofs/proofs.contract.d.ts.map +1 -0
  229. package/dist/proofs/proofs.contract.js +92 -0
  230. package/dist/proofs/proofs.dtos.d.ts +1319 -0
  231. package/dist/proofs/proofs.dtos.d.ts.map +1 -0
  232. package/dist/proofs/proofs.dtos.js +178 -0
  233. package/dist/qualifications/qualifications.contract.d.ts +94 -94
  234. package/dist/realtime/data-changed.d.ts +21 -0
  235. package/dist/realtime/data-changed.d.ts.map +1 -0
  236. package/dist/realtime/data-changed.js +37 -0
  237. package/dist/shared/booking-history.schema.d.ts +27 -0
  238. package/dist/shared/booking-history.schema.d.ts.map +1 -0
  239. package/dist/shared/booking-history.schema.js +22 -0
  240. package/dist/shared/booking-history.spec.d.ts +2 -0
  241. package/dist/shared/booking-history.spec.d.ts.map +1 -0
  242. package/dist/shared/booking-history.spec.js +44 -0
  243. package/dist/shared/contact-suppressions.contract.d.ts +22 -0
  244. package/dist/shared/contact-suppressions.contract.d.ts.map +1 -0
  245. package/dist/shared/contact-suppressions.contract.js +13 -0
  246. package/dist/shared/live-booking.schema.d.ts +57 -0
  247. package/dist/shared/live-booking.schema.d.ts.map +1 -0
  248. package/dist/shared/live-booking.schema.js +34 -0
  249. package/dist/shared/summary-schemas.d.ts +218 -0
  250. package/dist/shared/summary-schemas.d.ts.map +1 -0
  251. package/dist/shared/summary-schemas.js +56 -0
  252. package/dist/sheets-sync/__tests__/sheets-sync-events.schemas.test.d.ts +2 -0
  253. package/dist/sheets-sync/__tests__/sheets-sync-events.schemas.test.d.ts.map +1 -0
  254. package/dist/sheets-sync/__tests__/sheets-sync-events.schemas.test.js +20 -0
  255. package/dist/sheets-sync/__tests__/tab-sync-config.schema.test.d.ts +2 -0
  256. package/dist/sheets-sync/__tests__/tab-sync-config.schema.test.d.ts.map +1 -0
  257. package/dist/sheets-sync/__tests__/tab-sync-config.schema.test.js +41 -0
  258. package/dist/sheets-sync/sheets-sync-events.schemas.d.ts +43 -0
  259. package/dist/sheets-sync/sheets-sync-events.schemas.d.ts.map +1 -0
  260. package/dist/sheets-sync/sheets-sync-events.schemas.js +29 -0
  261. package/dist/sheets-sync/sheets-sync.contract.d.ts +7258 -0
  262. package/dist/sheets-sync/sheets-sync.contract.d.ts.map +1 -0
  263. package/dist/sheets-sync/sheets-sync.contract.js +323 -0
  264. package/dist/telegram/telegram.contract.d.ts +727 -0
  265. package/dist/telegram/telegram.contract.d.ts.map +1 -0
  266. package/dist/telegram/telegram.contract.js +75 -0
  267. package/dist/trades/trade-rate-assessment.d.ts +18 -0
  268. package/dist/trades/trade-rate-assessment.d.ts.map +1 -0
  269. package/dist/trades/trade-rate-assessment.js +46 -0
  270. package/dist/trades/trade-rate-assessment.spec.d.ts +2 -0
  271. package/dist/trades/trade-rate-assessment.spec.d.ts.map +1 -0
  272. package/dist/trades/trade-rate-assessment.spec.js +223 -0
  273. package/dist/trades/trades.contract.d.ts +111 -0
  274. package/dist/trades/trades.contract.d.ts.map +1 -1
  275. package/dist/trades/trades.contract.js +49 -1
  276. package/dist/trades/trades.contract.spec.d.ts +2 -0
  277. package/dist/trades/trades.contract.spec.d.ts.map +1 -0
  278. package/dist/trades/trades.contract.spec.js +173 -0
  279. package/dist/user-access-grants/build-user-access-grant-rules.d.ts +10 -0
  280. package/dist/user-access-grants/build-user-access-grant-rules.d.ts.map +1 -0
  281. package/dist/user-access-grants/build-user-access-grant-rules.js +69 -0
  282. package/dist/user-access-grants/build-user-access-grant-rules.spec.d.ts +2 -0
  283. package/dist/user-access-grants/build-user-access-grant-rules.spec.d.ts.map +1 -0
  284. package/dist/user-access-grants/build-user-access-grant-rules.spec.js +77 -0
  285. package/dist/user-access-grants/user-access-grant-templates.json +454 -0
  286. package/dist/user-access-grants/user-access-grants.contract.d.ts +3886 -0
  287. package/dist/user-access-grants/user-access-grants.contract.d.ts.map +1 -0
  288. package/dist/user-access-grants/user-access-grants.contract.js +189 -0
  289. package/dist/user-access-grants/user-access-grants.contract.spec.d.ts +2 -0
  290. package/dist/user-access-grants/user-access-grants.contract.spec.d.ts.map +1 -0
  291. package/dist/user-access-grants/user-access-grants.contract.spec.js +149 -0
  292. package/dist/users/users.contract.d.ts +1959 -349
  293. package/dist/users/users.contract.d.ts.map +1 -1
  294. package/dist/users/users.contract.js +222 -37
  295. package/dist/users/users.contract.spec.d.ts +2 -0
  296. package/dist/users/users.contract.spec.d.ts.map +1 -0
  297. package/dist/users/users.contract.spec.js +103 -0
  298. package/dist/worker-identity-cases/worker-identity-cases.contract.d.ts +4609 -0
  299. package/dist/worker-identity-cases/worker-identity-cases.contract.d.ts.map +1 -0
  300. package/dist/worker-identity-cases/worker-identity-cases.contract.js +409 -0
  301. package/dist/worker-merge-proposals/worker-merge-proposals.contract.d.ts +1511 -0
  302. package/dist/worker-merge-proposals/worker-merge-proposals.contract.d.ts.map +1 -0
  303. package/dist/worker-merge-proposals/worker-merge-proposals.contract.js +150 -0
  304. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.d.ts +1106 -0
  305. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.d.ts.map +1 -0
  306. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.js +85 -0
  307. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.spec.d.ts +2 -0
  308. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.spec.d.ts.map +1 -0
  309. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.spec.js +216 -0
  310. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.schemas.d.ts +453 -0
  311. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.schemas.d.ts.map +1 -0
  312. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.schemas.js +109 -0
  313. package/dist/workers/do-not-contact.contract.d.ts +46 -0
  314. package/dist/workers/do-not-contact.contract.d.ts.map +1 -0
  315. package/dist/workers/do-not-contact.contract.js +41 -0
  316. package/dist/workers/do-not-contact.contract.spec.d.ts +2 -0
  317. package/dist/workers/do-not-contact.contract.spec.d.ts.map +1 -0
  318. package/dist/workers/do-not-contact.contract.spec.js +47 -0
  319. package/dist/workers/duplicate-group-worker.spec.d.ts +2 -0
  320. package/dist/workers/duplicate-group-worker.spec.d.ts.map +1 -0
  321. package/dist/workers/duplicate-group-worker.spec.js +34 -0
  322. package/dist/workers/filter-exact-flags.spec.d.ts +2 -0
  323. package/dist/workers/filter-exact-flags.spec.d.ts.map +1 -0
  324. package/dist/workers/filter-exact-flags.spec.js +37 -0
  325. package/dist/workers/worker-source-attribution.contract.spec.d.ts +2 -0
  326. package/dist/workers/worker-source-attribution.contract.spec.d.ts.map +1 -0
  327. package/dist/workers/worker-source-attribution.contract.spec.js +442 -0
  328. package/dist/workers/worker-source.spec.d.ts +2 -0
  329. package/dist/workers/worker-source.spec.d.ts.map +1 -0
  330. package/dist/workers/worker-source.spec.js +13 -0
  331. package/dist/workers/worker-status-facets.spec.d.ts +2 -0
  332. package/dist/workers/worker-status-facets.spec.d.ts.map +1 -0
  333. package/dist/workers/worker-status-facets.spec.js +34 -0
  334. package/dist/workers/workers.contract.d.ts +19534 -5969
  335. package/dist/workers/workers.contract.d.ts.map +1 -1
  336. package/dist/workers/workers.contract.js +1096 -113
  337. package/dist/workers/workers.contract.spec.d.ts +2 -0
  338. package/dist/workers/workers.contract.spec.d.ts.map +1 -0
  339. package/dist/workers/workers.contract.spec.js +31 -0
  340. package/package.json +5 -4
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const do_not_contact_contract_1 = require("./do-not-contact.contract");
4
+ describe('SetDoNotContactSchema', () => {
5
+ it('accepts a standard DNC window', () => {
6
+ expect(do_not_contact_contract_1.SetDoNotContactSchema.parse({ reason: 'ALREADY_WORKING', days: 14 })).toEqual({
7
+ reason: 'ALREADY_WORKING',
8
+ days: 14,
9
+ });
10
+ });
11
+ it('accepts the bridge-only 90-day window and its note', () => {
12
+ expect(do_not_contact_contract_1.SetDoNotContactSchema.parse({
13
+ reason: 'NOT_INTERESTED',
14
+ note: 'Rate: wants £20+',
15
+ days: do_not_contact_contract_1.DNC_WRITE_MAX_DAYS,
16
+ })).toEqual({
17
+ reason: 'NOT_INTERESTED',
18
+ note: 'Rate: wants £20+',
19
+ days: 90,
20
+ });
21
+ });
22
+ it('accepts indefinite or days, but never both or neither', () => {
23
+ expect(do_not_contact_contract_1.SetDoNotContactSchema.safeParse({
24
+ reason: 'NOT_INTERESTED',
25
+ indefinite: true,
26
+ }).success).toBe(true);
27
+ expect(do_not_contact_contract_1.SetDoNotContactSchema.safeParse({
28
+ reason: 'NOT_INTERESTED',
29
+ days: 14,
30
+ indefinite: true,
31
+ }).success).toBe(false);
32
+ expect(do_not_contact_contract_1.SetDoNotContactSchema.safeParse({ reason: 'NOT_INTERESTED' }).success).toBe(false);
33
+ });
34
+ it('rejects 0 days', () => {
35
+ expect(do_not_contact_contract_1.SetDoNotContactSchema.safeParse({ reason: 'ALREADY_WORKING', days: 0 })
36
+ .success).toBe(false);
37
+ });
38
+ it(`rejects more than ${do_not_contact_contract_1.DNC_WRITE_MAX_DAYS} days`, () => {
39
+ expect(do_not_contact_contract_1.SetDoNotContactSchema.safeParse({
40
+ reason: 'ALREADY_WORKING',
41
+ days: do_not_contact_contract_1.DNC_WRITE_MAX_DAYS + 1,
42
+ }).success).toBe(false);
43
+ });
44
+ it('rejects non-DNC reasons like NO_ANSWER', () => {
45
+ expect(do_not_contact_contract_1.DoNotContactReasonSchema.safeParse('NO_ANSWER').success).toBe(false);
46
+ });
47
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=duplicate-group-worker.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duplicate-group-worker.spec.d.ts","sourceRoot":"","sources":["../../contracts/workers/duplicate-group-worker.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const workers_contract_1 = require("./workers.contract");
4
+ describe('DuplicateGroupWorkerSchema', () => {
5
+ it('parses a worker with location and updatedAt', () => {
6
+ const input = {
7
+ id: '00000000-0000-0000-0000-000000000001',
8
+ firstName: 'Ana',
9
+ lastName: 'Pop',
10
+ hasTools: false,
11
+ hasPpe: false,
12
+ locationId: '00000000-0000-0000-0000-000000000002',
13
+ location: { postcode: 'SW1A 1AA', postTown: 'London' },
14
+ createdAt: '2026-05-01T10:00:00.000Z',
15
+ updatedAt: '2026-05-10T11:00:00.000Z',
16
+ };
17
+ const parsed = workers_contract_1.DuplicateGroupWorkerSchema.parse(input);
18
+ expect(parsed.location?.postcode).toBe('SW1A 1AA');
19
+ expect(parsed.location?.postTown).toBe('London');
20
+ expect(parsed.updatedAt).toBeInstanceOf(Date);
21
+ });
22
+ it('accepts null location', () => {
23
+ const input = {
24
+ id: '00000000-0000-0000-0000-000000000001',
25
+ firstName: 'Ana',
26
+ hasTools: false,
27
+ hasPpe: false,
28
+ location: null,
29
+ createdAt: '2026-05-01T10:00:00.000Z',
30
+ updatedAt: '2026-05-01T10:00:00.000Z',
31
+ };
32
+ expect(() => workers_contract_1.DuplicateGroupWorkerSchema.parse(input)).not.toThrow();
33
+ });
34
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=filter-exact-flags.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-exact-flags.spec.d.ts","sourceRoot":"","sources":["../../contracts/workers/filter-exact-flags.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const workers_contract_1 = require("./workers.contract");
4
+ const bookings_contract_1 = require("../bookings/bookings.contract");
5
+ const actives_contract_1 = require("../actives/actives.contract");
6
+ describe('nested name filter with exact flag', () => {
7
+ it('FilterWorkerSchema parses name.value + coerces name.exact', () => {
8
+ expect(workers_contract_1.FilterWorkerSchema.parse({ name: { value: 'x', exact: 'true' } }).name).toEqual({ value: 'x', exact: true });
9
+ expect(workers_contract_1.FilterWorkerSchema.parse({ name: { value: 'x', exact: 'false' } }).name
10
+ ?.exact).toBe(false);
11
+ expect(workers_contract_1.FilterWorkerSchema.parse({ name: { value: 'x', exact: true } }).name
12
+ ?.exact).toBe(true);
13
+ expect(workers_contract_1.FilterWorkerSchema.parse({ name: { value: 'x' } }).name?.exact).toBeUndefined();
14
+ expect(workers_contract_1.FilterWorkerSchema.parse({}).name).toBeUndefined();
15
+ });
16
+ it('FilterBookingSchema parses workerName.value + coerces workerName.exact', () => {
17
+ expect(bookings_contract_1.FilterBookingSchema.parse({ workerName: { value: 'x', exact: 'true' } })
18
+ .workerName).toEqual({ value: 'x', exact: true });
19
+ expect(bookings_contract_1.FilterBookingSchema.parse({ workerName: { value: 'x', exact: 'false' } })
20
+ .workerName?.exact).toBe(false);
21
+ expect(bookings_contract_1.FilterBookingSchema.parse({}).workerName).toBeUndefined();
22
+ });
23
+ it('FilterActiveSchema parses workerName.value + coerces workerName.exact', () => {
24
+ expect(actives_contract_1.FilterActiveSchema.parse({ workerName: { value: 'x', exact: 'true' } })
25
+ .workerName).toEqual({ value: 'x', exact: true });
26
+ expect(actives_contract_1.FilterActiveSchema.parse({ workerName: { value: 'x', exact: 'false' } })
27
+ .workerName?.exact).toBe(false);
28
+ expect(actives_contract_1.FilterActiveSchema.parse({}).workerName).toBeUndefined();
29
+ });
30
+ it('FilterActiveByJobSchema parses workerName.value + coerces workerName.exact', () => {
31
+ expect(actives_contract_1.FilterActiveByJobSchema.parse({
32
+ date: '2026-06-25',
33
+ workerName: { value: 'x', exact: 'true' },
34
+ }).workerName).toEqual({ value: 'x', exact: true });
35
+ expect(actives_contract_1.FilterActiveByJobSchema.parse({ date: '2026-06-25' }).workerName).toBeUndefined();
36
+ });
37
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=worker-source-attribution.contract.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-source-attribution.contract.spec.d.ts","sourceRoot":"","sources":["../../contracts/workers/worker-source-attribution.contract.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,442 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const workers_contract_1 = require("./workers.contract");
4
+ const GENERIC_WORKER_CREATE_CONFLICT_CODES = [
5
+ 'BAD_REQUEST',
6
+ 'CREW_MEMBER_LIMIT_REACHED',
7
+ 'ENTITY_HAS_RELATED_RECORDS',
8
+ 'FILE_ATTACHMENT_INVALID',
9
+ 'INVALID_WORKER_DATA',
10
+ 'VALIDATION_ERROR',
11
+ 'WORKER_ALREADY_EXISTS',
12
+ 'WORKER_ALREADY_HAS_QUALIFICATION',
13
+ ];
14
+ const workerCreateConflictCodesAreStructurallyDisjoint = true;
15
+ describe('worker source attribution contracts', () => {
16
+ const evidence = {
17
+ curatedWorker: {
18
+ id: crypto.randomUUID(),
19
+ firstName: 'Earl',
20
+ lastName: 'Kearney',
21
+ },
22
+ phoneMasked: '+44••••1417',
23
+ contactedAt: '2026-07-17T15:35:52.270Z',
24
+ channel: 'PHONE',
25
+ outcome: 'INTERESTED',
26
+ qualifyingContactCount: 1,
27
+ };
28
+ const challenge = {
29
+ id: crypto.randomUUID(),
30
+ context: 'SINGLE',
31
+ status: 'PENDING',
32
+ submittedWorkerName: 'Earl Kearney',
33
+ match: evidence,
34
+ expiresAt: '2026-07-22T15:35:52.270Z',
35
+ createdAt: '2026-07-21T15:35:52.270Z',
36
+ };
37
+ const identityConflict = {
38
+ id: crypto.randomUUID(),
39
+ status: 'OPEN',
40
+ reviewUrl: '/workers/identity-matches?workerSourceIdentityConflictId=case-id',
41
+ };
42
+ it('parses an attribution-required response', () => {
43
+ expect(workers_contract_1.WorkerLeadAttributionRequiredResponseSchema.parse({
44
+ message: 'Worker Leads attribution is required',
45
+ code: 'WORKER_LEAD_ATTRIBUTION_REQUIRED',
46
+ statusCode: 409,
47
+ details: {
48
+ challengeId: crypto.randomUUID(),
49
+ expiresAt: '2026-07-22T15:35:52.270Z',
50
+ submittedWorkerName: 'Earl Kearney',
51
+ match: evidence,
52
+ identityReviewAdjustment: null,
53
+ },
54
+ }).details.match.outcome).toBe('INTERESTED');
55
+ });
56
+ it('requires a strict display-safe review adjustment on attribution-required responses', () => {
57
+ const adjustment = {
58
+ caseId: identityConflict.id,
59
+ retainedPhoneMasks: ['+44••••1417'],
60
+ excludedPhoneMasks: ['+44••••2894'],
61
+ };
62
+ const response = {
63
+ message: 'Worker Leads attribution is required',
64
+ code: 'WORKER_LEAD_ATTRIBUTION_REQUIRED',
65
+ statusCode: 409,
66
+ details: {
67
+ challengeId: crypto.randomUUID(),
68
+ expiresAt: '2026-07-22T15:35:52.270Z',
69
+ submittedWorkerName: 'Earl Kearney',
70
+ match: evidence,
71
+ identityReviewAdjustment: adjustment,
72
+ },
73
+ };
74
+ expect(workers_contract_1.WorkerLeadAttributionRequiredResponseSchema.parse(response).details
75
+ .identityReviewAdjustment).toEqual(adjustment);
76
+ expect(workers_contract_1.WorkerLeadAttributionRequiredResponseSchema.parse({
77
+ ...response,
78
+ details: { ...response.details, identityReviewAdjustment: null },
79
+ }).details.identityReviewAdjustment).toBeNull();
80
+ expect(() => workers_contract_1.WorkerLeadAttributionRequiredResponseSchema.parse({
81
+ ...response,
82
+ details: {
83
+ ...response.details,
84
+ identityReviewAdjustment: {
85
+ ...adjustment,
86
+ retainedPhoneMasks: ['+447700901417'],
87
+ },
88
+ },
89
+ })).toThrow();
90
+ expect(() => workers_contract_1.WorkerLeadAttributionRequiredResponseSchema.parse({
91
+ ...response,
92
+ details: {
93
+ ...response.details,
94
+ identityReviewAdjustment: {
95
+ ...adjustment,
96
+ retainedPhoneE164s: ['+447700901417'],
97
+ },
98
+ },
99
+ })).toThrow();
100
+ expect(() => workers_contract_1.WorkerLeadAttributionRequiredResponseSchema.parse({
101
+ ...response,
102
+ details: {
103
+ challengeId: response.details.challengeId,
104
+ expiresAt: response.details.expiresAt,
105
+ submittedWorkerName: response.details.submittedWorkerName,
106
+ match: response.details.match,
107
+ },
108
+ })).toThrow();
109
+ });
110
+ it('accepts an explicit pending challenge to supersede on single resubmit', () => {
111
+ const supersedesAttributionChallengeId = crypto.randomUUID();
112
+ expect(workers_contract_1.CreateSingleWorkerBodySchema.parse({
113
+ firstName: 'Alice',
114
+ phoneNumbers: [{ phoneNumber: '+447768468895', isPrimary: true }],
115
+ trades: [{ tradeId: crypto.randomUUID(), mainTrade: true }],
116
+ supersedesAttributionChallengeId,
117
+ }).supersedesAttributionChallengeId).toBe(supersedesAttributionChallengeId);
118
+ expect(() => workers_contract_1.CreateSingleWorkerBodySchema.parse({
119
+ firstName: 'Alice',
120
+ phoneNumbers: [{ phoneNumber: '+447768468895', isPrimary: true }],
121
+ trades: [{ tradeId: crypto.randomUUID(), mainTrade: true }],
122
+ supersedesAttributionChallengeId: 'not-a-uuid',
123
+ })).toThrow();
124
+ });
125
+ it('rejects attribution evidence missing a qualifying contact', () => {
126
+ expect(() => workers_contract_1.WorkerLeadAttributionRequiredResponseSchema.parse({
127
+ message: 'Worker Leads attribution is required',
128
+ code: 'WORKER_LEAD_ATTRIBUTION_REQUIRED',
129
+ statusCode: 409,
130
+ details: {
131
+ challengeId: crypto.randomUUID(),
132
+ expiresAt: '2026-07-22T15:35:52.270Z',
133
+ submittedWorkerName: 'Earl Kearney',
134
+ match: {
135
+ ...evidence,
136
+ qualifyingContactCount: 0,
137
+ },
138
+ identityReviewAdjustment: null,
139
+ },
140
+ })).toThrow();
141
+ });
142
+ it('rejects a raw E.164 value in a public phoneMasked field', () => {
143
+ expect(() => workers_contract_1.WorkerLeadAttributionMatchSchema.parse({
144
+ ...evidence,
145
+ phoneMasked: '+447700901417',
146
+ })).toThrow();
147
+ });
148
+ it('represents strict display-safe identity review adjustments', () => {
149
+ const identityReviewAdjustment = {
150
+ caseId: identityConflict.id,
151
+ retainedPhoneMasks: ['+44••••1417'],
152
+ excludedPhoneMasks: ['+44••••2894'],
153
+ };
154
+ expect(workers_contract_1.WorkerSourceAttributionChallengeSchema.parse({
155
+ ...challenge,
156
+ identityReviewAdjustment,
157
+ }).identityReviewAdjustment).toEqual(identityReviewAdjustment);
158
+ expect(() => workers_contract_1.WorkerSourceAttributionChallengeSchema.parse({
159
+ ...challenge,
160
+ identityReviewAdjustment: {
161
+ ...identityReviewAdjustment,
162
+ retainedPhoneMasks: ['+447700901417'],
163
+ },
164
+ })).toThrow();
165
+ expect(() => workers_contract_1.WorkerSourceAttributionChallengeSchema.parse({
166
+ ...challenge,
167
+ identityReviewAdjustment: {
168
+ ...identityReviewAdjustment,
169
+ retainedPhoneE164s: ['+447700901417'],
170
+ },
171
+ })).toThrow();
172
+ });
173
+ it('requires YES or NO and keeps explanation optional', () => {
174
+ expect(workers_contract_1.ResolveWorkerSourceAttributionBodySchema.parse({ answer: 'YES' })).toEqual({ answer: 'YES' });
175
+ expect(workers_contract_1.ResolveWorkerSourceAttributionBodySchema.parse({
176
+ answer: 'NO',
177
+ explanation: 'Known from a previous site',
178
+ }).answer).toBe('NO');
179
+ expect(() => workers_contract_1.ResolveWorkerSourceAttributionBodySchema.parse({ answer: 'SKIP' })).toThrow();
180
+ expect(workers_contract_1.ResolveWorkerSourceAttributionBodySchema.parse({
181
+ answer: 'NO',
182
+ explanation: ' Known from a previous site ',
183
+ }).explanation).toBe('Known from a previous site');
184
+ expect(() => workers_contract_1.ResolveWorkerSourceAttributionBodySchema.parse({
185
+ answer: 'NO',
186
+ explanation: 'x'.repeat(501),
187
+ })).toThrow();
188
+ });
189
+ it('rejects the pending worker payload at the public boundary', () => {
190
+ expect(() => workers_contract_1.WorkerSourceAttributionChallengeSchema.parse({
191
+ ...challenge,
192
+ pendingPayload: {
193
+ firstName: 'Earl',
194
+ lastName: 'Kearney',
195
+ email: 'earl.kearney@example.com',
196
+ phoneNumbers: [{ phoneNumber: '+447700901417', isPrimary: true }],
197
+ },
198
+ })).toThrow();
199
+ expect('pendingPayload' in workers_contract_1.WorkerSourceAttributionChallengeSchema.shape).toBe(false);
200
+ });
201
+ it('extends availability, batch results, and import progress', () => {
202
+ const importJobId = crypto.randomUUID();
203
+ const identityConflictReviewUrl = `/workers/identity-matches?workerSourceIdentityConflictContext=IMPORT&` +
204
+ `workerSourceIdentityConflictContextId=${importJobId}`;
205
+ expect(workers_contract_1.CheckWorkerAvailabilityResponseSchema.parse({
206
+ email: null,
207
+ phoneNumber: null,
208
+ workerLeadAttributionMatch: evidence,
209
+ }).workerLeadAttributionMatch).toEqual(evidence);
210
+ expect(workers_contract_1.CheckWorkerAvailabilityResponseSchema.parse({
211
+ email: null,
212
+ phoneNumber: null,
213
+ workerLeadAttributionMatch: null,
214
+ }).workerLeadAttributionMatch).toBeNull();
215
+ expect(workers_contract_1.BatchCreateWorkerResultSchema.parse({
216
+ index: 0,
217
+ status: 'ATTRIBUTION_REQUIRED',
218
+ challenge,
219
+ }).status).toBe('ATTRIBUTION_REQUIRED');
220
+ expect(workers_contract_1.BatchCreateWorkerResultSchema.parse({
221
+ index: 1,
222
+ status: 'IDENTITY_CONFLICT',
223
+ identityConflict,
224
+ }).status).toBe('IDENTITY_CONFLICT');
225
+ expect(workers_contract_1.WorkerImportJobSchema.parse({
226
+ id: importJobId,
227
+ status: 'COMPLETED',
228
+ totalRows: 3,
229
+ successCount: 1,
230
+ failedCount: 0,
231
+ skippedCount: 0,
232
+ awaitingAttributionCount: 1,
233
+ identityConflictCount: 1,
234
+ identityConflictReviewUrl,
235
+ identityConflictCaseIds: [identityConflict.id],
236
+ sourceFileId: crypto.randomUUID(),
237
+ createdByUserId: crypto.randomUUID(),
238
+ createdAt: '2026-07-21T15:35:52.270Z',
239
+ }).awaitingAttributionCount).toBe(1);
240
+ const baseImportJob = {
241
+ id: importJobId,
242
+ status: 'COMPLETED',
243
+ totalRows: 1,
244
+ successCount: 0,
245
+ failedCount: 0,
246
+ skippedCount: 0,
247
+ awaitingAttributionCount: 0,
248
+ identityConflictCount: 1,
249
+ identityConflictCaseIds: [identityConflict.id],
250
+ sourceFileId: crypto.randomUUID(),
251
+ createdByUserId: crypto.randomUUID(),
252
+ createdAt: '2026-07-21T15:35:52.270Z',
253
+ };
254
+ expect(workers_contract_1.WorkerImportJobSchema.safeParse({
255
+ ...baseImportJob,
256
+ identityConflictReviewUrl: 'https://example.com/workers/identity-matches?workerSourceIdentityConflictContext=IMPORT&' +
257
+ `workerSourceIdentityConflictContextId=${importJobId}`,
258
+ }).success).toBe(false);
259
+ expect(workers_contract_1.WorkerImportJobSchema.safeParse({
260
+ ...baseImportJob,
261
+ identityConflictReviewUrl: '/workers/identity-matches?workerSourceIdentityConflictContext=IMPORT',
262
+ }).success).toBe(false);
263
+ expect(workers_contract_1.WorkerImportJobSchema.safeParse({
264
+ ...baseImportJob,
265
+ identityConflictReviewUrl: '/workers/identity-matches?workerSourceIdentityConflictContext=IMPORT&' +
266
+ `workerSourceIdentityConflictContextId=${crypto.randomUUID()}`,
267
+ }).success).toBe(false);
268
+ });
269
+ it('defines the bounded agent challenge routes', () => {
270
+ const listRoute = workers_contract_1.workersContractRouter.listSourceAttributionChallenges;
271
+ const resolveRoute = workers_contract_1.workersContractRouter.resolveSourceAttributionChallenge;
272
+ const batchRoute = workers_contract_1.workersContractRouter.resolveSourceAttributionChallengesBatch;
273
+ expect(listRoute.method).toBe('GET');
274
+ expect(listRoute.path).toBe('/v2/workers/source-attribution-challenges');
275
+ const importJobId = crypto.randomUUID();
276
+ expect(workers_contract_1.ListWorkerSourceAttributionChallengesQuerySchema.parse({
277
+ context: 'IMPORT',
278
+ contextId: importJobId,
279
+ })).toMatchObject({ context: 'IMPORT', contextId: importJobId });
280
+ const sourceIdentityConflictId = crypto.randomUUID();
281
+ expect(workers_contract_1.ListWorkerSourceAttributionChallengesQuerySchema.parse({
282
+ context: 'SINGLE',
283
+ sourceIdentityConflictId,
284
+ })).toMatchObject({
285
+ context: 'SINGLE',
286
+ sourceIdentityConflictId,
287
+ });
288
+ expect(() => workers_contract_1.ListWorkerSourceAttributionChallengesQuerySchema.parse({
289
+ sourceIdentityConflictId: 'not-a-uuid',
290
+ })).toThrow();
291
+ expect(listRoute.query.parse({})).toEqual({ page: 1, limit: 50 });
292
+ expect(listRoute.query.parse({ context: 'BATCH' })).toEqual({
293
+ page: 1,
294
+ limit: 50,
295
+ context: 'BATCH',
296
+ });
297
+ expect(() => listRoute.query.parse({ page: 0 })).toThrow();
298
+ expect(() => listRoute.query.parse({ limit: 0 })).toThrow();
299
+ expect(() => listRoute.query.parse({ limit: 101 })).toThrow();
300
+ expect(listRoute.responses[200].parse({
301
+ data: [challenge],
302
+ total: 1,
303
+ page: 1,
304
+ limit: 50,
305
+ }).data).toHaveLength(1);
306
+ expect(resolveRoute.method).toBe('POST');
307
+ expect(resolveRoute.path).toBe('/v2/workers/source-attribution-challenges/:id/resolve');
308
+ expect(resolveRoute.responses[201]).toBeDefined();
309
+ expect(batchRoute.method).toBe('POST');
310
+ expect(batchRoute.path).toBe('/v2/workers/source-attribution-challenges/resolve-batch');
311
+ expect(batchRoute.body.parse({
312
+ items: [{ challengeId: challenge.id, answer: 'YES' }],
313
+ }).items).toHaveLength(1);
314
+ expect(() => batchRoute.body.parse({ items: [] })).toThrow();
315
+ expect(() => batchRoute.body.parse({
316
+ items: Array.from({ length: 101 }, () => ({
317
+ challengeId: crypto.randomUUID(),
318
+ answer: 'NO',
319
+ })),
320
+ })).toThrow();
321
+ expect(batchRoute.responses[200].parse({
322
+ results: [
323
+ {
324
+ challengeId: challenge.id,
325
+ status: 'IDENTITY_CONFLICT',
326
+ error: 'Identity changed while awaiting an answer',
327
+ terminal: true,
328
+ identityConflict,
329
+ },
330
+ {
331
+ challengeId: crypto.randomUUID(),
332
+ status: 'FAILED',
333
+ error: 'Temporary database error',
334
+ terminal: false,
335
+ },
336
+ ],
337
+ }).results).toEqual([
338
+ {
339
+ challengeId: challenge.id,
340
+ status: 'IDENTITY_CONFLICT',
341
+ error: 'Identity changed while awaiting an answer',
342
+ terminal: true,
343
+ identityConflict,
344
+ },
345
+ {
346
+ challengeId: expect.any(String),
347
+ status: 'FAILED',
348
+ error: 'Temporary database error',
349
+ terminal: false,
350
+ },
351
+ ]);
352
+ expect(() => batchRoute.responses[200].parse({
353
+ results: [
354
+ {
355
+ challengeId: challenge.id,
356
+ status: 'FAILED',
357
+ error: 'Missing terminal classification',
358
+ },
359
+ ],
360
+ })).toThrow();
361
+ expect(() => batchRoute.responses[200].parse({
362
+ results: [
363
+ {
364
+ challengeId: challenge.id,
365
+ status: 'IDENTITY_CONFLICT',
366
+ error: 'Missing owner-safe review reference',
367
+ terminal: true,
368
+ },
369
+ ],
370
+ })).toThrow();
371
+ expect(() => batchRoute.responses[200].parse({
372
+ results: [
373
+ {
374
+ challengeId: challenge.id,
375
+ status: 'IDENTITY_CONFLICT',
376
+ error: 'Cross-branch field supplied',
377
+ terminal: true,
378
+ identityConflict,
379
+ workerId: crypto.randomUUID(),
380
+ },
381
+ ],
382
+ })).toThrow();
383
+ });
384
+ it('defines read and invalidation-only administrator routes', () => {
385
+ const listRoute = workers_contract_1.workersContractRouter.adminListSourceAttributionChallenges;
386
+ const invalidateRoute = workers_contract_1.workersContractRouter.adminInvalidateSourceAttributionChallenge;
387
+ expect(listRoute.method).toBe('GET');
388
+ expect(listRoute.path).toBe('/v2/workers/admin/source-attribution-challenges');
389
+ expect(listRoute.query.parse({ context: 'IMPORT', status: 'RESOLVED_NO' })).toEqual({
390
+ page: 1,
391
+ limit: 50,
392
+ context: 'IMPORT',
393
+ status: 'RESOLVED_NO',
394
+ });
395
+ expect(invalidateRoute.method).toBe('POST');
396
+ expect(invalidateRoute.path).toBe('/v2/workers/admin/source-attribution-challenges/:id/invalidate');
397
+ expect(invalidateRoute.body.parse({ reason: 'Duplicate submission' })).toEqual({ reason: 'Duplicate submission' });
398
+ expect(() => invalidateRoute.body.parse({ reason: ' ' })).toThrow();
399
+ expect(invalidateRoute.responses[200].parse(challenge).id).toBe(challenge.id);
400
+ expect(Object.keys(workers_contract_1.workersContractRouter).filter((routeName) => routeName.startsWith('admin') && routeName.includes('Resolve'))).toEqual([]);
401
+ });
402
+ it('keeps existing create conflicts alongside attribution-required conflicts', () => {
403
+ const createConflictSchema = workers_contract_1.workersContractRouter.create.responses[409];
404
+ expect(workerCreateConflictCodesAreStructurallyDisjoint).toBe(true);
405
+ expect(createConflictSchema.parse({
406
+ message: 'Worker Leads attribution is required',
407
+ code: 'WORKER_LEAD_ATTRIBUTION_REQUIRED',
408
+ statusCode: 409,
409
+ details: {
410
+ challengeId: crypto.randomUUID(),
411
+ expiresAt: '2026-07-22T15:35:52.270Z',
412
+ submittedWorkerName: 'Earl Kearney',
413
+ match: evidence,
414
+ identityReviewAdjustment: null,
415
+ },
416
+ }).code).toBe('WORKER_LEAD_ATTRIBUTION_REQUIRED');
417
+ for (const code of GENERIC_WORKER_CREATE_CONFLICT_CODES) {
418
+ expect(createConflictSchema.parse({
419
+ statusCode: 409,
420
+ message: 'Worker creation conflict',
421
+ code,
422
+ timestamp: '2026-07-21T15:35:52.270Z',
423
+ path: '/v2/workers',
424
+ }).code).toBe(code);
425
+ }
426
+ expect(() => createConflictSchema.parse({
427
+ statusCode: 409,
428
+ message: 'Unmodeled generic conflict',
429
+ code: 'CONFLICT',
430
+ timestamp: '2026-07-21T15:35:52.270Z',
431
+ path: '/v2/workers',
432
+ })).toThrow();
433
+ expect(() => createConflictSchema.parse({
434
+ statusCode: 409,
435
+ message: 'Typed identity conflict using a generic shape',
436
+ code: 'WORKER_IDENTITY_CONFLICT',
437
+ details: { curatedWorkerIds: [crypto.randomUUID()] },
438
+ timestamp: '2026-07-21T15:35:52.270Z',
439
+ path: '/v2/workers',
440
+ })).toThrow();
441
+ });
442
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=worker-source.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-source.spec.d.ts","sourceRoot":"","sources":["../../contracts/workers/worker-source.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const workers_contract_1 = require("./workers.contract");
4
+ describe('WorkerSource contract', () => {
5
+ it('accepts the four source values', () => {
6
+ expect(workers_contract_1.WorkerSourceSchema.parse('LEAD_MATCH')).toBe('LEAD_MATCH');
7
+ expect(() => workers_contract_1.WorkerSourceSchema.parse('NOPE')).toThrow();
8
+ });
9
+ it('FilterWorkerSchema accepts a source array', () => {
10
+ const parsed = workers_contract_1.FilterWorkerSchema.parse({ source: ['LEAD_MATCH', 'MANUAL'] });
11
+ expect(parsed.source).toEqual(['LEAD_MATCH', 'MANUAL']);
12
+ });
13
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=worker-status-facets.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-status-facets.spec.d.ts","sourceRoot":"","sources":["../../contracts/workers/worker-status-facets.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const workers_contract_1 = require("./workers.contract");
4
+ const curated_workers_contract_1 = require("../curated-workers/curated-workers.contract");
5
+ describe('worker status facets', () => {
6
+ it('defines nullable booking-derived occupancy', () => {
7
+ expect(workers_contract_1.OccupancyStatusSchema.parse('ACTIVE')).toBe('ACTIVE');
8
+ expect(workers_contract_1.OccupancyStatusSchema.parse('BOOKED')).toBe('BOOKED');
9
+ expect(workers_contract_1.OccupancyStatusSchema.parse(null)).toBeNull();
10
+ expect(workers_contract_1.OccupancyStatusSchema.safeParse('FREE').success).toBe(false);
11
+ });
12
+ it('exposes occupancyStatus and required suppression on both worker responses', () => {
13
+ for (const shape of [workers_contract_1.WorkerSchema.shape, workers_contract_1.WorkerListItemSchema.shape]) {
14
+ expect(shape.occupancyStatus).toBeDefined();
15
+ expect(shape.suppression).toBeDefined();
16
+ expect(shape.suppression.safeParse(undefined).success).toBe(false);
17
+ }
18
+ });
19
+ it('exposes the same independent facets on curated worker responses', () => {
20
+ expect(curated_workers_contract_1.CuratedWorkerResponseSchema.shape.occupancyStatus).toBeDefined();
21
+ expect(curated_workers_contract_1.CuratedWorkerResponseSchema.shape.suppression).toBeDefined();
22
+ expect(curated_workers_contract_1.CuratedWorkerResponseSchema.shape.suppression.safeParse(undefined)
23
+ .success).toBe(false);
24
+ });
25
+ it('replaces the unified status filters with singular occupancy and contact filters', () => {
26
+ for (const schema of [workers_contract_1.FilterWorkerSchema, curated_workers_contract_1.FilterCuratedWorkerSchema]) {
27
+ expect(schema.parse({ occupancy: 'FREE', contact: 'CHASEABLE' })).toMatchObject({ occupancy: 'FREE', contact: 'CHASEABLE' });
28
+ expect(schema.shape.status).toBeUndefined();
29
+ expect(schema.safeParse({ occupancy: ['BOOKED'] }).success).toBe(false);
30
+ expect(schema.safeParse({ contact: 'BLACKLISTED' }).success).toBe(true);
31
+ expect(schema.safeParse({ contact: 'PAUSED' }).success).toBe(true);
32
+ }
33
+ });
34
+ });