@dakkitor/api-contracts 1.1.154 → 1.5.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 (353) hide show
  1. package/dist/abilities/abilities.contract.d.ts +55 -1
  2. package/dist/abilities/abilities.contract.d.ts.map +1 -1
  3. package/dist/abilities/abilities.contract.js +95 -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 +330 -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/outreach-service.abilities.json +14 -0
  17. package/dist/abilities/second-agent.abilities.json +430 -43
  18. package/dist/abilities/team-leads.json +71 -6
  19. package/dist/abilities/worker-curator.abilities.json +233 -0
  20. package/dist/actives/actives.contract.d.ts +15521 -19793
  21. package/dist/actives/actives.contract.d.ts.map +1 -1
  22. package/dist/actives/actives.contract.js +517 -114
  23. package/dist/agent-client-links/agent-client-links.contract.d.ts +1431 -291
  24. package/dist/agent-client-links/agent-client-links.contract.d.ts.map +1 -1
  25. package/dist/auth/auth.contract.d.ts +1050 -81
  26. package/dist/auth/auth.contract.d.ts.map +1 -1
  27. package/dist/auth/auth.contract.js +115 -3
  28. package/dist/bookings/booking-worker-summary.spec.d.ts +2 -0
  29. package/dist/bookings/booking-worker-summary.spec.d.ts.map +1 -0
  30. package/dist/bookings/booking-worker-summary.spec.js +25 -0
  31. package/dist/bookings/bookings.contract.d.ts +21631 -27105
  32. package/dist/bookings/bookings.contract.d.ts.map +1 -1
  33. package/dist/bookings/bookings.contract.js +383 -91
  34. package/dist/bookings/bookings.contract.spec.d.ts +2 -0
  35. package/dist/bookings/bookings.contract.spec.d.ts.map +1 -0
  36. package/dist/bookings/bookings.contract.spec.js +11 -0
  37. package/dist/bookings/job-lock.spec.d.ts +2 -0
  38. package/dist/bookings/job-lock.spec.d.ts.map +1 -0
  39. package/dist/bookings/job-lock.spec.js +56 -0
  40. package/dist/bot-parse-cache/bot-parse-cache.contract.d.ts +232 -0
  41. package/dist/bot-parse-cache/bot-parse-cache.contract.d.ts.map +1 -0
  42. package/dist/bot-parse-cache/bot-parse-cache.contract.js +64 -0
  43. package/dist/call-history/call-history.contract.d.ts +1336 -767
  44. package/dist/call-history/call-history.contract.d.ts.map +1 -1
  45. package/dist/call-history/call-history.contract.js +86 -10
  46. package/dist/calls-feed/calls-feed.contract.d.ts +417 -0
  47. package/dist/calls-feed/calls-feed.contract.d.ts.map +1 -0
  48. package/dist/calls-feed/calls-feed.contract.js +32 -0
  49. package/dist/client-contacts/client-contacts.contract.d.ts +410 -226
  50. package/dist/client-contacts/client-contacts.contract.d.ts.map +1 -1
  51. package/dist/client-contacts/client-contacts.contract.js +35 -4
  52. package/dist/clients/clients.contract.d.ts +227 -73
  53. package/dist/clients/clients.contract.d.ts.map +1 -1
  54. package/dist/clients/clients.contract.js +45 -21
  55. package/dist/collaboration-checkings/collaboration-checkings.contract.d.ts +2908 -1834
  56. package/dist/collaboration-checkings/collaboration-checkings.contract.d.ts.map +1 -1
  57. package/dist/collaboration-checkings/collaboration-checkings.contract.js +14 -9
  58. package/dist/collaborations/collaborations.contract.d.ts +2676 -1409
  59. package/dist/collaborations/collaborations.contract.d.ts.map +1 -1
  60. package/dist/collaborations/collaborations.contract.js +33 -9
  61. package/dist/common/call-rating.schema.d.ts.map +1 -1
  62. package/dist/common/call-rating.schema.js +4 -2
  63. package/dist/common/common-schemas.d.ts +59 -11
  64. package/dist/common/common-schemas.d.ts.map +1 -1
  65. package/dist/common/common-schemas.js +55 -29
  66. package/dist/common/error-schemas.d.ts +2 -2
  67. package/dist/common/pagination-query.schema.d.ts +13 -2
  68. package/dist/common/pagination-query.schema.d.ts.map +1 -1
  69. package/dist/common/pagination-query.schema.js +21 -2
  70. package/dist/common/pagination-query.schema.spec.d.ts +2 -0
  71. package/dist/common/pagination-query.schema.spec.d.ts.map +1 -0
  72. package/dist/common/pagination-query.schema.spec.js +53 -0
  73. package/dist/companies/companies.contract.d.ts +53 -28
  74. package/dist/companies/companies.contract.d.ts.map +1 -1
  75. package/dist/companies/companies.contract.js +11 -10
  76. package/dist/crews/crews.contract.d.ts +1010 -196
  77. package/dist/crews/crews.contract.d.ts.map +1 -1
  78. package/dist/crews/crews.contract.js +98 -17
  79. package/dist/crews/crews.contract.spec.d.ts +2 -0
  80. package/dist/crews/crews.contract.spec.d.ts.map +1 -0
  81. package/dist/crews/crews.contract.spec.js +67 -0
  82. package/dist/cron-executions/cron-executions.contract.d.ts +988 -59
  83. package/dist/cron-executions/cron-executions.contract.d.ts.map +1 -1
  84. package/dist/cron-executions/cron-executions.contract.js +127 -7
  85. package/dist/curated-worker-leads/__tests__/disposition-reason.spec.d.ts +2 -0
  86. package/dist/curated-worker-leads/__tests__/disposition-reason.spec.d.ts.map +1 -0
  87. package/dist/curated-worker-leads/__tests__/disposition-reason.spec.js +40 -0
  88. package/dist/curated-worker-leads/candidate-coordination-snapshot.spec.d.ts +2 -0
  89. package/dist/curated-worker-leads/candidate-coordination-snapshot.spec.d.ts.map +1 -0
  90. package/dist/curated-worker-leads/candidate-coordination-snapshot.spec.js +16 -0
  91. package/dist/curated-worker-leads/candidate-coordination.contract.d.ts +21650 -0
  92. package/dist/curated-worker-leads/candidate-coordination.contract.d.ts.map +1 -0
  93. package/dist/curated-worker-leads/candidate-coordination.contract.js +921 -0
  94. package/dist/curated-worker-leads/candidate-coordination.contract.spec.d.ts +2 -0
  95. package/dist/curated-worker-leads/candidate-coordination.contract.spec.d.ts.map +1 -0
  96. package/dist/curated-worker-leads/candidate-coordination.contract.spec.js +51 -0
  97. package/dist/curated-worker-leads/candidate-edit-session.contract.d.ts +2364 -0
  98. package/dist/curated-worker-leads/candidate-edit-session.contract.d.ts.map +1 -0
  99. package/dist/curated-worker-leads/candidate-edit-session.contract.js +173 -0
  100. package/dist/curated-worker-leads/consent-queue.contract.d.ts +4497 -0
  101. package/dist/curated-worker-leads/consent-queue.contract.d.ts.map +1 -0
  102. package/dist/curated-worker-leads/consent-queue.contract.js +201 -0
  103. package/dist/curated-worker-leads/contact-history.spec.d.ts +2 -0
  104. package/dist/curated-worker-leads/contact-history.spec.d.ts.map +1 -0
  105. package/dist/curated-worker-leads/contact-history.spec.js +88 -0
  106. package/dist/curated-worker-leads/contact-session.contract.spec.d.ts +2 -0
  107. package/dist/curated-worker-leads/contact-session.contract.spec.d.ts.map +1 -0
  108. package/dist/curated-worker-leads/contact-session.contract.spec.js +315 -0
  109. package/dist/curated-worker-leads/curated-worker-lead-config.contract.d.ts +489 -0
  110. package/dist/curated-worker-leads/curated-worker-lead-config.contract.d.ts.map +1 -0
  111. package/dist/curated-worker-leads/curated-worker-lead-config.contract.js +88 -0
  112. package/dist/curated-worker-leads/curated-worker-leads.contract.d.ts +135 -0
  113. package/dist/curated-worker-leads/curated-worker-leads.contract.d.ts.map +1 -0
  114. package/dist/curated-worker-leads/curated-worker-leads.contract.js +32 -0
  115. package/dist/curated-worker-leads/job-candidate-cards.spec.d.ts +2 -0
  116. package/dist/curated-worker-leads/job-candidate-cards.spec.d.ts.map +1 -0
  117. package/dist/curated-worker-leads/job-candidate-cards.spec.js +157 -0
  118. package/dist/curated-worker-leads/job-candidates.spec.d.ts +2 -0
  119. package/dist/curated-worker-leads/job-candidates.spec.d.ts.map +1 -0
  120. package/dist/curated-worker-leads/job-candidates.spec.js +140 -0
  121. package/dist/curated-worker-leads/job-feed-match-counts.contract.spec.d.ts +2 -0
  122. package/dist/curated-worker-leads/job-feed-match-counts.contract.spec.d.ts.map +1 -0
  123. package/dist/curated-worker-leads/job-feed-match-counts.contract.spec.js +19 -0
  124. package/dist/curated-worker-leads/jobs-tab.contract.d.ts +18547 -0
  125. package/dist/curated-worker-leads/jobs-tab.contract.d.ts.map +1 -0
  126. package/dist/curated-worker-leads/jobs-tab.contract.js +672 -0
  127. package/dist/curated-worker-leads/lead-agent-area.contract.d.ts +348 -0
  128. package/dist/curated-worker-leads/lead-agent-area.contract.d.ts.map +1 -0
  129. package/dist/curated-worker-leads/lead-agent-area.contract.js +51 -0
  130. package/dist/curated-worker-leads/owned-jobs-tab.contract.d.ts +1116 -0
  131. package/dist/curated-worker-leads/owned-jobs-tab.contract.d.ts.map +1 -0
  132. package/dist/curated-worker-leads/owned-jobs-tab.contract.js +93 -0
  133. package/dist/curated-workers/curated-filter-additions.spec.d.ts +2 -0
  134. package/dist/curated-workers/curated-filter-additions.spec.d.ts.map +1 -0
  135. package/dist/curated-workers/curated-filter-additions.spec.js +17 -0
  136. package/dist/curated-workers/curated-job-seeking.spec.d.ts +2 -0
  137. package/dist/curated-workers/curated-job-seeking.spec.d.ts.map +1 -0
  138. package/dist/curated-workers/curated-job-seeking.spec.js +53 -0
  139. package/dist/curated-workers/curated-workers-id-documents.spec.d.ts +2 -0
  140. package/dist/curated-workers/curated-workers-id-documents.spec.d.ts.map +1 -0
  141. package/dist/curated-workers/curated-workers-id-documents.spec.js +38 -0
  142. package/dist/curated-workers/curated-workers.contract.d.ts +6160 -1906
  143. package/dist/curated-workers/curated-workers.contract.d.ts.map +1 -1
  144. package/dist/curated-workers/curated-workers.contract.js +333 -51
  145. package/dist/dashboards/agent-daily-metrics.contract.d.ts +10 -10
  146. package/dist/dashboards/agent-daily-metrics.contract.js +1 -1
  147. package/dist/dashboards/dashboard-widgets.contract.d.ts +3777 -473
  148. package/dist/dashboards/dashboard-widgets.contract.d.ts.map +1 -1
  149. package/dist/dashboards/dashboard-widgets.contract.js +527 -29
  150. package/dist/dashboards/dashboard.contract.d.ts +8 -8
  151. package/dist/document-intake/document-intake.contract.d.ts +3132 -0
  152. package/dist/document-intake/document-intake.contract.d.ts.map +1 -0
  153. package/dist/document-intake/document-intake.contract.js +418 -0
  154. package/dist/export-jobs/export-jobs.contract.d.ts +3928 -0
  155. package/dist/export-jobs/export-jobs.contract.d.ts.map +1 -0
  156. package/dist/export-jobs/export-jobs.contract.js +240 -0
  157. package/dist/exports-events/exports-events.schemas.d.ts +90 -0
  158. package/dist/exports-events/exports-events.schemas.d.ts.map +1 -0
  159. package/dist/exports-events/exports-events.schemas.js +56 -0
  160. package/dist/files/files.contract.d.ts +133 -126
  161. package/dist/files/files.contract.d.ts.map +1 -1
  162. package/dist/files/files.contract.js +8 -0
  163. package/dist/health/health.contract.d.ts +4 -4
  164. package/dist/index.d.ts +86 -0
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +91 -1
  167. package/dist/interactions/interactions.contract.d.ts +162 -0
  168. package/dist/interactions/interactions.contract.d.ts.map +1 -0
  169. package/dist/interactions/interactions.contract.js +42 -0
  170. package/dist/job-clusters/job-clusters.contract.d.ts +1584 -0
  171. package/dist/job-clusters/job-clusters.contract.d.ts.map +1 -0
  172. package/dist/job-clusters/job-clusters.contract.js +133 -0
  173. package/dist/jobs/jobs.contract.d.ts +16662 -8628
  174. package/dist/jobs/jobs.contract.d.ts.map +1 -1
  175. package/dist/jobs/jobs.contract.js +403 -190
  176. package/dist/jobs/jobs.contract.spec.d.ts +2 -0
  177. package/dist/jobs/jobs.contract.spec.d.ts.map +1 -0
  178. package/dist/jobs/jobs.contract.spec.js +70 -0
  179. package/dist/kpi-impersonation/kpi-impersonation.contract.d.ts +75 -75
  180. package/dist/lead-assignments/lead-assignments.contract.d.ts +2933 -1122
  181. package/dist/lead-assignments/lead-assignments.contract.d.ts.map +1 -1
  182. package/dist/lead-assignments/lead-assignments.contract.js +29 -7
  183. package/dist/lead-distribution/agent-lead-distribution.contract.d.ts +328 -64
  184. package/dist/lead-distribution/agent-lead-distribution.contract.d.ts.map +1 -1
  185. package/dist/lead-distribution/agent-lead-distribution.contract.js +1 -1
  186. package/dist/lead-distribution/lead-distribution-config.contract.d.ts +31 -31
  187. package/dist/leads/leads.contract.d.ts +830 -368
  188. package/dist/leads/leads.contract.d.ts.map +1 -1
  189. package/dist/leads/leads.contract.js +106 -26
  190. package/dist/locations/locations.contract.d.ts +36 -36
  191. package/dist/notifications/notifications.contract.d.ts +1039 -0
  192. package/dist/notifications/notifications.contract.d.ts.map +1 -0
  193. package/dist/notifications/notifications.contract.js +110 -0
  194. package/dist/offices/offices.contract.d.ts +210 -60
  195. package/dist/offices/offices.contract.d.ts.map +1 -1
  196. package/dist/offices/offices.contract.js +18 -4
  197. package/dist/outreach/__tests__/outreach-claim.test.d.ts +2 -0
  198. package/dist/outreach/__tests__/outreach-claim.test.d.ts.map +1 -0
  199. package/dist/outreach/__tests__/outreach-claim.test.js +98 -0
  200. package/dist/outreach/__tests__/outreach-confirm-release.test.d.ts +2 -0
  201. package/dist/outreach/__tests__/outreach-confirm-release.test.d.ts.map +1 -0
  202. package/dist/outreach/__tests__/outreach-confirm-release.test.js +98 -0
  203. package/dist/outreach/__tests__/outreach-contract-additions.spec.d.ts +2 -0
  204. package/dist/outreach/__tests__/outreach-contract-additions.spec.d.ts.map +1 -0
  205. package/dist/outreach/__tests__/outreach-contract-additions.spec.js +78 -0
  206. package/dist/outreach/__tests__/outreach-requests.contract.spec.d.ts +2 -0
  207. package/dist/outreach/__tests__/outreach-requests.contract.spec.d.ts.map +1 -0
  208. package/dist/outreach/__tests__/outreach-requests.contract.spec.js +64 -0
  209. package/dist/outreach/__tests__/outreach-routes.test.d.ts +2 -0
  210. package/dist/outreach/__tests__/outreach-routes.test.d.ts.map +1 -0
  211. package/dist/outreach/__tests__/outreach-routes.test.js +57 -0
  212. package/dist/outreach/__tests__/outreach.schemas.test.d.ts +2 -0
  213. package/dist/outreach/__tests__/outreach.schemas.test.d.ts.map +1 -0
  214. package/dist/outreach/__tests__/outreach.schemas.test.js +144 -0
  215. package/dist/outreach/outreach-requests.contract.d.ts +1108 -0
  216. package/dist/outreach/outreach-requests.contract.d.ts.map +1 -0
  217. package/dist/outreach/outreach-requests.contract.js +134 -0
  218. package/dist/outreach/outreach-requests.schemas.d.ts +49 -0
  219. package/dist/outreach/outreach-requests.schemas.d.ts.map +1 -0
  220. package/dist/outreach/outreach-requests.schemas.js +60 -0
  221. package/dist/outreach/outreach.contract.d.ts +819 -0
  222. package/dist/outreach/outreach.contract.d.ts.map +1 -0
  223. package/dist/outreach/outreach.contract.js +195 -0
  224. package/dist/outreach/outreach.schemas.d.ts +118 -0
  225. package/dist/outreach/outreach.schemas.d.ts.map +1 -0
  226. package/dist/outreach/outreach.schemas.js +135 -0
  227. package/dist/own-research/own-research.contract.d.ts +1356 -552
  228. package/dist/own-research/own-research.contract.d.ts.map +1 -1
  229. package/dist/own-research/own-research.contract.js +14 -3
  230. package/dist/postcodes/postcodes.contract.d.ts +16 -16
  231. package/dist/proofs/proof-category.enum.d.ts +4 -0
  232. package/dist/proofs/proof-category.enum.d.ts.map +1 -0
  233. package/dist/proofs/proof-category.enum.js +5 -0
  234. package/dist/proofs/proof-entity-type.enum.d.ts +4 -0
  235. package/dist/proofs/proof-entity-type.enum.d.ts.map +1 -0
  236. package/dist/proofs/proof-entity-type.enum.js +5 -0
  237. package/dist/proofs/proof-type.enum.d.ts +28 -0
  238. package/dist/proofs/proof-type.enum.d.ts.map +1 -0
  239. package/dist/proofs/proof-type.enum.js +14 -0
  240. package/dist/proofs/proofs.contract.d.ts +3009 -0
  241. package/dist/proofs/proofs.contract.d.ts.map +1 -0
  242. package/dist/proofs/proofs.contract.js +92 -0
  243. package/dist/proofs/proofs.dtos.d.ts +1319 -0
  244. package/dist/proofs/proofs.dtos.d.ts.map +1 -0
  245. package/dist/proofs/proofs.dtos.js +178 -0
  246. package/dist/qualifications/qualifications.contract.d.ts +94 -94
  247. package/dist/realtime/data-changed.d.ts +21 -0
  248. package/dist/realtime/data-changed.d.ts.map +1 -0
  249. package/dist/realtime/data-changed.js +37 -0
  250. package/dist/shared/booking-history.schema.d.ts +27 -0
  251. package/dist/shared/booking-history.schema.d.ts.map +1 -0
  252. package/dist/shared/booking-history.schema.js +22 -0
  253. package/dist/shared/booking-history.spec.d.ts +2 -0
  254. package/dist/shared/booking-history.spec.d.ts.map +1 -0
  255. package/dist/shared/booking-history.spec.js +44 -0
  256. package/dist/shared/contact-suppressions.contract.d.ts +22 -0
  257. package/dist/shared/contact-suppressions.contract.d.ts.map +1 -0
  258. package/dist/shared/contact-suppressions.contract.js +13 -0
  259. package/dist/shared/live-booking.schema.d.ts +57 -0
  260. package/dist/shared/live-booking.schema.d.ts.map +1 -0
  261. package/dist/shared/live-booking.schema.js +34 -0
  262. package/dist/shared/summary-schemas.d.ts +218 -0
  263. package/dist/shared/summary-schemas.d.ts.map +1 -0
  264. package/dist/shared/summary-schemas.js +56 -0
  265. package/dist/sheets-sync/__tests__/sheets-sync-events.schemas.test.d.ts +2 -0
  266. package/dist/sheets-sync/__tests__/sheets-sync-events.schemas.test.d.ts.map +1 -0
  267. package/dist/sheets-sync/__tests__/sheets-sync-events.schemas.test.js +20 -0
  268. package/dist/sheets-sync/__tests__/tab-sync-config.schema.test.d.ts +2 -0
  269. package/dist/sheets-sync/__tests__/tab-sync-config.schema.test.d.ts.map +1 -0
  270. package/dist/sheets-sync/__tests__/tab-sync-config.schema.test.js +41 -0
  271. package/dist/sheets-sync/sheets-sync-events.schemas.d.ts +43 -0
  272. package/dist/sheets-sync/sheets-sync-events.schemas.d.ts.map +1 -0
  273. package/dist/sheets-sync/sheets-sync-events.schemas.js +29 -0
  274. package/dist/sheets-sync/sheets-sync.contract.d.ts +7258 -0
  275. package/dist/sheets-sync/sheets-sync.contract.d.ts.map +1 -0
  276. package/dist/sheets-sync/sheets-sync.contract.js +323 -0
  277. package/dist/telegram/telegram.contract.d.ts +727 -0
  278. package/dist/telegram/telegram.contract.d.ts.map +1 -0
  279. package/dist/telegram/telegram.contract.js +75 -0
  280. package/dist/trades/trade-rate-assessment.d.ts +18 -0
  281. package/dist/trades/trade-rate-assessment.d.ts.map +1 -0
  282. package/dist/trades/trade-rate-assessment.js +46 -0
  283. package/dist/trades/trade-rate-assessment.spec.d.ts +2 -0
  284. package/dist/trades/trade-rate-assessment.spec.d.ts.map +1 -0
  285. package/dist/trades/trade-rate-assessment.spec.js +223 -0
  286. package/dist/trades/trades.contract.d.ts +111 -0
  287. package/dist/trades/trades.contract.d.ts.map +1 -1
  288. package/dist/trades/trades.contract.js +49 -1
  289. package/dist/trades/trades.contract.spec.d.ts +2 -0
  290. package/dist/trades/trades.contract.spec.d.ts.map +1 -0
  291. package/dist/trades/trades.contract.spec.js +173 -0
  292. package/dist/user-access-grants/build-user-access-grant-rules.d.ts +10 -0
  293. package/dist/user-access-grants/build-user-access-grant-rules.d.ts.map +1 -0
  294. package/dist/user-access-grants/build-user-access-grant-rules.js +69 -0
  295. package/dist/user-access-grants/build-user-access-grant-rules.spec.d.ts +2 -0
  296. package/dist/user-access-grants/build-user-access-grant-rules.spec.d.ts.map +1 -0
  297. package/dist/user-access-grants/build-user-access-grant-rules.spec.js +77 -0
  298. package/dist/user-access-grants/user-access-grant-templates.json +454 -0
  299. package/dist/user-access-grants/user-access-grants.contract.d.ts +3886 -0
  300. package/dist/user-access-grants/user-access-grants.contract.d.ts.map +1 -0
  301. package/dist/user-access-grants/user-access-grants.contract.js +189 -0
  302. package/dist/user-access-grants/user-access-grants.contract.spec.d.ts +2 -0
  303. package/dist/user-access-grants/user-access-grants.contract.spec.d.ts.map +1 -0
  304. package/dist/user-access-grants/user-access-grants.contract.spec.js +149 -0
  305. package/dist/users/users.contract.d.ts +1959 -349
  306. package/dist/users/users.contract.d.ts.map +1 -1
  307. package/dist/users/users.contract.js +222 -37
  308. package/dist/users/users.contract.spec.d.ts +2 -0
  309. package/dist/users/users.contract.spec.d.ts.map +1 -0
  310. package/dist/users/users.contract.spec.js +103 -0
  311. package/dist/worker-identity-cases/worker-identity-cases.contract.d.ts +4609 -0
  312. package/dist/worker-identity-cases/worker-identity-cases.contract.d.ts.map +1 -0
  313. package/dist/worker-identity-cases/worker-identity-cases.contract.js +409 -0
  314. package/dist/worker-merge-proposals/worker-merge-proposals.contract.d.ts +1511 -0
  315. package/dist/worker-merge-proposals/worker-merge-proposals.contract.d.ts.map +1 -0
  316. package/dist/worker-merge-proposals/worker-merge-proposals.contract.js +150 -0
  317. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.d.ts +1106 -0
  318. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.d.ts.map +1 -0
  319. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.js +85 -0
  320. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.spec.d.ts +2 -0
  321. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.spec.d.ts.map +1 -0
  322. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.spec.js +216 -0
  323. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.schemas.d.ts +453 -0
  324. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.schemas.d.ts.map +1 -0
  325. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.schemas.js +109 -0
  326. package/dist/workers/do-not-contact.contract.d.ts +46 -0
  327. package/dist/workers/do-not-contact.contract.d.ts.map +1 -0
  328. package/dist/workers/do-not-contact.contract.js +41 -0
  329. package/dist/workers/do-not-contact.contract.spec.d.ts +2 -0
  330. package/dist/workers/do-not-contact.contract.spec.d.ts.map +1 -0
  331. package/dist/workers/do-not-contact.contract.spec.js +47 -0
  332. package/dist/workers/duplicate-group-worker.spec.d.ts +2 -0
  333. package/dist/workers/duplicate-group-worker.spec.d.ts.map +1 -0
  334. package/dist/workers/duplicate-group-worker.spec.js +34 -0
  335. package/dist/workers/filter-exact-flags.spec.d.ts +2 -0
  336. package/dist/workers/filter-exact-flags.spec.d.ts.map +1 -0
  337. package/dist/workers/filter-exact-flags.spec.js +37 -0
  338. package/dist/workers/worker-source-attribution.contract.spec.d.ts +2 -0
  339. package/dist/workers/worker-source-attribution.contract.spec.d.ts.map +1 -0
  340. package/dist/workers/worker-source-attribution.contract.spec.js +442 -0
  341. package/dist/workers/worker-source.spec.d.ts +2 -0
  342. package/dist/workers/worker-source.spec.d.ts.map +1 -0
  343. package/dist/workers/worker-source.spec.js +13 -0
  344. package/dist/workers/worker-status-facets.spec.d.ts +2 -0
  345. package/dist/workers/worker-status-facets.spec.d.ts.map +1 -0
  346. package/dist/workers/worker-status-facets.spec.js +34 -0
  347. package/dist/workers/workers.contract.d.ts +19534 -5969
  348. package/dist/workers/workers.contract.d.ts.map +1 -1
  349. package/dist/workers/workers.contract.js +1096 -113
  350. package/dist/workers/workers.contract.spec.d.ts +2 -0
  351. package/dist/workers/workers.contract.spec.d.ts.map +1 -0
  352. package/dist/workers/workers.contract.spec.js +31 -0
  353. package/package.json +5 -4
