@dakkitor/api-contracts 1.1.153 → 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,921 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CandidatePhoneCancellationReasonSchema = exports.CandidateContactHistoryResponseSchema = exports.CandidateContactHistoryQuerySchema = exports.CandidateContactHistoryItemSchema = exports.CandidateContactHistoryOutcomeSchema = exports.ContactCompletionResultSchema = exports.StaleContactJobConflictResponseSchema = exports.StaleContactJobConflictDetailsSchema = exports.ConfirmWhatsAppSentBodySchema = exports.AttachContactSessionJobsBodySchema = exports.AlternativeContactJobSchema = exports.ContactSessionSummarySchema = exports.ContactSessionJobSchema = exports.ContactJobSummarySchema = exports.ContactSessionStatusSchema = exports.CandidateContactChannelSchema = exports.ContactFeedbackDataSchema = exports.MultiJobContactCompletionSchema = exports.NonConnectedContactCompletionSchema = exports.FollowUpContactCompletionSchema = exports.ConnectedContactCompletionSchema = exports.ContactJobResultEntrySchema = exports.ContactJobPreviousContextSchema = exports.PreviousPhoneJobResultSchema = exports.ContactJobResultSchema = exports.ContactWorkerStateSchema = exports.ContactConnectionResultSchema = exports.CompletePhoneCallBodySchema = exports.DO_NOT_CONTACT_REASON_MAX_LENGTH = exports.DO_NOT_CONTACT_REASON_MIN_LENGTH = exports.NotInterestedReasonSchema = exports.PhoneCallOutcomeSchema = exports.CandidateCoordinationChangedSchema = exports.CandidateCoordinationChangedReasonSchema = exports.JobCandidatePresenceChangedSchema = exports.CandidateCoordinationStateSchema = exports.CandidateContactRestrictionSchema = exports.PhoneOwnershipSchema = exports.PhoneOwnershipOutcomeSchema = exports.CoordinationLeaseSchema = exports.CoordinationLeaseKindSchema = exports.CandidateCoordinationConflictErrorSchema = exports.EditLeaseHeartbeatBodySchema = exports.CandidateCoordinationConflictDetailsSchema = exports.CandidateCoordinationConflictKindSchema = exports.CoordinationUserSummarySchema = exports.CanonicalWorkerRefSchema = exports.CanonicalWorkerKindSchema = exports.CANDIDATE_COORDINATION_CHANGED_EVENT = exports.JOB_CANDIDATE_PRESENCE_CHANGED_EVENT = void 0;
4
+ exports.candidateCoordinationContract = exports.CandidateCoordinationSnapshotSchema = exports.CandidatePresenceSnapshotSchema = exports.CancelPhoneCallResponseSchema = exports.PhoneCallOutcomeResponseSchema = exports.PhoneRevealResponseSchema = exports.ActivePhoneCallResponseSchema = exports.ActivePhoneCallSchema = exports.StartPhoneCallResponseSchema = exports.CandidateRefPathSchema = void 0;
5
+ const zod_openapi_1 = require("@anatine/zod-openapi");
6
+ const core_1 = require("@ts-rest/core");
7
+ const zod_1 = require("zod");
8
+ const error_schemas_1 = require("../common/error-schemas");
9
+ const jobs_contract_1 = require("../jobs/jobs.contract");
10
+ const common_schemas_1 = require("../common/common-schemas");
11
+ (0, zod_openapi_1.extendZodWithOpenApi)(zod_1.z);
12
+ const c = (0, core_1.initContract)();
13
+ exports.JOB_CANDIDATE_PRESENCE_CHANGED_EVENT = 'job.candidate-presence.changed';
14
+ exports.CANDIDATE_COORDINATION_CHANGED_EVENT = 'candidate.coordination.changed';
15
+ exports.CanonicalWorkerKindSchema = zod_1.z.enum(['WORKER', 'CURATED_WORKER']);
16
+ // Deliberately untitled: this shape is reused through optional/nullable
17
+ // wrappers in HTTP and SSE payloads.
18
+ exports.CanonicalWorkerRefSchema = zod_1.z.object({
19
+ kind: exports.CanonicalWorkerKindSchema,
20
+ id: zod_1.z.string().uuid(),
21
+ });
22
+ exports.CoordinationUserSummarySchema = zod_1.z.object({
23
+ id: zod_1.z.string().uuid(),
24
+ firstName: zod_1.z.string(),
25
+ lastName: zod_1.z.string().nullable(),
26
+ });
27
+ exports.CandidateCoordinationConflictKindSchema = zod_1.z.enum([
28
+ 'EDIT_LEASE',
29
+ 'PHONE_CALL',
30
+ 'PHONE_OWNERSHIP',
31
+ ]);
32
+ // Deliberately untitled because ErrorResponseSchema.details wraps this shape.
33
+ exports.CandidateCoordinationConflictDetailsSchema = zod_1.z.object({
34
+ conflictKind: exports.CandidateCoordinationConflictKindSchema,
35
+ holder: exports.CoordinationUserSummarySchema,
36
+ expiresAt: zod_1.z.string().datetime(),
37
+ sameUser: zod_1.z.boolean().optional(),
38
+ });
39
+ exports.EditLeaseHeartbeatBodySchema = zod_1.z.object({
40
+ clientId: zod_1.z.string().uuid(),
41
+ takeover: zod_1.z.boolean().optional().default(false),
42
+ });
43
+ exports.CandidateCoordinationConflictErrorSchema = error_schemas_1.ErrorResponseSchema.extend({
44
+ code: zod_1.z.literal('CANDIDATE_COORDINATION_CONFLICT'),
45
+ details: exports.CandidateCoordinationConflictDetailsSchema,
46
+ });
47
+ exports.CoordinationLeaseKindSchema = zod_1.z.enum(['CALLING', 'EDITING']);
48
+ exports.CoordinationLeaseSchema = zod_1.z.object({
49
+ id: zod_1.z.string().uuid(),
50
+ kind: exports.CoordinationLeaseKindSchema,
51
+ holder: exports.CoordinationUserSummarySchema,
52
+ startedAt: zod_1.z.string().datetime(),
53
+ expiresAt: zod_1.z.string().datetime(),
54
+ });
55
+ exports.PhoneOwnershipOutcomeSchema = zod_1.z.enum([
56
+ 'CONNECTED',
57
+ 'INTERESTED',
58
+ 'NO_ANSWER',
59
+ 'BUSY',
60
+ ]);
61
+ exports.PhoneOwnershipSchema = zod_1.z.object({
62
+ id: zod_1.z.string().uuid(),
63
+ owner: exports.CoordinationUserSummarySchema,
64
+ sourceJobId: zod_1.z.string().uuid(),
65
+ outcome: exports.PhoneOwnershipOutcomeSchema,
66
+ acquiredAt: zod_1.z.string().datetime(),
67
+ expiresAt: zod_1.z.string().datetime(),
68
+ // Optional so rolling deploys stay compatible in BOTH directions: an older
69
+ // web treats the reservation as candidate-wide (locks, today's behaviour),
70
+ // and a newer web seeing `undefined` from an older API does the same. Both
71
+ // fail safe toward locking.
72
+ exclusivity: zod_1.z.enum(['GLOBAL', 'SOURCE_JOB']).optional(),
73
+ // Jobs a SOURCE_JOB reservation covers. Empty/absent for GLOBAL.
74
+ coveredJobIds: zod_1.z.array(zod_1.z.string().uuid()).optional(),
75
+ });
76
+ exports.CandidateContactRestrictionSchema = zod_1.z.object({
77
+ scope: zod_1.z.enum(['NOT_LOOKING', 'DO_NOT_CONTACT']),
78
+ until: zod_1.z.string().datetime().nullable(),
79
+ setBy: exports.CoordinationUserSummarySchema,
80
+ });
81
+ exports.CandidateCoordinationStateSchema = zod_1.z.object({
82
+ canonicalWorker: exports.CanonicalWorkerRefSchema,
83
+ callingClaim: exports.CoordinationLeaseSchema.nullable(),
84
+ editLease: exports.CoordinationLeaseSchema.nullable(),
85
+ phoneOwnership: exports.PhoneOwnershipSchema.nullable(),
86
+ // Present on the outcome event that removes a worker from the current
87
+ // candidate set. Optional keeps rolling deployments compatible with older
88
+ // API/web instances; a page refresh naturally removes the ineligible row.
89
+ contactRestriction: exports.CandidateContactRestrictionSchema.optional(),
90
+ });
91
+ exports.JobCandidatePresenceChangedSchema = zod_1.z.object({
92
+ jobId: zod_1.z.string().uuid(),
93
+ activeAgentCount: zod_1.z.number().int().min(0),
94
+ });
95
+ exports.CandidateCoordinationChangedReasonSchema = zod_1.z.enum([
96
+ 'CALL_STARTED',
97
+ 'OUTCOME',
98
+ 'INVALID_NUMBER',
99
+ 'EDIT',
100
+ 'RELEASE',
101
+ 'EXPIRY',
102
+ 'ADMIN_OVERRIDE',
103
+ ]);
104
+ exports.CandidateCoordinationChangedSchema = zod_1.z.object({
105
+ canonicalWorker: exports.CanonicalWorkerRefSchema,
106
+ sourceJobId: zod_1.z.string().uuid().optional(),
107
+ state: exports.CandidateCoordinationStateSchema,
108
+ reason: exports.CandidateCoordinationChangedReasonSchema,
109
+ });
110
+ exports.PhoneCallOutcomeSchema = zod_1.z.enum([
111
+ 'INTERESTED',
112
+ 'NO_ANSWER',
113
+ 'BUSY',
114
+ 'NOT_INTERESTED',
115
+ 'INVALID_NUMBER',
116
+ ]);
117
+ exports.NotInterestedReasonSchema = zod_1.z.enum([
118
+ 'RATE',
119
+ 'DISTANCE',
120
+ 'TRANSPORT_COST',
121
+ 'OTHER',
122
+ ]);
123
+ const OptionalCallNoteSchema = zod_1.z.string().trim().max(500).nullable().optional();
124
+ exports.DO_NOT_CONTACT_REASON_MIN_LENGTH = 20;
125
+ exports.DO_NOT_CONTACT_REASON_MAX_LENGTH = 300;
126
+ const InterestedPhoneCallCompletionSchema = zod_1.z
127
+ .object({
128
+ outcome: zod_1.z.literal('INTERESTED'),
129
+ jobSeeking: zod_1.z
130
+ .object({
131
+ offerOpenness: zod_1.z.enum(['ACTIVELY_LOOKING', 'OPEN']),
132
+ offerNote: OptionalCallNoteSchema,
133
+ })
134
+ .strict(),
135
+ })
136
+ .strict();
137
+ const SimplePhoneCallCompletionSchema = zod_1.z
138
+ .object({
139
+ outcome: zod_1.z.enum(['NO_ANSWER', 'BUSY', 'INVALID_NUMBER']),
140
+ })
141
+ .strict();
142
+ const JobSpecificNotInterestedCompletionSchema = zod_1.z
143
+ .object({
144
+ outcome: zod_1.z.literal('NOT_INTERESTED'),
145
+ scope: zod_1.z.literal('THIS_JOB'),
146
+ reason: exports.NotInterestedReasonSchema,
147
+ comment: zod_1.z.string().trim().max(500).optional(),
148
+ })
149
+ .strict()
150
+ .superRefine((data, ctx) => {
151
+ if (data.reason === 'OTHER' && !data.comment?.trim()) {
152
+ ctx.addIssue({
153
+ code: zod_1.z.ZodIssueCode.custom,
154
+ path: ['comment'],
155
+ message: 'A comment is required when the reason is Other',
156
+ });
157
+ }
158
+ });
159
+ const TemporarilyNotLookingCompletionSchema = zod_1.z
160
+ .object({
161
+ outcome: zod_1.z.literal('NOT_INTERESTED'),
162
+ scope: zod_1.z.literal('NOT_LOOKING'),
163
+ doNotContactDays: zod_1.z.union([zod_1.z.literal(7), zod_1.z.literal(14), zod_1.z.literal(30)]),
164
+ offerNote: OptionalCallNoteSchema,
165
+ })
166
+ .strict();
167
+ const DoNotContactCompletionSchema = zod_1.z
168
+ .object({
169
+ outcome: zod_1.z.literal('NOT_INTERESTED'),
170
+ scope: zod_1.z.literal('DO_NOT_CONTACT'),
171
+ reason: zod_1.z
172
+ .string()
173
+ .trim()
174
+ .min(exports.DO_NOT_CONTACT_REASON_MIN_LENGTH, `Reason must be at least ${exports.DO_NOT_CONTACT_REASON_MIN_LENGTH} characters`)
175
+ .max(exports.DO_NOT_CONTACT_REASON_MAX_LENGTH, `Reason must be at most ${exports.DO_NOT_CONTACT_REASON_MAX_LENGTH} characters`),
176
+ })
177
+ .strict();
178
+ exports.CompletePhoneCallBodySchema = zod_1.z.union([
179
+ InterestedPhoneCallCompletionSchema,
180
+ SimplePhoneCallCompletionSchema,
181
+ JobSpecificNotInterestedCompletionSchema,
182
+ TemporarilyNotLookingCompletionSchema,
183
+ DoNotContactCompletionSchema,
184
+ ]);
185
+ exports.ContactConnectionResultSchema = zod_1.z.enum([
186
+ 'CONNECTED',
187
+ 'NO_ANSWER',
188
+ 'BUSY',
189
+ 'INVALID_NUMBER',
190
+ ]);
191
+ const ContactWorkerNoteSchema = zod_1.z
192
+ .string()
193
+ .trim()
194
+ .max(500)
195
+ .nullable()
196
+ .optional();
197
+ exports.ContactWorkerStateSchema = zod_1.z.discriminatedUnion('kind', [
198
+ zod_1.z
199
+ .object({
200
+ kind: zod_1.z.literal('ACTIVELY_LOOKING'),
201
+ note: ContactWorkerNoteSchema,
202
+ })
203
+ .strict(),
204
+ zod_1.z
205
+ .object({
206
+ kind: zod_1.z.literal('OPEN_TO_OFFERS'),
207
+ note: ContactWorkerNoteSchema,
208
+ })
209
+ .strict(),
210
+ zod_1.z
211
+ .object({
212
+ kind: zod_1.z.literal('NOT_LOOKING'),
213
+ days: zod_1.z.union([zod_1.z.literal(7), zod_1.z.literal(14), zod_1.z.literal(30)]),
214
+ note: ContactWorkerNoteSchema,
215
+ })
216
+ .strict(),
217
+ zod_1.z
218
+ .object({
219
+ kind: zod_1.z.literal('DO_NOT_CONTACT'),
220
+ reason: zod_1.z
221
+ .string()
222
+ .trim()
223
+ .min(exports.DO_NOT_CONTACT_REASON_MIN_LENGTH)
224
+ .max(exports.DO_NOT_CONTACT_REASON_MAX_LENGTH),
225
+ })
226
+ .strict(),
227
+ zod_1.z
228
+ .object({
229
+ kind: zod_1.z.literal('NOT_CONFIRMED'),
230
+ note: ContactWorkerNoteSchema,
231
+ })
232
+ .strict(),
233
+ ]);
234
+ const ContactJobChannelSchema = zod_1.z.enum(['PHONE', 'WHATSAPP']);
235
+ const ContactJobNoteSchema = zod_1.z.string().trim().max(500).optional();
236
+ exports.ContactJobResultSchema = zod_1.z
237
+ .union([
238
+ zod_1.z
239
+ .object({
240
+ kind: zod_1.z.literal('OFFER_SENT'),
241
+ channel: ContactJobChannelSchema,
242
+ })
243
+ .strict(),
244
+ zod_1.z
245
+ .object({
246
+ kind: zod_1.z.literal('DISCUSSED'),
247
+ channel: ContactJobChannelSchema,
248
+ })
249
+ .strict(),
250
+ zod_1.z
251
+ .object({
252
+ kind: zod_1.z.literal('INTERESTED'),
253
+ channel: ContactJobChannelSchema,
254
+ })
255
+ .strict(),
256
+ zod_1.z
257
+ .object({
258
+ kind: zod_1.z.literal('NOT_INTERESTED'),
259
+ channel: ContactJobChannelSchema,
260
+ reason: exports.NotInterestedReasonSchema,
261
+ note: ContactJobNoteSchema,
262
+ })
263
+ .strict(),
264
+ ])
265
+ .superRefine((data, ctx) => {
266
+ if (data.kind === 'NOT_INTERESTED' &&
267
+ data.reason === 'OTHER' &&
268
+ !data.note?.trim()) {
269
+ ctx.addIssue({
270
+ code: zod_1.z.ZodIssueCode.custom,
271
+ path: ['note'],
272
+ message: 'A note is required when the reason is Other',
273
+ });
274
+ }
275
+ });
276
+ /** Read-only projection of an earlier completed phone response for one job.
277
+ * Built from the existing result kinds rather than a new business enum, but
278
+ * deliberately without the optional decline note: historical notes stay
279
+ * confined to Contact History (design §5.2). The channel is the literal
280
+ * PHONE so a WhatsApp-channel row can never render as "Your previous call". */
281
+ exports.PreviousPhoneJobResultSchema = zod_1.z.discriminatedUnion('kind', [
282
+ zod_1.z
283
+ .object({
284
+ kind: zod_1.z.literal('INTERESTED'),
285
+ channel: zod_1.z.literal('PHONE'),
286
+ })
287
+ .strict(),
288
+ zod_1.z
289
+ .object({
290
+ kind: zod_1.z.literal('DISCUSSED'),
291
+ channel: zod_1.z.literal('PHONE'),
292
+ })
293
+ .strict(),
294
+ zod_1.z
295
+ .object({
296
+ kind: zod_1.z.literal('OFFER_SENT'),
297
+ channel: zod_1.z.literal('PHONE'),
298
+ })
299
+ .strict(),
300
+ zod_1.z
301
+ .object({
302
+ kind: zod_1.z.literal('NOT_INTERESTED'),
303
+ channel: zod_1.z.literal('PHONE'),
304
+ reason: exports.NotInterestedReasonSchema,
305
+ })
306
+ .strict(),
307
+ ]);
308
+ /** Two independent historical signals for one job on the active-call pivot:
309
+ * the current viewer's own latest phone response, and the team's latest
310
+ * WhatsApp outreach. A non-optional object with nullable members keeps
311
+ * attached session jobs and unattached alternatives on one rendering shape. */
312
+ exports.ContactJobPreviousContextSchema = zod_1.z
313
+ .object({
314
+ phone: zod_1.z
315
+ .object({
316
+ contactedAt: zod_1.z.string().datetime(),
317
+ result: exports.PreviousPhoneJobResultSchema,
318
+ })
319
+ .strict()
320
+ .nullable(),
321
+ whatsapp: zod_1.z
322
+ .object({
323
+ contactedAt: zod_1.z.string().datetime(),
324
+ agent: exports.CoordinationUserSummarySchema,
325
+ })
326
+ .strict()
327
+ .nullable(),
328
+ })
329
+ .strict();
330
+ exports.ContactJobResultEntrySchema = zod_1.z
331
+ .object({
332
+ jobId: zod_1.z.string().uuid(),
333
+ result: exports.ContactJobResultSchema.optional(),
334
+ offerSentViaWhatsApp: zod_1.z.literal(true).optional(),
335
+ })
336
+ .strict()
337
+ .refine((entry) => entry.result || entry.offerSentViaWhatsApp, {
338
+ message: 'A worker response or WhatsApp offer is required',
339
+ });
340
+ const rejectDuplicateIds = (ids, ctx, path) => {
341
+ if (new Set(ids).size !== ids.length) {
342
+ ctx.addIssue({
343
+ code: zod_1.z.ZodIssueCode.custom,
344
+ path: [path],
345
+ message: 'Duplicate job IDs are not allowed',
346
+ });
347
+ }
348
+ };
349
+ exports.ConnectedContactCompletionSchema = zod_1.z
350
+ .object({
351
+ connection: zod_1.z.literal('CONNECTED'),
352
+ workerState: exports.ContactWorkerStateSchema,
353
+ jobs: zod_1.z.array(exports.ContactJobResultEntrySchema).max(20),
354
+ })
355
+ .strict()
356
+ .superRefine((data, ctx) => rejectDuplicateIds(data.jobs.map((entry) => entry.jobId), ctx, 'jobs'));
357
+ /** The only result a follow-up (didn't answer / can't talk) may record: the
358
+ * agent sent the job by WhatsApp. A worker who never responded cannot have a
359
+ * DISCUSSED/NOT_INTERESTED response (spec §3). */
360
+ const FollowUpJobResultSchema = zod_1.z
361
+ .object({ kind: zod_1.z.literal('OFFER_SENT'), channel: zod_1.z.literal('WHATSAPP') })
362
+ .strict();
363
+ exports.FollowUpContactCompletionSchema = zod_1.z
364
+ .object({
365
+ connection: zod_1.z.enum(['NO_ANSWER', 'BUSY']),
366
+ jobs: zod_1.z
367
+ .array(zod_1.z
368
+ .object({ jobId: zod_1.z.string().uuid(), result: FollowUpJobResultSchema })
369
+ .strict())
370
+ .max(20)
371
+ .optional(),
372
+ })
373
+ .strict()
374
+ .superRefine((data, ctx) => {
375
+ if (data.jobs) {
376
+ rejectDuplicateIds(data.jobs.map((entry) => entry.jobId), ctx, 'jobs');
377
+ }
378
+ });
379
+ const InvalidNumberContactCompletionSchema = zod_1.z
380
+ .object({ connection: zod_1.z.literal('INVALID_NUMBER') })
381
+ .strict();
382
+ /** Kept as an export for existing consumers; now a union of the two
383
+ * non-connected shapes. */
384
+ exports.NonConnectedContactCompletionSchema = zod_1.z.union([
385
+ exports.FollowUpContactCompletionSchema,
386
+ InvalidNumberContactCompletionSchema,
387
+ ]);
388
+ exports.MultiJobContactCompletionSchema = zod_1.z.union([
389
+ exports.ConnectedContactCompletionSchema,
390
+ exports.FollowUpContactCompletionSchema,
391
+ InvalidNumberContactCompletionSchema,
392
+ ]);
393
+ exports.ContactFeedbackDataSchema = zod_1.z.union([
394
+ exports.MultiJobContactCompletionSchema,
395
+ exports.CompletePhoneCallBodySchema,
396
+ ]);
397
+ exports.CandidateContactChannelSchema = zod_1.z.enum(['PHONE', 'WHATSAPP']);
398
+ exports.ContactSessionStatusSchema = zod_1.z.enum([
399
+ 'ACTIVE',
400
+ 'COMPLETED',
401
+ 'CANCELLED',
402
+ 'EXPIRED',
403
+ ]);
404
+ exports.ContactJobSummarySchema = zod_1.z
405
+ .object({
406
+ id: zod_1.z.string().uuid(),
407
+ description: zod_1.z.string(),
408
+ tradeName: zod_1.z.string().nullable(),
409
+ postcode: zod_1.z.string().nullable(),
410
+ distanceKm: zod_1.z.number().nullable(),
411
+ driveMinutes: zod_1.z.number().nullable(),
412
+ transitMinutes: zod_1.z.number().nullable(),
413
+ pay: jobs_contract_1.PaySchema,
414
+ hours: zod_1.z.number().nullable(),
415
+ positionsAvailable: zod_1.z.number().int().min(0),
416
+ startDate: jobs_contract_1.JobStartDateSchema.nullable(),
417
+ previousContact: exports.ContactJobPreviousContextSchema,
418
+ })
419
+ .strict();
420
+ exports.ContactSessionJobSchema = zod_1.z
421
+ .object({
422
+ jobId: zod_1.z.string().uuid(),
423
+ subjectKind: zod_1.z.enum(['OWNED', 'CURATED']),
424
+ subjectId: zod_1.z.string().uuid(),
425
+ isPrimary: zod_1.z.boolean(),
426
+ attachedAt: zod_1.z.string().datetime(),
427
+ job: exports.ContactJobSummarySchema,
428
+ })
429
+ .strict();
430
+ exports.ContactSessionSummarySchema = zod_1.z
431
+ .object({
432
+ revealSessionId: zod_1.z.string().uuid(),
433
+ channel: exports.CandidateContactChannelSchema,
434
+ status: exports.ContactSessionStatusSchema,
435
+ candidate: zod_1.z
436
+ .object({
437
+ subjectKind: zod_1.z.enum(['OWNED', 'CURATED']),
438
+ subjectId: zod_1.z.string().uuid(),
439
+ canonicalWorker: exports.CanonicalWorkerRefSchema,
440
+ firstName: zod_1.z.string(),
441
+ lastName: zod_1.z.string().nullable(),
442
+ })
443
+ .strict(),
444
+ jobs: zod_1.z.array(exports.ContactSessionJobSchema).max(20),
445
+ startedAt: zod_1.z.string().datetime(),
446
+ expiresAt: zod_1.z.string().datetime(),
447
+ })
448
+ .strict();
449
+ exports.AlternativeContactJobSchema = zod_1.z
450
+ .object({
451
+ jobId: zod_1.z.string().uuid(),
452
+ subjectKind: zod_1.z.enum(['OWNED', 'CURATED']),
453
+ subjectId: zod_1.z.string().uuid(),
454
+ job: exports.ContactJobSummarySchema,
455
+ })
456
+ .strict();
457
+ const ContactMatchTupleSchema = zod_1.z
458
+ .object({
459
+ subjectKind: zod_1.z.enum(['OWNED', 'CURATED']),
460
+ subjectId: zod_1.z.string().uuid(),
461
+ jobId: zod_1.z.string().uuid(),
462
+ })
463
+ .strict();
464
+ const SelectedContactJobsSchema = zod_1.z
465
+ .array(ContactMatchTupleSchema)
466
+ .max(19)
467
+ .superRefine((jobs, ctx) => rejectDuplicateIds(jobs.map((entry) => entry.jobId), ctx, 'selectedJobs'));
468
+ exports.AttachContactSessionJobsBodySchema = zod_1.z
469
+ .object({
470
+ jobs: zod_1.z.array(ContactMatchTupleSchema).min(1).max(20),
471
+ })
472
+ .strict()
473
+ .superRefine((data, ctx) => rejectDuplicateIds(data.jobs.map((entry) => entry.jobId), ctx, 'jobs'));
474
+ exports.ConfirmWhatsAppSentBodySchema = zod_1.z
475
+ .object({
476
+ jobIds: zod_1.z.array(zod_1.z.string().uuid()).min(1).max(20),
477
+ /**
478
+ * Jobs whose "already sent by X" history the agent was shown and chose to
479
+ * message anyway. The server waives its duplicate-outreach guard for
480
+ * exactly these, so a client can never widen the waiver past what it
481
+ * displayed — an id here that isn't in `jobIds` is a client bug, and is
482
+ * rejected rather than ignored.
483
+ */
484
+ allowDuplicateJobIds: zod_1.z.array(zod_1.z.string().uuid()).max(20).optional(),
485
+ })
486
+ .strict()
487
+ .superRefine((data, ctx) => {
488
+ rejectDuplicateIds(data.jobIds, ctx, 'jobIds');
489
+ if (!data.allowDuplicateJobIds)
490
+ return;
491
+ rejectDuplicateIds(data.allowDuplicateJobIds, ctx, 'allowDuplicateJobIds');
492
+ const submitted = new Set(data.jobIds);
493
+ for (const jobId of data.allowDuplicateJobIds) {
494
+ if (submitted.has(jobId))
495
+ continue;
496
+ ctx.addIssue({
497
+ code: zod_1.z.ZodIssueCode.custom,
498
+ path: ['allowDuplicateJobIds'],
499
+ message: 'allowDuplicateJobIds must be a subset of jobIds',
500
+ });
501
+ return;
502
+ }
503
+ });
504
+ exports.StaleContactJobConflictDetailsSchema = zod_1.z
505
+ .object({
506
+ kind: zod_1.z.literal('STALE_CONTACT_JOB'),
507
+ jobId: zod_1.z.string().uuid(),
508
+ reason: zod_1.z.enum(['CLOSED', 'FULL', 'INELIGIBLE', 'SUPPRESSED', 'RESERVED']),
509
+ })
510
+ .strict();
511
+ exports.StaleContactJobConflictResponseSchema = error_schemas_1.ErrorResponseSchema.extend({
512
+ details: exports.StaleContactJobConflictDetailsSchema,
513
+ });
514
+ exports.ContactCompletionResultSchema = zod_1.z.object({
515
+ state: exports.CandidateCoordinationStateSchema,
516
+ affectedJobIds: zod_1.z.array(zod_1.z.string().uuid()),
517
+ contactRestriction: exports.CandidateContactRestrictionSchema.optional(),
518
+ /** WhatsApp completion only: submitted jobs skipped because they went stale
519
+ * between marking and submission. The recorded jobs (affectedJobIds) still
520
+ * committed and the session completed (design 2026-07-23 §8). */
521
+ staleJobIds: zod_1.z.array(zod_1.z.string().uuid()).optional(),
522
+ });
523
+ /**
524
+ * A normalized result shown in the current user's candidate-contact history.
525
+ * WhatsApp starts in AWAITING_FEEDBACK and can be updated later; phone calls
526
+ * already collect their result as part of the call workflow.
527
+ */
528
+ exports.CandidateContactHistoryOutcomeSchema = zod_1.z.enum([
529
+ 'AWAITING_FEEDBACK',
530
+ 'INTERESTED',
531
+ 'NO_ANSWER',
532
+ 'BUSY',
533
+ 'NOT_INTERESTED',
534
+ 'INVALID_NUMBER',
535
+ ]);
536
+ exports.CandidateContactHistoryItemSchema = zod_1.z.object({
537
+ id: zod_1.z.string().uuid(),
538
+ agentId: zod_1.z.string().uuid(),
539
+ agent: zod_1.z
540
+ .object({
541
+ id: zod_1.z.string().uuid(),
542
+ firstName: zod_1.z.string(),
543
+ lastName: zod_1.z.string().nullable(),
544
+ })
545
+ .optional(),
546
+ subjectKind: zod_1.z.enum(['OWNED', 'CURATED']),
547
+ subjectId: zod_1.z.string().uuid(),
548
+ worker: zod_1.z.object({
549
+ firstName: zod_1.z.string(),
550
+ lastName: zod_1.z.string().nullable(),
551
+ postcode: zod_1.z.string().nullable(),
552
+ }),
553
+ job: zod_1.z.object({
554
+ id: zod_1.z.string().uuid(),
555
+ tradeName: zod_1.z.string().nullable(),
556
+ postcode: zod_1.z.string().nullable(),
557
+ firstAgent: zod_1.z
558
+ .object({
559
+ id: zod_1.z.string().uuid(),
560
+ firstName: zod_1.z.string(),
561
+ lastName: zod_1.z.string().nullable(),
562
+ })
563
+ .nullable(),
564
+ }),
565
+ channel: exports.CandidateContactChannelSchema,
566
+ contactedAt: zod_1.z.string().datetime(),
567
+ outcome: exports.CandidateContactHistoryOutcomeSchema,
568
+ feedbackAt: zod_1.z.string().datetime().nullable(),
569
+ feedback: exports.ContactFeedbackDataSchema.nullable(),
570
+ contactSessionId: zod_1.z.string().uuid().nullable().optional(),
571
+ connection: exports.ContactConnectionResultSchema.optional(),
572
+ workerState: exports.ContactWorkerStateSchema.nullable().optional(),
573
+ jobResult: exports.ContactJobResultSchema.nullable().optional(),
574
+ canRecordFeedback: zod_1.z.boolean(),
575
+ });
576
+ exports.CandidateContactHistoryQuerySchema = zod_1.z.object({
577
+ page: zod_1.z.coerce.number().int().min(1).optional(),
578
+ limit: zod_1.z.coerce.number().int().min(1).max(50).optional(),
579
+ contactedById: zod_1.z.string().uuid().optional(),
580
+ status: zod_1.z.enum(['ALL', 'PENDING', 'COMPLETED']).optional(),
581
+ channel: exports.CandidateContactChannelSchema.optional(),
582
+ worker: zod_1.z
583
+ .object({
584
+ name: common_schemas_1.NameFilterSchema.optional(),
585
+ phone: zod_1.z.string().trim().max(30).optional(),
586
+ postcode: zod_1.z.string().trim().max(16).optional(),
587
+ })
588
+ .optional(),
589
+ job: zod_1.z
590
+ .object({
591
+ location: common_schemas_1.LocationFilterSchema.optional(),
592
+ tradeId: zod_1.z.string().uuid().optional(),
593
+ userId: zod_1.z.string().uuid().optional(),
594
+ })
595
+ .optional(),
596
+ });
597
+ exports.CandidateContactHistoryResponseSchema = zod_1.z.object({
598
+ items: zod_1.z.array(exports.CandidateContactHistoryItemSchema),
599
+ total: zod_1.z.number().int().min(0),
600
+ hasMore: zod_1.z.boolean(),
601
+ totalPages: zod_1.z.number().int().min(0),
602
+ });
603
+ exports.CandidatePhoneCancellationReasonSchema = zod_1.z.enum([
604
+ 'ACCIDENTAL_REVEAL',
605
+ 'INTERRUPTED',
606
+ 'WRONG_CANDIDATE_OR_JOB',
607
+ 'TECHNICAL_PROBLEM',
608
+ ]);
609
+ exports.CandidateRefPathSchema = zod_1.z.object({
610
+ jobId: zod_1.z.string().uuid(),
611
+ subjectKind: zod_1.z.enum(['OWNED', 'CURATED']),
612
+ subjectId: zod_1.z.string().uuid(),
613
+ });
614
+ exports.StartPhoneCallResponseSchema = zod_1.z.object({
615
+ callSessionId: zod_1.z.string().uuid(),
616
+ outcomeAvailableAt: zod_1.z.record(exports.PhoneCallOutcomeSchema, zod_1.z.string().datetime()),
617
+ state: exports.CandidateCoordinationStateSchema,
618
+ });
619
+ exports.ActivePhoneCallSchema = zod_1.z.object({
620
+ callSessionId: zod_1.z.string().uuid(),
621
+ revealSessionId: zod_1.z.string().uuid(),
622
+ startedAt: zod_1.z.string().datetime(),
623
+ expiresAt: zod_1.z.string().datetime(),
624
+ outcomeAvailableAt: zod_1.z.record(exports.PhoneCallOutcomeSchema, zod_1.z.string().datetime()),
625
+ candidate: zod_1.z.object({
626
+ subjectKind: zod_1.z.enum(['OWNED', 'CURATED']),
627
+ subjectId: zod_1.z.string().uuid(),
628
+ canonicalWorker: exports.CanonicalWorkerRefSchema,
629
+ firstName: zod_1.z.string(),
630
+ lastName: zod_1.z.string().nullable(),
631
+ }),
632
+ job: zod_1.z.object({
633
+ id: zod_1.z.string().uuid(),
634
+ description: zod_1.z.string(),
635
+ tradeName: zod_1.z.string().nullable(),
636
+ postcode: zod_1.z.string().nullable(),
637
+ }),
638
+ phoneNumber: common_schemas_1.PhoneNumberResponseSchema,
639
+ });
640
+ exports.ActivePhoneCallResponseSchema = zod_1.z.object({
641
+ call: exports.ActivePhoneCallSchema.nullable(),
642
+ });
643
+ exports.PhoneRevealResponseSchema = zod_1.z.object({
644
+ revealSessionId: zod_1.z.string().uuid(),
645
+ expiresAt: zod_1.z.string().datetime(),
646
+ channel: exports.CandidateContactChannelSchema,
647
+ phoneNumbers: zod_1.z.array(common_schemas_1.PhoneNumberResponseSchema),
648
+ call: exports.StartPhoneCallResponseSchema.nullable(),
649
+ quota: zod_1.z.object({
650
+ remaining: zod_1.z.number().int().min(0),
651
+ resetsAt: zod_1.z.string().datetime(),
652
+ }),
653
+ });
654
+ exports.PhoneCallOutcomeResponseSchema = zod_1.z.object({
655
+ state: exports.CandidateCoordinationStateSchema,
656
+ });
657
+ exports.CancelPhoneCallResponseSchema = zod_1.z.object({
658
+ state: exports.CandidateCoordinationStateSchema,
659
+ cancellation: zod_1.z.object({
660
+ count30Minutes: zod_1.z.number().int().min(0),
661
+ cooldownUntil: zod_1.z.string().datetime().nullable(),
662
+ }),
663
+ });
664
+ exports.CandidatePresenceSnapshotSchema = zod_1.z.object({
665
+ jobs: zod_1.z.array(exports.JobCandidatePresenceChangedSchema),
666
+ });
667
+ exports.CandidateCoordinationSnapshotSchema = zod_1.z.object({
668
+ candidates: zod_1.z.array(exports.CandidateCoordinationStateSchema),
669
+ });
670
+ exports.candidateCoordinationContract = c.router({
671
+ heartbeatPresence: {
672
+ method: 'PUT',
673
+ path: '/jobs/:jobId/candidate-presence',
674
+ pathParams: zod_1.z.object({ jobId: zod_1.z.string().uuid() }),
675
+ body: zod_1.z.object({ clientId: zod_1.z.string().uuid() }),
676
+ responses: {
677
+ 200: exports.JobCandidatePresenceChangedSchema,
678
+ 403: error_schemas_1.ErrorResponseSchema,
679
+ 404: error_schemas_1.ErrorResponseSchema,
680
+ },
681
+ summary: 'Enter or renew focused presence on a job candidates page',
682
+ metadata: { tags: ['Candidate Coordination'] },
683
+ },
684
+ leavePresence: {
685
+ method: 'DELETE',
686
+ path: '/jobs/:jobId/candidate-presence',
687
+ pathParams: zod_1.z.object({ jobId: zod_1.z.string().uuid() }),
688
+ body: zod_1.z.object({ clientId: zod_1.z.string().uuid() }),
689
+ responses: { 200: exports.JobCandidatePresenceChangedSchema },
690
+ summary: 'Leave a job candidates page presence set',
691
+ metadata: { tags: ['Candidate Coordination'] },
692
+ },
693
+ presenceSnapshot: {
694
+ method: 'GET',
695
+ // Keep the literal route deeper than /v2/jobs/:id so Express cannot
696
+ // interpret "candidate-presence" as the UUID job id.
697
+ path: '/jobs/candidate-presence/snapshot',
698
+ query: zod_1.z.object({ jobIds: zod_1.z.string().min(1) }),
699
+ responses: { 200: exports.CandidatePresenceSnapshotSchema },
700
+ summary: 'Batch current candidate-page presence for jobs',
701
+ metadata: { tags: ['Candidate Coordination'] },
702
+ },
703
+ coordinationSnapshot: {
704
+ method: 'GET',
705
+ path: '/jobs/:jobId/candidate-coordination',
706
+ pathParams: zod_1.z.object({ jobId: zod_1.z.string().uuid() }),
707
+ query: zod_1.z.object({
708
+ ownedIds: zod_1.z.string().optional(),
709
+ curatedIds: zod_1.z.string().optional(),
710
+ }),
711
+ responses: { 200: exports.CandidateCoordinationSnapshotSchema },
712
+ summary: 'Current calling/edit/ownership state for a job candidate page',
713
+ metadata: { tags: ['Candidate Coordination'] },
714
+ },
715
+ heartbeatEditLease: {
716
+ method: 'PUT',
717
+ path: '/candidate-coordination/:kind/:id/edit-lease',
718
+ pathParams: zod_1.z.object({
719
+ kind: exports.CanonicalWorkerKindSchema,
720
+ id: zod_1.z.string().uuid(),
721
+ }),
722
+ body: exports.EditLeaseHeartbeatBodySchema,
723
+ responses: {
724
+ 200: exports.CandidateCoordinationStateSchema,
725
+ 403: error_schemas_1.ErrorResponseSchema,
726
+ 404: error_schemas_1.ErrorResponseSchema,
727
+ 409: exports.CandidateCoordinationConflictErrorSchema,
728
+ },
729
+ summary: 'Acquire or renew a worker editing lease',
730
+ metadata: { tags: ['Candidate Coordination'] },
731
+ },
732
+ releaseEditLease: {
733
+ method: 'DELETE',
734
+ path: '/candidate-coordination/:kind/:id/edit-lease',
735
+ pathParams: zod_1.z.object({
736
+ kind: exports.CanonicalWorkerKindSchema,
737
+ id: zod_1.z.string().uuid(),
738
+ }),
739
+ body: zod_1.z.object({ clientId: zod_1.z.string().uuid() }),
740
+ responses: { 200: exports.CandidateCoordinationStateSchema },
741
+ summary: 'Release a worker editing lease',
742
+ metadata: { tags: ['Candidate Coordination'] },
743
+ },
744
+ revealPhone: {
745
+ method: 'POST',
746
+ path: '/jobs/:jobId/candidates/:subjectKind/:subjectId/phone-reveal',
747
+ pathParams: exports.CandidateRefPathSchema,
748
+ body: zod_1.z
749
+ .object({
750
+ channel: exports.CandidateContactChannelSchema,
751
+ selectedJobs: SelectedContactJobsSchema.optional(),
752
+ /**
753
+ * Set when the agent was shown this job's existing WhatsApp outreach
754
+ * and chose to message again. Only waives the early reveal-time
755
+ * warning; every job still clears the authoritative duplicate check
756
+ * at confirm time via `allowDuplicateJobIds`.
757
+ */
758
+ allowDuplicateWhatsApp: zod_1.z.boolean().optional(),
759
+ })
760
+ .strict(),
761
+ responses: {
762
+ 200: exports.PhoneRevealResponseSchema,
763
+ 403: error_schemas_1.ErrorResponseSchema,
764
+ 404: error_schemas_1.ErrorResponseSchema,
765
+ 409: error_schemas_1.ErrorResponseSchema,
766
+ 429: error_schemas_1.ErrorResponseSchema,
767
+ },
768
+ summary: 'Declare contact intent, then reveal candidate phone numbers',
769
+ metadata: { tags: ['Candidate Coordination'] },
770
+ },
771
+ activeContactSession: {
772
+ method: 'GET',
773
+ path: '/contact-sessions/active',
774
+ responses: {
775
+ 200: zod_1.z.object({ session: exports.ContactSessionSummarySchema.nullable() }),
776
+ 403: error_schemas_1.ErrorResponseSchema,
777
+ },
778
+ summary: 'Recover the current user active contact session',
779
+ metadata: { tags: ['Candidate Coordination'] },
780
+ },
781
+ contactSessionAlternatives: {
782
+ method: 'GET',
783
+ path: '/contact-sessions/:revealSessionId/alternatives',
784
+ pathParams: zod_1.z.object({ revealSessionId: zod_1.z.string().uuid() }),
785
+ responses: {
786
+ 200: zod_1.z.array(exports.AlternativeContactJobSchema),
787
+ 403: error_schemas_1.ErrorResponseSchema,
788
+ 404: error_schemas_1.ErrorResponseSchema,
789
+ 409: error_schemas_1.ErrorResponseSchema,
790
+ },
791
+ summary: 'List ranked redacted alternatives for a contact session',
792
+ metadata: { tags: ['Candidate Coordination'] },
793
+ },
794
+ attachContactSessionJobs: {
795
+ method: 'POST',
796
+ path: '/contact-sessions/:revealSessionId/jobs',
797
+ pathParams: zod_1.z.object({ revealSessionId: zod_1.z.string().uuid() }),
798
+ body: exports.AttachContactSessionJobsBodySchema,
799
+ responses: {
800
+ 200: exports.ContactSessionSummarySchema,
801
+ 403: error_schemas_1.ErrorResponseSchema,
802
+ 404: error_schemas_1.ErrorResponseSchema,
803
+ 409: zod_1.z.union([
804
+ exports.StaleContactJobConflictResponseSchema,
805
+ error_schemas_1.ErrorResponseSchema,
806
+ ]),
807
+ },
808
+ summary: 'Attach revalidated discussed jobs to a contact session',
809
+ metadata: { tags: ['Candidate Coordination'] },
810
+ },
811
+ confirmWhatsAppSent: {
812
+ method: 'POST',
813
+ path: '/contact-sessions/:revealSessionId/whatsapp-sent',
814
+ pathParams: zod_1.z.object({ revealSessionId: zod_1.z.string().uuid() }),
815
+ body: exports.ConfirmWhatsAppSentBodySchema,
816
+ responses: {
817
+ 200: exports.ContactCompletionResultSchema,
818
+ 403: error_schemas_1.ErrorResponseSchema,
819
+ 404: error_schemas_1.ErrorResponseSchema,
820
+ 409: zod_1.z.union([
821
+ exports.StaleContactJobConflictResponseSchema,
822
+ error_schemas_1.ErrorResponseSchema,
823
+ ]),
824
+ },
825
+ summary: 'Confirm WhatsApp delivery for attached contact-session jobs',
826
+ metadata: { tags: ['Candidate Coordination'] },
827
+ },
828
+ activePhoneCall: {
829
+ method: 'GET',
830
+ path: '/candidate-phone-calls/active',
831
+ responses: { 200: exports.ActivePhoneCallResponseSchema },
832
+ summary: 'Recover the current user active phone call and its context',
833
+ metadata: { tags: ['Candidate Coordination'] },
834
+ },
835
+ contactHistory: {
836
+ method: 'GET',
837
+ path: '/candidate-contacts/history',
838
+ query: exports.CandidateContactHistoryQuerySchema,
839
+ responses: { 200: exports.CandidateContactHistoryResponseSchema },
840
+ summary: 'Ability-scoped job-candidate contact history, including delayed WhatsApp feedback',
841
+ metadata: { tags: ['Candidate Coordination'] },
842
+ },
843
+ recordWhatsAppFeedback: {
844
+ method: 'POST',
845
+ path: '/candidate-contacts/:contactEventId/whatsapp-feedback',
846
+ pathParams: zod_1.z.object({ contactEventId: zod_1.z.string().uuid() }),
847
+ body: exports.CompletePhoneCallBodySchema,
848
+ responses: {
849
+ 200: exports.CandidateContactHistoryItemSchema,
850
+ 404: error_schemas_1.ErrorResponseSchema,
851
+ 409: error_schemas_1.ErrorResponseSchema,
852
+ },
853
+ summary: 'Record or update feedback received after a WhatsApp contact',
854
+ metadata: { tags: ['Candidate Coordination'] },
855
+ },
856
+ recordContactFeedback: {
857
+ method: 'POST',
858
+ path: '/candidate-contacts/:contactEventId/feedback',
859
+ pathParams: zod_1.z.object({ contactEventId: zod_1.z.string().uuid() }),
860
+ body: exports.CompletePhoneCallBodySchema,
861
+ responses: {
862
+ 200: exports.CandidateContactHistoryItemSchema,
863
+ 404: error_schemas_1.ErrorResponseSchema,
864
+ 409: error_schemas_1.ErrorResponseSchema,
865
+ },
866
+ summary: 'Record or revise feedback for a phone or WhatsApp contact',
867
+ metadata: { tags: ['Candidate Coordination'] },
868
+ },
869
+ completePhoneCall: {
870
+ method: 'POST',
871
+ path: '/candidate-phone-calls/:callSessionId/outcome',
872
+ pathParams: zod_1.z.object({ callSessionId: zod_1.z.string().uuid() }),
873
+ body: exports.ContactFeedbackDataSchema,
874
+ responses: {
875
+ 200: exports.ContactCompletionResultSchema,
876
+ 403: error_schemas_1.ErrorResponseSchema,
877
+ 404: error_schemas_1.ErrorResponseSchema,
878
+ 409: zod_1.z.union([
879
+ exports.StaleContactJobConflictResponseSchema,
880
+ error_schemas_1.ErrorResponseSchema,
881
+ ]),
882
+ },
883
+ summary: 'Record a call outcome and transition ownership',
884
+ metadata: { tags: ['Candidate Coordination'] },
885
+ },
886
+ cancelPhoneCall: {
887
+ method: 'DELETE',
888
+ path: '/candidate-phone-calls/:callSessionId',
889
+ pathParams: zod_1.z.object({ callSessionId: zod_1.z.string().uuid() }),
890
+ body: zod_1.z
891
+ .object({ reason: exports.CandidatePhoneCancellationReasonSchema })
892
+ .strict(),
893
+ responses: { 200: exports.CancelPhoneCallResponseSchema },
894
+ summary: 'Cancel, audit, and release a short calling claim',
895
+ metadata: { tags: ['Candidate Coordination'] },
896
+ },
897
+ markPhoneInvalid: {
898
+ method: 'POST',
899
+ path: '/candidate-phone-reveals/:revealSessionId/numbers/:phoneNumberId/invalid',
900
+ pathParams: zod_1.z.object({
901
+ revealSessionId: zod_1.z.string().uuid(),
902
+ phoneNumberId: zod_1.z.string().uuid(),
903
+ }),
904
+ body: zod_1.z.object({}).strict(),
905
+ responses: {
906
+ 200: exports.PhoneCallOutcomeResponseSchema,
907
+ 403: error_schemas_1.ErrorResponseSchema,
908
+ 404: error_schemas_1.ErrorResponseSchema,
909
+ 409: error_schemas_1.ErrorResponseSchema,
910
+ },
911
+ summary: 'Report one revealed phone number invalid and release ownership',
912
+ metadata: { tags: ['Candidate Coordination'] },
913
+ },
914
+ }, {
915
+ pathPrefix: '/v2',
916
+ commonResponses: {
917
+ 400: error_schemas_1.ErrorResponseSchema,
918
+ 401: error_schemas_1.ErrorResponseSchema,
919
+ 500: error_schemas_1.ErrorResponseSchema,
920
+ },
921
+ });