@@ -1 +1 @@
1
- {"version":3,"file":"offices.contract.d.ts","sourceRoot":"","sources":["../../contracts/offices/offices.contract.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,YAAY;;;;;;;;;EAIrB,CAAC;AAEL,eAAO,MAAM,kBAAkB;;;;;;EAIM,CAAC;AAEtC,eAAO,MAAM,kBAAkB;;;;;;EAIM,CAAC;AAEtC,eAAO,MAAM,iBAAiB;;;;;;;;;WAEM,CAAC;AAGrC,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAG9D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoE3B,CAAC"}
1
+ {"version":3,"file":"offices.contract.d.ts","sourceRoot":"","sources":["../../contracts/offices/offices.contract.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIvB,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;EAKM,CAAC;AAEtC,eAAO,MAAM,kBAAkB;;;;;;;;;EAWM,CAAC;AAEtC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAEM,CAAC;AAGrC,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAG9D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoE3B,CAAC"}
@@ -6,19 +6,33 @@ const zod_1 = require("zod");
6
6
  const error_schemas_1 = require("../common/error-schemas");
7
7
  const c = (0, core_1.initContract)();
8
8
  // --- Schemas ---
9
- exports.OfficeSchema = zod_1.z
10
- .object({
9
+ /** Inline to avoid circular dependency with users.contract (which imports OfficeSchema). */
10
+ const OfficeManagerSchema = zod_1.z.object({
11
+ id: zod_1.z.string().describe('The unique identifier of the user.'),
12
+ firstName: zod_1.z.string().describe('The first name of the user.'),
13
+ lastName: zod_1.z.string().describe('The last name of the user.'),
14
+ });
15
+ exports.OfficeSchema = zod_1.z.object({
11
16
  id: zod_1.z.string().uuid().describe('Unique identifier for the office'),
12
17
  name: zod_1.z.string().describe('Name of the office'),
18
+ managers: zod_1.z.array(OfficeManagerSchema).optional(),
13
19
  });
14
20
  exports.CreateOfficeSchema = zod_1.z
15
21
  .object({
16
- name: zod_1.z.string().min(1).max(255).describe('Name of the office'),
22
+ name: zod_1.z.string().trim().min(1).max(255).describe('Name of the office'),
23
+ managerIds: zod_1.z.array(zod_1.z.string().uuid()).optional(),
17
24
  })
18
25
  .openapi({ title: 'CreateOffice' });
19
26
  exports.UpdateOfficeSchema = zod_1.z
20
27
  .object({
21
- name: zod_1.z.string().min(1).max(255).optional().describe('Name of the office'),
28
+ name: zod_1.z
29
+ .string()
30
+ .trim()
31
+ .min(1)
32
+ .max(255)
33
+ .optional()
34
+ .describe('Name of the office'),
35
+ managerIds: zod_1.z.array(zod_1.z.string().uuid()).optional(),
22
36
  })
23
37
  .openapi({ title: 'UpdateOffice' });
24
38
  exports.OfficeArraySchema = zod_1.z
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outreach-claim.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outreach-claim.test.d.ts","sourceRoot":"","sources":["../../../contracts/outreach/__tests__/outreach-claim.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const outreach_contract_1 = require("../outreach.contract");
8
+ // --- request ---------------------------------------------------------------
9
+ node_assert_1.default.ok(outreach_contract_1.ClaimNextOutreachBodySchema.safeParse({ deviceId: 'rack-01' }).success);
10
+ // Eligibility is server-side policy and takes no parameters. A caller able to
11
+ // widen its own commute budget is a caller able to message someone the policy
12
+ // excluded, so unknown keys must not survive into the parsed body.
13
+ const widened = outreach_contract_1.ClaimNextOutreachBodySchema.safeParse({
14
+ deviceId: 'rack-01',
15
+ maxCommuteMinutes: 240,
16
+ });
17
+ node_assert_1.default.ok(widened.success);
18
+ node_assert_1.default.equal(Object.prototype.hasOwnProperty.call(widened.data, 'maxCommuteMinutes'), false);
19
+ node_assert_1.default.ok(!outreach_contract_1.ClaimNextOutreachBodySchema.safeParse({}).success);
20
+ // --- TTL -------------------------------------------------------------------
21
+ node_assert_1.default.equal(outreach_contract_1.OUTREACH_LEASE_TTL_MINUTES, 15);
22
+ // --- CLAIMED ---------------------------------------------------------------
23
+ const CLAIMED_PAYLOAD = {
24
+ status: 'CLAIMED',
25
+ lease: {
26
+ leaseId: '3f2504e0-4f89-41d3-9a0c-0305e82c3301',
27
+ expiresAt: '2026-07-28T10:15:00.000Z',
28
+ },
29
+ candidate: {
30
+ subjectKind: 'CURATED',
31
+ subjectId: '9c858901-8a57-4791-81fe-4c455b099bc9',
32
+ canonicalKind: 'CURATED_WORKER',
33
+ canonicalId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
34
+ name: 'Adam Kowalski',
35
+ phoneNumber: '+447700900123',
36
+ commuteMinutes: 45,
37
+ transportMode: 'PUBLIC_TRANSPORT',
38
+ },
39
+ job: {
40
+ title: 'Carpenter needed',
41
+ trade: 'CARPENTER',
42
+ payText: '£180/day',
43
+ locationText: 'Croydon, CR0',
44
+ createdByName: 'Sam Okoro',
45
+ },
46
+ };
47
+ const claimed = outreach_contract_1.ClaimNextOutreachResponseSchema.safeParse(CLAIMED_PAYLOAD);
48
+ node_assert_1.default.ok(claimed.success);
49
+ node_assert_1.default.equal(claimed.data.status, 'CLAIMED');
50
+ // A CLAIMED response missing a required branch member is rejected.
51
+ const { job: _omittedJob, ...claimedWithoutJob } = CLAIMED_PAYLOAD;
52
+ node_assert_1.default.ok(!outreach_contract_1.ClaimNextOutreachResponseSchema.safeParse(claimedWithoutJob).success);
53
+ // --- POOL_EMPTY ------------------------------------------------------------
54
+ // An empty pool is a 200, not an error: the caller winds the campaign down
55
+ // rather than backing off, and must not have to parse an error string.
56
+ const empty = outreach_contract_1.ClaimNextOutreachResponseSchema.safeParse({
57
+ status: 'POOL_EMPTY',
58
+ });
59
+ node_assert_1.default.ok(empty.success);
60
+ node_assert_1.default.equal(empty.data.status, 'POOL_EMPTY');
61
+ // Both are instances of the SAME 200 schema.
62
+ node_assert_1.default.ok(claimed.success && empty.success, 'CLAIMED and POOL_EMPTY are both valid 200 bodies');
63
+ // POOL_EMPTY carries none of the CLAIMED members.
64
+ const pollutedEmpty = outreach_contract_1.ClaimNextOutreachResponseSchema.safeParse({
65
+ status: 'POOL_EMPTY',
66
+ candidate: CLAIMED_PAYLOAD.candidate,
67
+ });
68
+ node_assert_1.default.ok(pollutedEmpty.success);
69
+ node_assert_1.default.equal(Object.prototype.hasOwnProperty.call(pollutedEmpty.data, 'candidate'), false);
70
+ // An unrecognised discriminant is rejected outright.
71
+ node_assert_1.default.ok(!outreach_contract_1.ClaimNextOutreachResponseSchema.safeParse({ status: 'ERROR' }).success);
72
+ // --- compile-time discrimination -------------------------------------------
73
+ // These probes are never called at runtime. They exist so `tsc` (run by
74
+ // `bun run build`) fails if the union stops discriminating: an unsatisfied
75
+ // `@ts-expect-error` is itself a compile error.
76
+ function renderClaim(res) {
77
+ if (res.status === 'POOL_EMPTY')
78
+ return 'idle';
79
+ return `${res.candidate.name} -> ${res.job.title}`;
80
+ }
81
+ function _unguardedAccessMustNotTypecheck(res) {
82
+ // @ts-expect-error `candidate` exists only on the CLAIMED member.
83
+ void res.candidate;
84
+ }
85
+ void _unguardedAccessMustNotTypecheck;
86
+ function _partialHandlingMustNotTypecheck(res) {
87
+ if (res.status === 'CLAIMED')
88
+ return res.candidate.name;
89
+ // POOL_EMPTY is unhandled, so `res` is not narrowed to `never` here.
90
+ // @ts-expect-error a consumer that handles only one branch fails to typecheck.
91
+ const exhaustive = res;
92
+ return exhaustive;
93
+ }
94
+ void _partialHandlingMustNotTypecheck;
95
+ // The narrowing path does work.
96
+ node_assert_1.default.equal(renderClaim(claimed.data), 'Adam Kowalski -> Carpenter needed');
97
+ node_assert_1.default.equal(renderClaim(empty.data), 'idle');
98
+ console.log('outreach claim contract OK');
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outreach-confirm-release.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outreach-confirm-release.test.d.ts","sourceRoot":"","sources":["../../../contracts/outreach/__tests__/outreach-confirm-release.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const outreach_contract_1 = require("../outreach.contract");
8
+ const BASE_SENT = {
9
+ deviceId: 'rack-01',
10
+ variantKey: 'greeting_v2',
11
+ deliveryVerified: true,
12
+ sentAt: '2026-07-28T10:07:31.000Z',
13
+ };
14
+ // --- sent: required shape --------------------------------------------------
15
+ const sent = outreach_contract_1.ConfirmOutreachSentBodySchema.safeParse(BASE_SENT);
16
+ node_assert_1.default.ok(sent.success);
17
+ node_assert_1.default.equal(sent.data.deliveryVerified, true);
18
+ node_assert_1.default.equal(sent.data.metadata, undefined);
19
+ // deliveryVerified distinguishes a send whose bubble was SEEN from one that was
20
+ // tapped but never confirmed. Both count as contacted, so `false` is valid.
21
+ const unverified = outreach_contract_1.ConfirmOutreachSentBodySchema.safeParse({
22
+ ...BASE_SENT,
23
+ deliveryVerified: false,
24
+ });
25
+ node_assert_1.default.ok(unverified.success);
26
+ // Missing required fields are rejected, one at a time.
27
+ for (const key of ['deviceId', 'variantKey', 'deliveryVerified', 'sentAt']) {
28
+ const partial = { ...BASE_SENT };
29
+ delete partial[key];
30
+ node_assert_1.default.ok(!outreach_contract_1.ConfirmOutreachSentBodySchema.safeParse(partial).success, `${key} must be required`);
31
+ }
32
+ // sentAt must be an instant, not a free string.
33
+ node_assert_1.default.ok(!outreach_contract_1.ConfirmOutreachSentBodySchema.safeParse({ ...BASE_SENT, sentAt: 'now' })
34
+ .success);
35
+ // --- deviceId is opaque ----------------------------------------------------
36
+ // It is a correlation key, not a parsed identifier. Anything non-empty goes,
37
+ // including values that look nothing like an ADB serial.
38
+ for (const deviceId of [
39
+ 'emulator-5554',
40
+ 'RF8N20XXXXX',
41
+ 'shelf-3/slot-2 (spare)',
42
+ 'urn:relay-lab:device:7',
43
+ '中文设备',
44
+ 'x'.repeat(200),
45
+ ]) {
46
+ node_assert_1.default.ok(outreach_contract_1.ConfirmOutreachSentBodySchema.safeParse({ ...BASE_SENT, deviceId }).success, `deviceId ${deviceId} must be accepted`);
47
+ }
48
+ node_assert_1.default.ok(!outreach_contract_1.ConfirmOutreachSentBodySchema.safeParse({ ...BASE_SENT, deviceId: '' })
49
+ .success);
50
+ // --- metadata round-trips an arbitrary nested object -----------------------
51
+ const metadata = {
52
+ attempt: 2,
53
+ bubbles: ['hi', 'details', 'cta'],
54
+ timings: { openMs: 812, sendMs: 1503, nested: { deep: { flag: true } } },
55
+ note: null,
56
+ };
57
+ const withMeta = outreach_contract_1.ConfirmOutreachSentBodySchema.safeParse({
58
+ ...BASE_SENT,
59
+ metadata,
60
+ });
61
+ node_assert_1.default.ok(withMeta.success);
62
+ node_assert_1.default.deepStrictEqual(withMeta.data.metadata, metadata);
63
+ // --- sent: response --------------------------------------------------------
64
+ // Confirming against an expired lease still succeeds — the message really was
65
+ // sent, and refusing to record it is how a worker gets messaged twice.
66
+ const late = outreach_contract_1.ConfirmOutreachSentResponseSchema.safeParse({
67
+ recorded: true,
68
+ lateConfirm: true,
69
+ });
70
+ node_assert_1.default.ok(late.success);
71
+ node_assert_1.default.equal(late.data.lateConfirm, true);
72
+ node_assert_1.default.ok(outreach_contract_1.ConfirmOutreachSentResponseSchema.safeParse({
73
+ recorded: true,
74
+ lateConfirm: false,
75
+ }).success);
76
+ node_assert_1.default.ok(!outreach_contract_1.ConfirmOutreachSentResponseSchema.safeParse({ recorded: true }).success);
77
+ // --- release ---------------------------------------------------------------
78
+ const released = outreach_contract_1.ReleaseOutreachLeaseBodySchema.safeParse({
79
+ deviceId: 'rack-01',
80
+ reason: 'CHAT_OPEN_FAILED',
81
+ });
82
+ node_assert_1.default.ok(released.success);
83
+ node_assert_1.default.equal(released.data.detail, undefined);
84
+ node_assert_1.default.ok(outreach_contract_1.ReleaseOutreachLeaseBodySchema.safeParse({
85
+ deviceId: 'rack-01',
86
+ reason: 'OTHER',
87
+ detail: 'accessibility service restarted mid-compose',
88
+ }).success);
89
+ // Release is for failures BEFORE the send button is tapped, never after: there
90
+ // is no "already sent" reason.
91
+ node_assert_1.default.ok(!outreach_contract_1.ReleaseOutreachLeaseBodySchema.safeParse({
92
+ deviceId: 'rack-01',
93
+ reason: 'ALREADY_SENT',
94
+ }).success);
95
+ node_assert_1.default.ok(!outreach_contract_1.ReleaseOutreachLeaseBodySchema.safeParse({ deviceId: 'rack-01' }).success);
96
+ node_assert_1.default.ok(outreach_contract_1.ReleaseOutreachLeaseResponseSchema.safeParse({ released: true }).success);
97
+ node_assert_1.default.ok(!outreach_contract_1.ReleaseOutreachLeaseResponseSchema.safeParse({ released: false }).success);
98
+ console.log('outreach confirm/release contract OK');
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outreach-contract-additions.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outreach-contract-additions.spec.d.ts","sourceRoot":"","sources":["../../../contracts/outreach/__tests__/outreach-contract-additions.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const bun_test_1 = require("bun:test");
4
+ const outreach_schemas_1 = require("../outreach.schemas");
5
+ const jobs_tab_contract_1 = require("../../curated-worker-leads/jobs-tab.contract");
6
+ (0, bun_test_1.describe)('1.5.0 additions stay backward compatible', () => {
7
+ (0, bun_test_1.it)('OutreachJobSchema carries createdByName, nullable', () => {
8
+ (0, bun_test_1.expect)(outreach_schemas_1.OutreachJobSchema.parse({
9
+ title: 'Need 1 x bricklayer',
10
+ trade: 'Bricklayer',
11
+ payText: null,
12
+ locationText: 'SW1A 1AA',
13
+ createdByName: null,
14
+ }).createdByName).toBeNull();
15
+ });
16
+ (0, bun_test_1.it)('JobFeedMatchCountSchema still parses a 1.4.0-shaped payload', () => {
17
+ // The whole point of `.optional()`: an API that has not deployed the new
18
+ // CTE yet, and a 1.4.0 consumer, both keep working.
19
+ const parsed = jobs_tab_contract_1.JobFeedMatchCountSchema.parse({
20
+ owned: 3,
21
+ curated: 4,
22
+ workersContactedByViewerCount: 1,
23
+ workersContactedByOthersCount: 2,
24
+ pendingEnrichmentCount: 0,
25
+ });
26
+ (0, bun_test_1.expect)(parsed.outreachRequest).toBeUndefined();
27
+ });
28
+ (0, bun_test_1.it)('JobFeedMatchCountSchema carries an outreach request when there is one', () => {
29
+ const parsed = jobs_tab_contract_1.JobFeedMatchCountSchema.parse({
30
+ owned: 3,
31
+ curated: 4,
32
+ workersContactedByViewerCount: 1,
33
+ workersContactedByOthersCount: 2,
34
+ pendingEnrichmentCount: 0,
35
+ outreachRequest: {
36
+ id: '22222222-2222-4222-8222-222222222222',
37
+ status: 'RUNNING',
38
+ requestedByName: 'Priya Shah',
39
+ contactedCount: 142,
40
+ },
41
+ });
42
+ (0, bun_test_1.expect)(parsed.outreachRequest?.contactedCount).toBe(142);
43
+ (0, bun_test_1.expect)(parsed.outreachRequest?.id).toBe('22222222-2222-4222-8222-222222222222');
44
+ });
45
+ (0, bun_test_1.it)('rejects an open request without an id', () => {
46
+ // The id is REQUIRED inside the object (the object itself stays nullable
47
+ // and optional). It is the only route a browser has to the request id:
48
+ // cancel is agent-lane while the queue list route is service-key only, so
49
+ // omitting it would leave the cancel route unreachable.
50
+ (0, bun_test_1.expect)(() => jobs_tab_contract_1.JobFeedMatchCountSchema.parse({
51
+ owned: 0,
52
+ curated: 0,
53
+ workersContactedByViewerCount: 0,
54
+ workersContactedByOthersCount: 0,
55
+ pendingEnrichmentCount: 0,
56
+ outreachRequest: {
57
+ status: 'PENDING',
58
+ requestedByName: null,
59
+ contactedCount: 0,
60
+ },
61
+ })).toThrow();
62
+ });
63
+ (0, bun_test_1.it)('null means "no open request", distinct from "not computed"', () => {
64
+ (0, bun_test_1.expect)(jobs_tab_contract_1.JobFeedMatchCountSchema.parse({
65
+ owned: 0,
66
+ curated: 0,
67
+ workersContactedByViewerCount: 0,
68
+ workersContactedByOthersCount: 0,
69
+ pendingEnrichmentCount: 0,
70
+ outreachRequest: null,
71
+ }).outreachRequest).toBeNull();
72
+ });
73
+ (0, bun_test_1.it)('the candidates query takes outreachEligible as a coerced boolean', () => {
74
+ const query = jobs_tab_contract_1.jobsTabContract.candidates.query;
75
+ (0, bun_test_1.expect)(query.parse({ outreachEligible: 'true' }).outreachEligible).toBe(true);
76
+ (0, bun_test_1.expect)(query.parse({}).outreachEligible).toBeUndefined();
77
+ });
78
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outreach-requests.contract.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outreach-requests.contract.spec.d.ts","sourceRoot":"","sources":["../../../contracts/outreach/__tests__/outreach-requests.contract.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const bun_test_1 = require("bun:test");
4
+ const outreach_requests_contract_1 = require("../outreach-requests.contract");
5
+ (0, bun_test_1.describe)('outreachRequestsContract', () => {
6
+ (0, bun_test_1.it)('enumerates exactly the four request states', () => {
7
+ (0, bun_test_1.expect)(outreach_requests_contract_1.OutreachRequestStatusSchema.options).toEqual([
8
+ 'PENDING',
9
+ 'RUNNING',
10
+ 'COMPLETED',
11
+ 'CANCELLED',
12
+ ]);
13
+ });
14
+ (0, bun_test_1.it)('parses a request row', () => {
15
+ const parsed = outreach_requests_contract_1.OutreachRequestSchema.parse({
16
+ id: '11111111-1111-4111-8111-111111111111',
17
+ jobId: '22222222-2222-4222-8222-222222222222',
18
+ status: 'PENDING',
19
+ eligibleAtRequest: 214,
20
+ requestedByName: 'Priya Shah',
21
+ contactedCount: 0,
22
+ createdAt: '2026-07-29T09:00:00.000Z',
23
+ startedAt: null,
24
+ completedAt: null,
25
+ });
26
+ (0, bun_test_1.expect)(parsed.status).toBe('PENDING');
27
+ });
28
+ (0, bun_test_1.it)('carries job facts on a queue item so the rack can label a campaign', () => {
29
+ const item = outreach_requests_contract_1.OutreachRequestQueueItemSchema.parse({
30
+ id: '11111111-1111-4111-8111-111111111111',
31
+ jobId: '22222222-2222-4222-8222-222222222222',
32
+ status: 'RUNNING',
33
+ eligibleAtRequest: 12,
34
+ requestedByName: null,
35
+ contactedCount: 3,
36
+ createdAt: '2026-07-29T09:00:00.000Z',
37
+ startedAt: '2026-07-29T09:05:00.000Z',
38
+ completedAt: null,
39
+ job: {
40
+ title: 'Need 1 x bricklayer',
41
+ trade: 'Bricklayer',
42
+ payText: '£20 per hour',
43
+ locationText: 'SW1A 1AA',
44
+ createdByName: 'Sam Okoro',
45
+ },
46
+ });
47
+ // `trade` is the label Relay Lab shows: `title` is j.description, the raw
48
+ // ad text. `locationText` is the job postcode, carried since 1.4.0.
49
+ (0, bun_test_1.expect)(item.job.trade).toBe('Bricklayer');
50
+ (0, bun_test_1.expect)(item.job.locationText).toBe('SW1A 1AA');
51
+ });
52
+ (0, bun_test_1.it)('routes both lanes under /v2', () => {
53
+ (0, bun_test_1.expect)(outreach_requests_contract_1.outreachRequestsContract.create.path).toBe('/v2/outreach/requests');
54
+ (0, bun_test_1.expect)(outreach_requests_contract_1.outreachRequestsContract.list.path).toBe('/v2/outreach/requests');
55
+ (0, bun_test_1.expect)(outreach_requests_contract_1.outreachRequestsContract.list.method).toBe('GET');
56
+ (0, bun_test_1.expect)(outreach_requests_contract_1.outreachRequestsContract.cancel.path).toBe('/v2/outreach/requests/:id/cancel');
57
+ (0, bun_test_1.expect)(outreach_requests_contract_1.outreachRequestsContract.start.path).toBe('/v2/outreach/requests/:id/start');
58
+ (0, bun_test_1.expect)(outreach_requests_contract_1.outreachRequestsContract.complete.path).toBe('/v2/outreach/requests/:id/complete');
59
+ });
60
+ (0, bun_test_1.it)('declares 200 on create, because a second click returns the open request', () => {
61
+ (0, bun_test_1.expect)(Object.keys(outreach_requests_contract_1.outreachRequestsContract.create.responses)).toContain('200');
62
+ (0, bun_test_1.expect)(Object.keys(outreach_requests_contract_1.outreachRequestsContract.create.responses)).not.toContain('409');
63
+ });
64
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outreach-routes.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outreach-routes.test.d.ts","sourceRoot":"","sources":["../../../contracts/outreach/__tests__/outreach-routes.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const index_1 = require("../../index");
8
+ const outreach_contract_1 = require("../outreach.contract");
9
+ // `pathPrefix: '/v2'` is applied by c.router, so the runtime paths are absolute.
10
+ node_assert_1.default.equal(outreach_contract_1.outreachContract.claimNext.method, 'POST');
11
+ node_assert_1.default.equal(outreach_contract_1.outreachContract.claimNext.path, '/v2/outreach/jobs/:jobId/claim-next');
12
+ node_assert_1.default.equal(outreach_contract_1.outreachContract.confirmSent.method, 'POST');
13
+ node_assert_1.default.equal(outreach_contract_1.outreachContract.confirmSent.path, '/v2/outreach/leases/:leaseId/sent');
14
+ node_assert_1.default.equal(outreach_contract_1.outreachContract.release.method, 'POST');
15
+ node_assert_1.default.equal(outreach_contract_1.outreachContract.release.path, '/v2/outreach/leases/:leaseId/release');
16
+ // Error taxonomy. Exhaustion is a 200, so claim-next declares no 404, and
17
+ // 410 is not used anywhere: a late confirm succeeds. `commonResponses` are
18
+ // merged into every route's `responses` by c.router, so 400, 401, 403 and 500
19
+ // appear here.
20
+ const declared = (route) => Object.keys(route.responses).map(Number).sort((a, b) => a - b);
21
+ node_assert_1.default.deepStrictEqual(declared(outreach_contract_1.outreachContract.claimNext), [200, 400, 401, 403, 409, 500]);
22
+ node_assert_1.default.deepStrictEqual(declared(outreach_contract_1.outreachContract.confirmSent), [200, 400, 401, 403, 404, 500]);
23
+ node_assert_1.default.deepStrictEqual(declared(outreach_contract_1.outreachContract.release), [200, 400, 401, 403, 404, 500]);
24
+ for (const route of [
25
+ outreach_contract_1.outreachContract.claimNext,
26
+ outreach_contract_1.outreachContract.confirmSent,
27
+ outreach_contract_1.outreachContract.release,
28
+ ]) {
29
+ node_assert_1.default.ok(!Object.prototype.hasOwnProperty.call(route.responses, '410'), '410 is not used: an expired lease that is confirmed late succeeds');
30
+ }
31
+ // Path params are validated as uuids.
32
+ node_assert_1.default.ok(outreach_contract_1.outreachContract.claimNext.pathParams.safeParse({
33
+ jobId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
34
+ }).success);
35
+ node_assert_1.default.ok(!outreach_contract_1.outreachContract.claimNext.pathParams.safeParse({ jobId: 'nope' }).success);
36
+ node_assert_1.default.ok(outreach_contract_1.outreachContract.confirmSent.pathParams.safeParse({
37
+ leaseId: '3f2504e0-4f89-41d3-9a0c-0305e82c3301',
38
+ }).success);
39
+ // Following the codebase convention, no route declares headers: the Bearer
40
+ // token rides the existing `authorization` header and is documented in the
41
+ // module header, not typed here. `c.router`'s zodMerge(baseHeaders, headers)
42
+ // falls back to `Object.assign({}, undefined, undefined)` when neither side
43
+ // is a strict zod object, so an undeclared `headers` comes out as `{}` at
44
+ // runtime, not `undefined` — verified against the pre-existing
45
+ // `healthContract.check` route, which also declares no headers.
46
+ const headersOf = (route) => route.headers;
47
+ for (const route of [
48
+ outreach_contract_1.outreachContract.claimNext,
49
+ outreach_contract_1.outreachContract.confirmSent,
50
+ outreach_contract_1.outreachContract.release,
51
+ ]) {
52
+ node_assert_1.default.deepStrictEqual(headersOf(route), {});
53
+ }
54
+ // Reachable from the aggregate router, which is what spec 2's controllers use.
55
+ node_assert_1.default.equal(index_1.apiContractRouter.Outreach.claimNext.method, 'POST');
56
+ node_assert_1.default.equal(index_1.apiContractRouter.Outreach.release.path, '/v2/outreach/leases/:leaseId/release');
57
+ console.log('outreach routes OK');
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outreach.schemas.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outreach.schemas.test.d.ts","sourceRoot":"","sources":["../../../contracts/outreach/__tests__/outreach.schemas.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const outreach_schemas_1 = require("../outreach.schemas");
8
+ // --- enums -----------------------------------------------------------------
9
+ node_assert_1.default.ok(outreach_schemas_1.OutreachSubjectKindSchema.safeParse('OWNED').success);
10
+ node_assert_1.default.ok(outreach_schemas_1.OutreachSubjectKindSchema.safeParse('CURATED').success);
11
+ node_assert_1.default.ok(!outreach_schemas_1.OutreachSubjectKindSchema.safeParse('WORKER').success);
12
+ // The mode is the mode the commute figure was MEASURED against, not the
13
+ // worker's saved transportation method, so the six-value method enum is
14
+ // deliberately not reused here.
15
+ node_assert_1.default.ok(outreach_schemas_1.OutreachTransportModeSchema.safeParse('DRIVE').success);
16
+ node_assert_1.default.ok(outreach_schemas_1.OutreachTransportModeSchema.safeParse('PUBLIC_TRANSPORT').success);
17
+ node_assert_1.default.ok(!outreach_schemas_1.OutreachTransportModeSchema.safeParse('OWN_VAN').success);
18
+ node_assert_1.default.ok(outreach_schemas_1.OutreachReleaseReasonSchema.safeParse('CONTACT_SAVE_FAILED').success);
19
+ node_assert_1.default.ok(outreach_schemas_1.OutreachReleaseReasonSchema.safeParse('CHAT_OPEN_FAILED').success);
20
+ node_assert_1.default.ok(outreach_schemas_1.OutreachReleaseReasonSchema.safeParse('COMPOSE_FAILED').success);
21
+ node_assert_1.default.ok(outreach_schemas_1.OutreachReleaseReasonSchema.safeParse('OTHER').success);
22
+ node_assert_1.default.ok(!outreach_schemas_1.OutreachReleaseReasonSchema.safeParse('SENT').success);
23
+ // canonicalKind is a separate axis from subjectKind: an OWNED subject can
24
+ // legitimately carry canonicalKind CURATED_WORKER (see the candidate tests
25
+ // below), so both values must parse regardless of lane.
26
+ node_assert_1.default.ok(outreach_schemas_1.OutreachCanonicalKindSchema.safeParse('WORKER').success);
27
+ node_assert_1.default.ok(outreach_schemas_1.OutreachCanonicalKindSchema.safeParse('CURATED_WORKER').success);
28
+ node_assert_1.default.ok(!outreach_schemas_1.OutreachCanonicalKindSchema.safeParse('OWNED').success);
29
+ // --- lease -----------------------------------------------------------------
30
+ const lease = outreach_schemas_1.OutreachLeaseSchema.safeParse({
31
+ leaseId: '3f2504e0-4f89-41d3-9a0c-0305e82c3301',
32
+ expiresAt: '2026-07-28T10:15:00.000Z',
33
+ });
34
+ node_assert_1.default.ok(lease.success);
35
+ node_assert_1.default.equal(lease.data.expiresAt, '2026-07-28T10:15:00.000Z');
36
+ // A missing required field is rejected.
37
+ node_assert_1.default.ok(!outreach_schemas_1.OutreachLeaseSchema.safeParse({
38
+ leaseId: '3f2504e0-4f89-41d3-9a0c-0305e82c3301',
39
+ }).success);
40
+ // --- candidate -------------------------------------------------------------
41
+ const candidate = outreach_schemas_1.OutreachCandidateSchema.safeParse({
42
+ subjectKind: 'CURATED',
43
+ subjectId: '9c858901-8a57-4791-81fe-4c455b099bc9',
44
+ canonicalKind: 'CURATED_WORKER',
45
+ canonicalId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
46
+ name: 'Adam Kowalski',
47
+ phoneNumber: '+447700900123',
48
+ commuteMinutes: 45,
49
+ transportMode: 'PUBLIC_TRANSPORT',
50
+ });
51
+ node_assert_1.default.ok(candidate.success);
52
+ node_assert_1.default.equal(candidate.data.commuteMinutes, 45);
53
+ // commuteMinutes is a plain number, not an integer: the source proximity
54
+ // columns (drive_minutes / transit_minutes) are `real`, so a fractional
55
+ // figure must parse — an .int() constraint here would make a well-behaved
56
+ // server response fail client-side validation on a successful claim.
57
+ const fractionalCandidate = outreach_schemas_1.OutreachCandidateSchema.safeParse({
58
+ subjectKind: 'CURATED',
59
+ subjectId: '9c858901-8a57-4791-81fe-4c455b099bc9',
60
+ canonicalKind: 'CURATED_WORKER',
61
+ canonicalId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
62
+ name: 'Adam Kowalski',
63
+ phoneNumber: '+447700900123',
64
+ commuteMinutes: 44.3,
65
+ transportMode: 'DRIVE',
66
+ });
67
+ node_assert_1.default.ok(fractionalCandidate.success);
68
+ node_assert_1.default.equal(fractionalCandidate.data.commuteMinutes, 44.3);
69
+ // commuteMinutes is NOT nullable: eligibility is strict on nulls, so a
70
+ // claimed candidate always has a known figure for its resolved mode.
71
+ node_assert_1.default.ok(!outreach_schemas_1.OutreachCandidateSchema.safeParse({
72
+ subjectKind: 'CURATED',
73
+ subjectId: '9c858901-8a57-4791-81fe-4c455b099bc9',
74
+ canonicalKind: 'CURATED_WORKER',
75
+ canonicalId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
76
+ name: 'Adam Kowalski',
77
+ phoneNumber: '+447700900123',
78
+ commuteMinutes: null,
79
+ transportMode: 'PUBLIC_TRANSPORT',
80
+ }).success);
81
+ // transportMode is resolved server-side AFTER the fallback, so it is never null.
82
+ node_assert_1.default.ok(!outreach_schemas_1.OutreachCandidateSchema.safeParse({
83
+ subjectKind: 'OWNED',
84
+ subjectId: '9c858901-8a57-4791-81fe-4c455b099bc9',
85
+ canonicalKind: 'WORKER',
86
+ canonicalId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
87
+ name: 'Adam Kowalski',
88
+ phoneNumber: '+447700900123',
89
+ commuteMinutes: 20,
90
+ transportMode: null,
91
+ }).success);
92
+ // canonicalKind is required: a candidate carrying only canonicalId cannot be
93
+ // correlated against the ledger, which keys canonical identity on the pair.
94
+ node_assert_1.default.ok(!outreach_schemas_1.OutreachCandidateSchema.safeParse({
95
+ subjectKind: 'OWNED',
96
+ subjectId: '9c858901-8a57-4791-81fe-4c455b099bc9',
97
+ canonicalId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
98
+ name: 'Adam Kowalski',
99
+ phoneNumber: '+447700900123',
100
+ commuteMinutes: 20,
101
+ transportMode: 'DRIVE',
102
+ }).success);
103
+ // canonicalKind is NOT derivable from subjectKind: an OWNED subject backed by
104
+ // a linked curated_workers row resolves to canonicalKind CURATED_WORKER, per
105
+ // apps/api's candidate-eligibility.util.ts. This is the case the field
106
+ // exists for, so it must parse cleanly.
107
+ const ownedWithCuratedCanonical = outreach_schemas_1.OutreachCandidateSchema.safeParse({
108
+ subjectKind: 'OWNED',
109
+ subjectId: '9c858901-8a57-4791-81fe-4c455b099bc9',
110
+ canonicalKind: 'CURATED_WORKER',
111
+ canonicalId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
112
+ name: 'Adam Kowalski',
113
+ phoneNumber: '+447700900123',
114
+ commuteMinutes: 20,
115
+ transportMode: 'DRIVE',
116
+ });
117
+ node_assert_1.default.ok(ownedWithCuratedCanonical.success);
118
+ // --- job -------------------------------------------------------------------
119
+ const job = outreach_schemas_1.OutreachJobSchema.safeParse({
120
+ title: 'Carpenter needed',
121
+ trade: 'CARPENTER',
122
+ payText: '£180/day',
123
+ locationText: 'Croydon, CR0',
124
+ createdByName: 'Sam Okoro',
125
+ });
126
+ node_assert_1.default.ok(job.success);
127
+ // Real jobs routinely lack pay, trade text, or a raising agent; those fields
128
+ // are nullable.
129
+ const sparseJob = outreach_schemas_1.OutreachJobSchema.safeParse({
130
+ title: 'Carpenter needed',
131
+ trade: null,
132
+ payText: null,
133
+ locationText: null,
134
+ createdByName: null,
135
+ });
136
+ node_assert_1.default.ok(sparseJob.success);
137
+ // title is not.
138
+ node_assert_1.default.ok(!outreach_schemas_1.OutreachJobSchema.safeParse({
139
+ trade: null,
140
+ payText: null,
141
+ locationText: null,
142
+ createdByName: null,
143
+ }).success);
144
+ console.log('outreach.schemas OK');