@dakkitor/api-contracts 1.1.154 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/dist/abilities/abilities.contract.d.ts +53 -1
  2. package/dist/abilities/abilities.contract.d.ts.map +1 -1
  3. package/dist/abilities/abilities.contract.js +92 -1
  4. package/dist/abilities/abilities.contract.spec.d.ts +2 -0
  5. package/dist/abilities/abilities.contract.spec.d.ts.map +1 -0
  6. package/dist/abilities/abilities.contract.spec.js +145 -0
  7. package/dist/abilities/admin-dashboard.abilities.test.d.ts +2 -0
  8. package/dist/abilities/admin-dashboard.abilities.test.d.ts.map +1 -0
  9. package/dist/abilities/admin-dashboard.abilities.test.js +33 -0
  10. package/dist/abilities/admin.abilities.json +19 -0
  11. package/dist/abilities/bot.abilities.json +13 -4
  12. package/dist/abilities/first-agent.abilities.json +317 -70
  13. package/dist/abilities/interconnection.abilities.json +75 -0
  14. package/dist/abilities/kpi.abilities.json +68 -0
  15. package/dist/abilities/office-manager.abilities.json +111 -0
  16. package/dist/abilities/second-agent.abilities.json +417 -43
  17. package/dist/abilities/team-leads.json +71 -6
  18. package/dist/abilities/worker-curator.abilities.json +233 -0
  19. package/dist/actives/actives.contract.d.ts +19379 -23651
  20. package/dist/actives/actives.contract.d.ts.map +1 -1
  21. package/dist/actives/actives.contract.js +517 -114
  22. package/dist/agent-client-links/agent-client-links.contract.d.ts +1431 -291
  23. package/dist/agent-client-links/agent-client-links.contract.d.ts.map +1 -1
  24. package/dist/auth/auth.contract.d.ts +1050 -81
  25. package/dist/auth/auth.contract.d.ts.map +1 -1
  26. package/dist/auth/auth.contract.js +115 -3
  27. package/dist/bookings/booking-worker-summary.spec.d.ts +2 -0
  28. package/dist/bookings/booking-worker-summary.spec.d.ts.map +1 -0
  29. package/dist/bookings/booking-worker-summary.spec.js +25 -0
  30. package/dist/bookings/bookings.contract.d.ts +20643 -26117
  31. package/dist/bookings/bookings.contract.d.ts.map +1 -1
  32. package/dist/bookings/bookings.contract.js +383 -91
  33. package/dist/bookings/bookings.contract.spec.d.ts +2 -0
  34. package/dist/bookings/bookings.contract.spec.d.ts.map +1 -0
  35. package/dist/bookings/bookings.contract.spec.js +11 -0
  36. package/dist/bookings/job-lock.spec.d.ts +2 -0
  37. package/dist/bookings/job-lock.spec.d.ts.map +1 -0
  38. package/dist/bookings/job-lock.spec.js +56 -0
  39. package/dist/bot-parse-cache/bot-parse-cache.contract.d.ts +232 -0
  40. package/dist/bot-parse-cache/bot-parse-cache.contract.d.ts.map +1 -0
  41. package/dist/bot-parse-cache/bot-parse-cache.contract.js +64 -0
  42. package/dist/call-history/call-history.contract.d.ts +1336 -767
  43. package/dist/call-history/call-history.contract.d.ts.map +1 -1
  44. package/dist/call-history/call-history.contract.js +86 -10
  45. package/dist/calls-feed/calls-feed.contract.d.ts +417 -0
  46. package/dist/calls-feed/calls-feed.contract.d.ts.map +1 -0
  47. package/dist/calls-feed/calls-feed.contract.js +32 -0
  48. package/dist/client-contacts/client-contacts.contract.d.ts +410 -226
  49. package/dist/client-contacts/client-contacts.contract.d.ts.map +1 -1
  50. package/dist/client-contacts/client-contacts.contract.js +35 -4
  51. package/dist/clients/clients.contract.d.ts +227 -73
  52. package/dist/clients/clients.contract.d.ts.map +1 -1
  53. package/dist/clients/clients.contract.js +45 -21
  54. package/dist/collaboration-checkings/collaboration-checkings.contract.d.ts +2908 -1834
  55. package/dist/collaboration-checkings/collaboration-checkings.contract.d.ts.map +1 -1
  56. package/dist/collaboration-checkings/collaboration-checkings.contract.js +14 -9
  57. package/dist/collaborations/collaborations.contract.d.ts +2676 -1409
  58. package/dist/collaborations/collaborations.contract.d.ts.map +1 -1
  59. package/dist/collaborations/collaborations.contract.js +33 -9
  60. package/dist/common/call-rating.schema.d.ts.map +1 -1
  61. package/dist/common/call-rating.schema.js +4 -2
  62. package/dist/common/common-schemas.d.ts +59 -11
  63. package/dist/common/common-schemas.d.ts.map +1 -1
  64. package/dist/common/common-schemas.js +55 -29
  65. package/dist/common/error-schemas.d.ts +2 -2
  66. package/dist/common/pagination-query.schema.d.ts +13 -2
  67. package/dist/common/pagination-query.schema.d.ts.map +1 -1
  68. package/dist/common/pagination-query.schema.js +21 -2
  69. package/dist/common/pagination-query.schema.spec.d.ts +2 -0
  70. package/dist/common/pagination-query.schema.spec.d.ts.map +1 -0
  71. package/dist/common/pagination-query.schema.spec.js +53 -0
  72. package/dist/companies/companies.contract.d.ts +53 -28
  73. package/dist/companies/companies.contract.d.ts.map +1 -1
  74. package/dist/companies/companies.contract.js +11 -10
  75. package/dist/crews/crews.contract.d.ts +1010 -196
  76. package/dist/crews/crews.contract.d.ts.map +1 -1
  77. package/dist/crews/crews.contract.js +98 -17
  78. package/dist/crews/crews.contract.spec.d.ts +2 -0
  79. package/dist/crews/crews.contract.spec.d.ts.map +1 -0
  80. package/dist/crews/crews.contract.spec.js +67 -0
  81. package/dist/cron-executions/cron-executions.contract.d.ts +988 -59
  82. package/dist/cron-executions/cron-executions.contract.d.ts.map +1 -1
  83. package/dist/cron-executions/cron-executions.contract.js +127 -7
  84. package/dist/curated-worker-leads/__tests__/disposition-reason.spec.d.ts +2 -0
  85. package/dist/curated-worker-leads/__tests__/disposition-reason.spec.d.ts.map +1 -0
  86. package/dist/curated-worker-leads/__tests__/disposition-reason.spec.js +40 -0
  87. package/dist/curated-worker-leads/candidate-coordination-snapshot.spec.d.ts +2 -0
  88. package/dist/curated-worker-leads/candidate-coordination-snapshot.spec.d.ts.map +1 -0
  89. package/dist/curated-worker-leads/candidate-coordination-snapshot.spec.js +16 -0
  90. package/dist/curated-worker-leads/candidate-coordination.contract.d.ts +21650 -0
  91. package/dist/curated-worker-leads/candidate-coordination.contract.d.ts.map +1 -0
  92. package/dist/curated-worker-leads/candidate-coordination.contract.js +921 -0
  93. package/dist/curated-worker-leads/candidate-coordination.contract.spec.d.ts +2 -0
  94. package/dist/curated-worker-leads/candidate-coordination.contract.spec.d.ts.map +1 -0
  95. package/dist/curated-worker-leads/candidate-coordination.contract.spec.js +51 -0
  96. package/dist/curated-worker-leads/candidate-edit-session.contract.d.ts +2364 -0
  97. package/dist/curated-worker-leads/candidate-edit-session.contract.d.ts.map +1 -0
  98. package/dist/curated-worker-leads/candidate-edit-session.contract.js +173 -0
  99. package/dist/curated-worker-leads/consent-queue.contract.d.ts +4497 -0
  100. package/dist/curated-worker-leads/consent-queue.contract.d.ts.map +1 -0
  101. package/dist/curated-worker-leads/consent-queue.contract.js +201 -0
  102. package/dist/curated-worker-leads/contact-history.spec.d.ts +2 -0
  103. package/dist/curated-worker-leads/contact-history.spec.d.ts.map +1 -0
  104. package/dist/curated-worker-leads/contact-history.spec.js +88 -0
  105. package/dist/curated-worker-leads/contact-session.contract.spec.d.ts +2 -0
  106. package/dist/curated-worker-leads/contact-session.contract.spec.d.ts.map +1 -0
  107. package/dist/curated-worker-leads/contact-session.contract.spec.js +315 -0
  108. package/dist/curated-worker-leads/curated-worker-lead-config.contract.d.ts +489 -0
  109. package/dist/curated-worker-leads/curated-worker-lead-config.contract.d.ts.map +1 -0
  110. package/dist/curated-worker-leads/curated-worker-lead-config.contract.js +88 -0
  111. package/dist/curated-worker-leads/curated-worker-leads.contract.d.ts +135 -0
  112. package/dist/curated-worker-leads/curated-worker-leads.contract.d.ts.map +1 -0
  113. package/dist/curated-worker-leads/curated-worker-leads.contract.js +32 -0
  114. package/dist/curated-worker-leads/job-candidate-cards.spec.d.ts +2 -0
  115. package/dist/curated-worker-leads/job-candidate-cards.spec.d.ts.map +1 -0
  116. package/dist/curated-worker-leads/job-candidate-cards.spec.js +157 -0
  117. package/dist/curated-worker-leads/job-candidates.spec.d.ts +2 -0
  118. package/dist/curated-worker-leads/job-candidates.spec.d.ts.map +1 -0
  119. package/dist/curated-worker-leads/job-candidates.spec.js +140 -0
  120. package/dist/curated-worker-leads/job-feed-match-counts.contract.spec.d.ts +2 -0
  121. package/dist/curated-worker-leads/job-feed-match-counts.contract.spec.d.ts.map +1 -0
  122. package/dist/curated-worker-leads/job-feed-match-counts.contract.spec.js +19 -0
  123. package/dist/curated-worker-leads/jobs-tab.contract.d.ts +18365 -0
  124. package/dist/curated-worker-leads/jobs-tab.contract.d.ts.map +1 -0
  125. package/dist/curated-worker-leads/jobs-tab.contract.js +642 -0
  126. package/dist/curated-worker-leads/lead-agent-area.contract.d.ts +348 -0
  127. package/dist/curated-worker-leads/lead-agent-area.contract.d.ts.map +1 -0
  128. package/dist/curated-worker-leads/lead-agent-area.contract.js +51 -0
  129. package/dist/curated-worker-leads/owned-jobs-tab.contract.d.ts +1116 -0
  130. package/dist/curated-worker-leads/owned-jobs-tab.contract.d.ts.map +1 -0
  131. package/dist/curated-worker-leads/owned-jobs-tab.contract.js +93 -0
  132. package/dist/curated-workers/curated-filter-additions.spec.d.ts +2 -0
  133. package/dist/curated-workers/curated-filter-additions.spec.d.ts.map +1 -0
  134. package/dist/curated-workers/curated-filter-additions.spec.js +17 -0
  135. package/dist/curated-workers/curated-job-seeking.spec.d.ts +2 -0
  136. package/dist/curated-workers/curated-job-seeking.spec.d.ts.map +1 -0
  137. package/dist/curated-workers/curated-job-seeking.spec.js +53 -0
  138. package/dist/curated-workers/curated-workers-id-documents.spec.d.ts +2 -0
  139. package/dist/curated-workers/curated-workers-id-documents.spec.d.ts.map +1 -0
  140. package/dist/curated-workers/curated-workers-id-documents.spec.js +38 -0
  141. package/dist/curated-workers/curated-workers.contract.d.ts +6160 -1906
  142. package/dist/curated-workers/curated-workers.contract.d.ts.map +1 -1
  143. package/dist/curated-workers/curated-workers.contract.js +333 -51
  144. package/dist/dashboards/agent-daily-metrics.contract.d.ts +10 -10
  145. package/dist/dashboards/agent-daily-metrics.contract.js +1 -1
  146. package/dist/dashboards/dashboard-widgets.contract.d.ts +3800 -496
  147. package/dist/dashboards/dashboard-widgets.contract.d.ts.map +1 -1
  148. package/dist/dashboards/dashboard-widgets.contract.js +527 -29
  149. package/dist/dashboards/dashboard.contract.d.ts +8 -8
  150. package/dist/document-intake/document-intake.contract.d.ts +3132 -0
  151. package/dist/document-intake/document-intake.contract.d.ts.map +1 -0
  152. package/dist/document-intake/document-intake.contract.js +418 -0
  153. package/dist/export-jobs/export-jobs.contract.d.ts +3918 -0
  154. package/dist/export-jobs/export-jobs.contract.d.ts.map +1 -0
  155. package/dist/export-jobs/export-jobs.contract.js +240 -0
  156. package/dist/exports-events/exports-events.schemas.d.ts +90 -0
  157. package/dist/exports-events/exports-events.schemas.d.ts.map +1 -0
  158. package/dist/exports-events/exports-events.schemas.js +56 -0
  159. package/dist/files/files.contract.d.ts +133 -126
  160. package/dist/files/files.contract.d.ts.map +1 -1
  161. package/dist/files/files.contract.js +8 -0
  162. package/dist/health/health.contract.d.ts +4 -4
  163. package/dist/index.d.ts +82 -0
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js +87 -1
  166. package/dist/interactions/interactions.contract.d.ts +162 -0
  167. package/dist/interactions/interactions.contract.d.ts.map +1 -0
  168. package/dist/interactions/interactions.contract.js +42 -0
  169. package/dist/job-clusters/job-clusters.contract.d.ts +1584 -0
  170. package/dist/job-clusters/job-clusters.contract.d.ts.map +1 -0
  171. package/dist/job-clusters/job-clusters.contract.js +133 -0
  172. package/dist/jobs/jobs.contract.d.ts +16517 -8495
  173. package/dist/jobs/jobs.contract.d.ts.map +1 -1
  174. package/dist/jobs/jobs.contract.js +394 -190
  175. package/dist/jobs/jobs.contract.spec.d.ts +2 -0
  176. package/dist/jobs/jobs.contract.spec.d.ts.map +1 -0
  177. package/dist/jobs/jobs.contract.spec.js +70 -0
  178. package/dist/kpi-impersonation/kpi-impersonation.contract.d.ts +75 -75
  179. package/dist/lead-assignments/lead-assignments.contract.d.ts +2933 -1122
  180. package/dist/lead-assignments/lead-assignments.contract.d.ts.map +1 -1
  181. package/dist/lead-assignments/lead-assignments.contract.js +29 -7
  182. package/dist/lead-distribution/agent-lead-distribution.contract.d.ts +328 -64
  183. package/dist/lead-distribution/agent-lead-distribution.contract.d.ts.map +1 -1
  184. package/dist/lead-distribution/agent-lead-distribution.contract.js +1 -1
  185. package/dist/lead-distribution/lead-distribution-config.contract.d.ts +31 -31
  186. package/dist/leads/leads.contract.d.ts +830 -368
  187. package/dist/leads/leads.contract.d.ts.map +1 -1
  188. package/dist/leads/leads.contract.js +106 -26
  189. package/dist/locations/locations.contract.d.ts +36 -36
  190. package/dist/notifications/notifications.contract.d.ts +1039 -0
  191. package/dist/notifications/notifications.contract.d.ts.map +1 -0
  192. package/dist/notifications/notifications.contract.js +110 -0
  193. package/dist/offices/offices.contract.d.ts +210 -60
  194. package/dist/offices/offices.contract.d.ts.map +1 -1
  195. package/dist/offices/offices.contract.js +18 -4
  196. package/dist/outreach/__tests__/outreach-claim.test.d.ts +2 -0
  197. package/dist/outreach/__tests__/outreach-claim.test.d.ts.map +1 -0
  198. package/dist/outreach/__tests__/outreach-claim.test.js +97 -0
  199. package/dist/outreach/__tests__/outreach-confirm-release.test.d.ts +2 -0
  200. package/dist/outreach/__tests__/outreach-confirm-release.test.d.ts.map +1 -0
  201. package/dist/outreach/__tests__/outreach-confirm-release.test.js +98 -0
  202. package/dist/outreach/__tests__/outreach-routes.test.d.ts +2 -0
  203. package/dist/outreach/__tests__/outreach-routes.test.d.ts.map +1 -0
  204. package/dist/outreach/__tests__/outreach-routes.test.js +57 -0
  205. package/dist/outreach/__tests__/outreach.schemas.test.d.ts +2 -0
  206. package/dist/outreach/__tests__/outreach.schemas.test.d.ts.map +1 -0
  207. package/dist/outreach/__tests__/outreach.schemas.test.js +140 -0
  208. package/dist/outreach/outreach.contract.d.ts +809 -0
  209. package/dist/outreach/outreach.contract.d.ts.map +1 -0
  210. package/dist/outreach/outreach.contract.js +195 -0
  211. package/dist/outreach/outreach.schemas.d.ts +113 -0
  212. package/dist/outreach/outreach.schemas.d.ts.map +1 -0
  213. package/dist/outreach/outreach.schemas.js +132 -0
  214. package/dist/own-research/own-research.contract.d.ts +1356 -552
  215. package/dist/own-research/own-research.contract.d.ts.map +1 -1
  216. package/dist/own-research/own-research.contract.js +14 -3
  217. package/dist/postcodes/postcodes.contract.d.ts +16 -16
  218. package/dist/proofs/proof-category.enum.d.ts +4 -0
  219. package/dist/proofs/proof-category.enum.d.ts.map +1 -0
  220. package/dist/proofs/proof-category.enum.js +5 -0
  221. package/dist/proofs/proof-entity-type.enum.d.ts +4 -0
  222. package/dist/proofs/proof-entity-type.enum.d.ts.map +1 -0
  223. package/dist/proofs/proof-entity-type.enum.js +5 -0
  224. package/dist/proofs/proof-type.enum.d.ts +28 -0
  225. package/dist/proofs/proof-type.enum.d.ts.map +1 -0
  226. package/dist/proofs/proof-type.enum.js +14 -0
  227. package/dist/proofs/proofs.contract.d.ts +3009 -0
  228. package/dist/proofs/proofs.contract.d.ts.map +1 -0
  229. package/dist/proofs/proofs.contract.js +92 -0
  230. package/dist/proofs/proofs.dtos.d.ts +1319 -0
  231. package/dist/proofs/proofs.dtos.d.ts.map +1 -0
  232. package/dist/proofs/proofs.dtos.js +178 -0
  233. package/dist/qualifications/qualifications.contract.d.ts +94 -94
  234. package/dist/realtime/data-changed.d.ts +21 -0
  235. package/dist/realtime/data-changed.d.ts.map +1 -0
  236. package/dist/realtime/data-changed.js +37 -0
  237. package/dist/shared/booking-history.schema.d.ts +27 -0
  238. package/dist/shared/booking-history.schema.d.ts.map +1 -0
  239. package/dist/shared/booking-history.schema.js +22 -0
  240. package/dist/shared/booking-history.spec.d.ts +2 -0
  241. package/dist/shared/booking-history.spec.d.ts.map +1 -0
  242. package/dist/shared/booking-history.spec.js +44 -0
  243. package/dist/shared/contact-suppressions.contract.d.ts +22 -0
  244. package/dist/shared/contact-suppressions.contract.d.ts.map +1 -0
  245. package/dist/shared/contact-suppressions.contract.js +13 -0
  246. package/dist/shared/live-booking.schema.d.ts +57 -0
  247. package/dist/shared/live-booking.schema.d.ts.map +1 -0
  248. package/dist/shared/live-booking.schema.js +34 -0
  249. package/dist/shared/summary-schemas.d.ts +218 -0
  250. package/dist/shared/summary-schemas.d.ts.map +1 -0
  251. package/dist/shared/summary-schemas.js +56 -0
  252. package/dist/sheets-sync/__tests__/sheets-sync-events.schemas.test.d.ts +2 -0
  253. package/dist/sheets-sync/__tests__/sheets-sync-events.schemas.test.d.ts.map +1 -0
  254. package/dist/sheets-sync/__tests__/sheets-sync-events.schemas.test.js +20 -0
  255. package/dist/sheets-sync/__tests__/tab-sync-config.schema.test.d.ts +2 -0
  256. package/dist/sheets-sync/__tests__/tab-sync-config.schema.test.d.ts.map +1 -0
  257. package/dist/sheets-sync/__tests__/tab-sync-config.schema.test.js +41 -0
  258. package/dist/sheets-sync/sheets-sync-events.schemas.d.ts +43 -0
  259. package/dist/sheets-sync/sheets-sync-events.schemas.d.ts.map +1 -0
  260. package/dist/sheets-sync/sheets-sync-events.schemas.js +29 -0
  261. package/dist/sheets-sync/sheets-sync.contract.d.ts +7258 -0
  262. package/dist/sheets-sync/sheets-sync.contract.d.ts.map +1 -0
  263. package/dist/sheets-sync/sheets-sync.contract.js +323 -0
  264. package/dist/telegram/telegram.contract.d.ts +727 -0
  265. package/dist/telegram/telegram.contract.d.ts.map +1 -0
  266. package/dist/telegram/telegram.contract.js +75 -0
  267. package/dist/trades/trade-rate-assessment.d.ts +18 -0
  268. package/dist/trades/trade-rate-assessment.d.ts.map +1 -0
  269. package/dist/trades/trade-rate-assessment.js +46 -0
  270. package/dist/trades/trade-rate-assessment.spec.d.ts +2 -0
  271. package/dist/trades/trade-rate-assessment.spec.d.ts.map +1 -0
  272. package/dist/trades/trade-rate-assessment.spec.js +223 -0
  273. package/dist/trades/trades.contract.d.ts +111 -0
  274. package/dist/trades/trades.contract.d.ts.map +1 -1
  275. package/dist/trades/trades.contract.js +49 -1
  276. package/dist/trades/trades.contract.spec.d.ts +2 -0
  277. package/dist/trades/trades.contract.spec.d.ts.map +1 -0
  278. package/dist/trades/trades.contract.spec.js +173 -0
  279. package/dist/user-access-grants/build-user-access-grant-rules.d.ts +10 -0
  280. package/dist/user-access-grants/build-user-access-grant-rules.d.ts.map +1 -0
  281. package/dist/user-access-grants/build-user-access-grant-rules.js +69 -0
  282. package/dist/user-access-grants/build-user-access-grant-rules.spec.d.ts +2 -0
  283. package/dist/user-access-grants/build-user-access-grant-rules.spec.d.ts.map +1 -0
  284. package/dist/user-access-grants/build-user-access-grant-rules.spec.js +77 -0
  285. package/dist/user-access-grants/user-access-grant-templates.json +454 -0
  286. package/dist/user-access-grants/user-access-grants.contract.d.ts +3886 -0
  287. package/dist/user-access-grants/user-access-grants.contract.d.ts.map +1 -0
  288. package/dist/user-access-grants/user-access-grants.contract.js +189 -0
  289. package/dist/user-access-grants/user-access-grants.contract.spec.d.ts +2 -0
  290. package/dist/user-access-grants/user-access-grants.contract.spec.d.ts.map +1 -0
  291. package/dist/user-access-grants/user-access-grants.contract.spec.js +149 -0
  292. package/dist/users/users.contract.d.ts +1959 -349
  293. package/dist/users/users.contract.d.ts.map +1 -1
  294. package/dist/users/users.contract.js +222 -37
  295. package/dist/users/users.contract.spec.d.ts +2 -0
  296. package/dist/users/users.contract.spec.d.ts.map +1 -0
  297. package/dist/users/users.contract.spec.js +103 -0
  298. package/dist/worker-identity-cases/worker-identity-cases.contract.d.ts +4609 -0
  299. package/dist/worker-identity-cases/worker-identity-cases.contract.d.ts.map +1 -0
  300. package/dist/worker-identity-cases/worker-identity-cases.contract.js +409 -0
  301. package/dist/worker-merge-proposals/worker-merge-proposals.contract.d.ts +1511 -0
  302. package/dist/worker-merge-proposals/worker-merge-proposals.contract.d.ts.map +1 -0
  303. package/dist/worker-merge-proposals/worker-merge-proposals.contract.js +150 -0
  304. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.d.ts +1106 -0
  305. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.d.ts.map +1 -0
  306. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.js +85 -0
  307. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.spec.d.ts +2 -0
  308. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.spec.d.ts.map +1 -0
  309. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.contract.spec.js +216 -0
  310. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.schemas.d.ts +453 -0
  311. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.schemas.d.ts.map +1 -0
  312. package/dist/worker-source-identity-conflicts/worker-source-identity-conflicts.schemas.js +109 -0
  313. package/dist/workers/do-not-contact.contract.d.ts +46 -0
  314. package/dist/workers/do-not-contact.contract.d.ts.map +1 -0
  315. package/dist/workers/do-not-contact.contract.js +41 -0
  316. package/dist/workers/do-not-contact.contract.spec.d.ts +2 -0
  317. package/dist/workers/do-not-contact.contract.spec.d.ts.map +1 -0
  318. package/dist/workers/do-not-contact.contract.spec.js +47 -0
  319. package/dist/workers/duplicate-group-worker.spec.d.ts +2 -0
  320. package/dist/workers/duplicate-group-worker.spec.d.ts.map +1 -0
  321. package/dist/workers/duplicate-group-worker.spec.js +34 -0
  322. package/dist/workers/filter-exact-flags.spec.d.ts +2 -0
  323. package/dist/workers/filter-exact-flags.spec.d.ts.map +1 -0
  324. package/dist/workers/filter-exact-flags.spec.js +37 -0
  325. package/dist/workers/worker-source-attribution.contract.spec.d.ts +2 -0
  326. package/dist/workers/worker-source-attribution.contract.spec.d.ts.map +1 -0
  327. package/dist/workers/worker-source-attribution.contract.spec.js +442 -0
  328. package/dist/workers/worker-source.spec.d.ts +2 -0
  329. package/dist/workers/worker-source.spec.d.ts.map +1 -0
  330. package/dist/workers/worker-source.spec.js +13 -0
  331. package/dist/workers/worker-status-facets.spec.d.ts +2 -0
  332. package/dist/workers/worker-status-facets.spec.d.ts.map +1 -0
  333. package/dist/workers/worker-status-facets.spec.js +34 -0
  334. package/dist/workers/workers.contract.d.ts +19534 -5969
  335. package/dist/workers/workers.contract.d.ts.map +1 -1
  336. package/dist/workers/workers.contract.js +1096 -113
  337. package/dist/workers/workers.contract.spec.d.ts +2 -0
  338. package/dist/workers/workers.contract.spec.d.ts.map +1 -0
  339. package/dist/workers/workers.contract.spec.js +31 -0
  340. package/package.json +5 -4
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.jobsContractRouter = exports.SearchJobResponseSchema = exports.SearchJobResultSchema = exports.SearchJobQuerySchema = exports.FilterMapMarkersSchema = exports.PaginatedJobResponseSchema = exports.FilterJobSchema = exports.BatchDeleteJobResponseSchema = exports.BatchDeleteJobSchema = exports.BatchUpdateJobResponseSchema = exports.BatchUpdateJobSchema = exports.UpdateJobSchema = exports.CreateDraftJobSchema = exports.CreateJobSchema = exports.JobMapMarkersResponseSchema = exports.JobMapMarkerSchema = exports.JobSchema = exports.CreateJobQualificationSchema = exports.JobQualificationSchema = exports.CreatePaySchema = exports.PaySchema = exports.JobSortableFieldsSchema = exports.JobStatusSchema = void 0;
3
+ exports.jobsContractRouter = exports.DuplicateJobConflictSchema = exports.SearchJobResponseSchema = exports.SearchJobResultSchema = exports.SearchJobQuerySchema = exports.FilterMapMarkersSchema = exports.PaginatedJobResponseSchema = exports.JobFeedResponseSchema = exports.JobFeedQuerySchema = exports.JOB_FEED_PAGE_SIZE = exports.FilterJobSchema = exports.BatchDeleteJobResponseSchema = exports.BatchDeleteJobSchema = exports.BatchUpdateJobResponseSchema = exports.BatchUpdateJobSchema = exports.UpdateJobSchema = exports.CreateJobSchema = exports.DemandBreakdownDetailResponseSchema = exports.DemandBreakdownDetailQuerySchema = exports.DemandUnitSchema = exports.DemandEpisodeSchema = exports.DemandBreakdownResponseSchema = exports.DemandBreakdownRowSchema = exports.DemandBreakdownFilterSchema = exports.DemandWindowSchema = exports.JobMapMarkersResponseSchema = exports.JobMapMarkerSchema = exports.PaginatedJobListResponseSchema = exports.FeedJobItemSchema = exports.JobListItemSchema = exports.JobSchema = exports.CreateJobQualificationSchema = exports.JobQualificationSchema = exports.CreatePaySchema = exports.PaySchema = exports.JobSortFieldMapping = exports.JobSortableFieldsSchema = exports.JobStartDateSchema = exports.CreationSourceSchema = exports.JobEventSchema = exports.JobCloseSourceSchema = exports.JobCloseReasonSchema = exports.JobEventTypeSchema = exports.JobStatusSchema = void 0;
4
4
  const zod_openapi_1 = require("@anatine/zod-openapi");
5
5
  const core_1 = require("@ts-rest/core");
6
6
  const zod_1 = require("zod");
@@ -9,13 +9,54 @@ const common_schemas_1 = require("../common/common-schemas");
9
9
  const error_schemas_1 = require("../common/error-schemas");
10
10
  const pagination_query_schema_1 = require("../common/pagination-query.schema");
11
11
  const pagination_schema_1 = require("../common/pagination.schema");
12
- const curated_workers_contract_1 = require("../curated-workers/curated-workers.contract");
12
+ const summary_schemas_1 = require("../shared/summary-schemas");
13
13
  const users_contract_1 = require("../users/users.contract");
14
14
  (0, zod_openapi_1.extendZodWithOpenApi)(zod_1.z);
15
15
  /**
16
16
  * Job Status Enum
17
17
  */
18
- exports.JobStatusSchema = zod_1.z.enum(['AVAILABLE', 'NOT_AVAILABLE', 'DRAFT']);
18
+ exports.JobStatusSchema = zod_1.z.enum(['AVAILABLE', 'NOT_AVAILABLE']);
19
+ /**
20
+ * Job lifecycle event log (job_events table) — read-only history.
21
+ * Mirrors apps/api JobEvent entity + its enums.
22
+ */
23
+ exports.JobEventTypeSchema = zod_1.z.enum([
24
+ 'CREATED',
25
+ 'STATUS_CHANGED',
26
+ 'POSITIONS_CHANGED',
27
+ ]);
28
+ exports.JobCloseReasonSchema = zod_1.z.enum([
29
+ 'FILLED',
30
+ 'PARTIALLY_FILLED',
31
+ 'UNFILLED',
32
+ ]);
33
+ exports.JobCloseSourceSchema = zod_1.z.enum([
34
+ 'BOOKINGS',
35
+ 'DECLARED',
36
+ 'EXPIRED',
37
+ 'START_DATE',
38
+ ]);
39
+ exports.JobEventSchema = zod_1.z.object({
40
+ id: zod_1.z.string().uuid(),
41
+ eventType: exports.JobEventTypeSchema,
42
+ fromStatus: exports.JobStatusSchema.nullable(),
43
+ toStatus: exports.JobStatusSchema.nullable(),
44
+ numberOfPositions: zod_1.z.number().int(),
45
+ previousNumberOfPositions: zod_1.z.number().int().nullable(),
46
+ filledPositions: zod_1.z.number().int().nullable(),
47
+ closeReason: exports.JobCloseReasonSchema.nullable(),
48
+ closeSource: exports.JobCloseSourceSchema.nullable(),
49
+ occurredAt: zod_1.z.union([zod_1.z.string().datetime(), zod_1.z.date()]),
50
+ });
51
+ /**
52
+ * Creation Source Enum
53
+ */
54
+ exports.CreationSourceSchema = zod_1.z.enum(['MANUAL', 'BOT']);
55
+ /** UK-local calendar date the job starts, e.g. '2026-07-14'. */
56
+ exports.JobStartDateSchema = zod_1.z
57
+ .string()
58
+ .regex(/^\d{4}-\d{2}-\d{2}$/, 'Expected YYYY-MM-DD')
59
+ .describe('Start date (UK-local calendar date)');
19
60
  /**
20
61
  * Job Sortable Fields Enum
21
62
  */
@@ -34,60 +75,71 @@ exports.JobSortableFieldsSchema = zod_1.z
34
75
  'receivedRate',
35
76
  'workHours',
36
77
  'qualificationsCount',
78
+ 'creationSource',
37
79
  'createdAt',
38
80
  'updatedAt',
81
+ 'startDate',
39
82
  ])
40
83
  .openapi({ title: 'JobSortableFields' });
84
+ /** Maps sort field values to ability field paths on SortJobSchema. */
85
+ exports.JobSortFieldMapping = {
86
+ description: 'description',
87
+ numberOfPositions: 'numberOfPositions',
88
+ status: 'status',
89
+ tradeId: 'tradeId',
90
+ collaborationCompany: 'collaboration.companyId',
91
+ collaborationClient: 'collaboration.clientId',
92
+ collaborationAgent: 'collaboration.userId',
93
+ distance: 'distance',
94
+ postcode: 'postcode',
95
+ payRate: 'payRate',
96
+ receivedRate: 'receivedRate',
97
+ workHours: 'workHours',
98
+ qualificationsCount: 'qualificationsCount',
99
+ creationSource: 'creationSource',
100
+ createdAt: 'createdAt',
101
+ updatedAt: 'updatedAt',
102
+ startDate: 'startDate',
103
+ };
41
104
  /**
42
105
  * Pay Schema - Nested object for job payment details
43
106
  */
44
107
  exports.PaySchema = zod_1.z
45
108
  .object({
46
- rateUnit: common_schemas_1.RateUnitSchema.describe('The unit for the pay rate'),
47
- isNegotiable: zod_1.z
48
- .boolean()
49
- .default(false)
50
- .describe('Whether the rate is negotiable'),
51
- rate: zod_1.z.coerce
52
- .number()
53
- .min(1)
54
- .nullable()
55
- .optional()
56
- .describe('The pay rate'),
109
+ rateUnit: common_schemas_1.RateUnitSchema.describe('Hourly or Daily'),
110
+ isNegotiable: zod_1.z.boolean().default(false).describe('Negotiable'),
111
+ rate: zod_1.z.coerce.number().min(1).nullable().optional().describe('e.g. 15.00'),
57
112
  rateMax: zod_1.z.coerce
58
113
  .number()
59
114
  .min(1)
60
115
  .nullable()
61
116
  .optional()
62
- .describe('The maximum pay rate (for a range)'),
117
+ .describe('e.g. 20.00'),
63
118
  receivedRate: zod_1.z.coerce
64
119
  .number()
65
120
  .min(1)
66
121
  .nullable()
67
122
  .optional()
68
- .describe('The received pay rate'),
123
+ .describe('e.g. 18.00'),
69
124
  })
70
125
  .openapi({ title: 'Pay' });
71
126
  exports.CreatePaySchema = zod_1.z
72
127
  .object({
73
- rateUnit: common_schemas_1.RateUnitSchema.default('HOURLY').describe('The unit for the pay rate'),
74
- isNegotiable: zod_1.z
75
- .boolean()
76
- .default(false)
77
- .describe('Whether the rate is negotiable'),
78
- rate: zod_1.z.number().min(1).nullable().optional().describe('The pay rate'),
128
+ rateUnit: common_schemas_1.RateUnitSchema.default('HOURLY').describe('Pay rate'),
129
+ isNegotiable: zod_1.z.boolean().default(false).describe('Negotiable'),
130
+ rate: zod_1.z.number().min(1).nullable().optional().describe('Pay rate'),
79
131
  rateMax: zod_1.z
80
132
  .number()
81
133
  .min(1)
82
134
  .optional()
83
135
  .nullable()
84
- .describe('The maximum pay rate (for a range)'),
136
+ .describe('Maximum pay rate'),
85
137
  receivedRate: zod_1.z
86
138
  .number()
87
139
  .min(1)
88
140
  .nullable()
89
141
  .optional()
90
- .describe('The received pay rate'),
142
+ .describe('Received rate'),
91
143
  })
92
144
  .superRefine((data, ctx) => {
93
145
  if (!data.isNegotiable) {
@@ -121,13 +173,13 @@ exports.CreatePaySchema = zod_1.z
121
173
  exports.JobQualificationSchema = zod_1.z
122
174
  .object({
123
175
  id: zod_1.z.string().uuid().describe('The ID of the job qualification'),
124
- qualificationId: zod_1.z.string().uuid().describe('The ID of the qualification'),
176
+ qualificationId: zod_1.z.string().uuid().describe('Qualification'),
125
177
  qualificationTypeId: zod_1.z
126
178
  .string()
127
179
  .uuid()
128
180
  .optional()
129
181
  .nullable()
130
- .describe('The ID of the qualification type'),
182
+ .describe('Qualification type'),
131
183
  })
132
184
  .openapi({ title: 'JobQualification' });
133
185
  exports.CreateJobQualificationSchema = zod_1.z
@@ -136,7 +188,7 @@ exports.CreateJobQualificationSchema = zod_1.z
136
188
  qualificationTypeId: zod_1.z
137
189
  .union([zod_1.z.string().uuid(), zod_1.z.null()])
138
190
  .optional()
139
- .describe('The ID of the qualification type'),
191
+ .describe('Qualification type'),
140
192
  })
141
193
  .openapi({ title: 'CreateJobQualification' });
142
194
  /**
@@ -145,24 +197,18 @@ exports.CreateJobQualificationSchema = zod_1.z
145
197
  exports.JobSchema = zod_1.z
146
198
  .object({
147
199
  id: zod_1.z.string().uuid().describe('Job ID'),
148
- description: zod_1.z.string().describe('Job Description'),
149
- numberOfPositions: zod_1.z
150
- .number()
151
- .int()
152
- .min(1)
153
- .describe('Number of Positions Available'),
200
+ description: zod_1.z.string().describe('Description'),
201
+ numberOfPositions: zod_1.z.number().int().min(1).describe('Positions'),
154
202
  workHours: zod_1.z.coerce
155
203
  .number()
156
204
  .min(0.01)
157
205
  .max(60)
158
206
  .optional()
159
207
  .nullable()
160
- .describe('Number of Work Hours'),
161
- status: exports.JobStatusSchema.describe('Job Status'),
208
+ .describe('Work Hours'),
209
+ status: exports.JobStatusSchema.describe('Status'),
162
210
  pay: exports.PaySchema.describe('Payment Details'),
163
- location: common_schemas_1.LocationDetailsSchema.optional()
164
- .nullable()
165
- .describe('Job Location'),
211
+ location: common_schemas_1.LocationDetailsSchema.optional().nullable().describe('Location'),
166
212
  tradeId: zod_1.z
167
213
  .string()
168
214
  .min(1, { message: 'Trade is required' })
@@ -172,10 +218,10 @@ exports.JobSchema = zod_1.z
172
218
  .array(exports.JobQualificationSchema)
173
219
  .optional()
174
220
  .default([])
175
- .describe('Job Qualifications'),
176
- currentCollaboration: collaborations_contract_1.CollaborationSchema.nullable()
221
+ .describe('Qualifications'),
222
+ collaboration: collaborations_contract_1.CollaborationSchema.nullable()
177
223
  .optional()
178
- .describe('Current Collaboration'),
224
+ .describe('Collaboration'),
179
225
  createdAt: zod_1.z
180
226
  .union([zod_1.z.string().datetime(), zod_1.z.date()])
181
227
  .transform((val) => (val instanceof Date ? val.toISOString() : val))
@@ -193,6 +239,9 @@ exports.JobSchema = zod_1.z
193
239
  createdBy: users_contract_1.UserSchema.nullable()
194
240
  .optional()
195
241
  .describe('User who created the job'),
242
+ creationSource: exports.CreationSourceSchema.nullable()
243
+ .optional()
244
+ .describe('How the job was created (BOT or MANUAL)'),
196
245
  distanceKm: zod_1.z.number().nullable().optional().describe('Distance in KM'),
197
246
  filledPositions: zod_1.z
198
247
  .number()
@@ -200,8 +249,58 @@ exports.JobSchema = zod_1.z
200
249
  .min(0)
201
250
  .default(0)
202
251
  .describe('Number of filled positions in the current availability window (computed from qualifying bookings)'),
252
+ startDate: exports.JobStartDateSchema.nullable().describe('Start date'),
203
253
  })
204
254
  .openapi({ title: 'Job' });
255
+ /**
256
+ * JobListItemSchema - Lightweight schema for job list views.
257
+ * Uses summary nested types instead of full entity schemas to reduce payload size.
258
+ * Key differences from JobSchema:
259
+ * - `location` uses LocationSummarySchema (4 fields) instead of LocationDetailsSchema (9 fields)
260
+ * - `collaboration` uses CollaborationSummarySchema instead of full CollaborationSchema
261
+ * - `createdBy` uses UserSummarySchema (shown as FA on jobs with no collaboration)
262
+ */
263
+ exports.JobListItemSchema = zod_1.z
264
+ .object({
265
+ id: zod_1.z.string().uuid(),
266
+ description: zod_1.z.string(),
267
+ numberOfPositions: zod_1.z.coerce.number().int().min(1),
268
+ workHours: zod_1.z.coerce.number().nullable().optional(),
269
+ status: exports.JobStatusSchema,
270
+ pay: exports.PaySchema,
271
+ location: summary_schemas_1.LocationSummarySchema.nullable().optional(),
272
+ tradeId: zod_1.z.string().uuid(),
273
+ jobQualifications: zod_1.z.array(exports.JobQualificationSchema).nullable().optional(),
274
+ collaboration: summary_schemas_1.CollaborationSummarySchema.nullable().optional(),
275
+ createdAt: zod_1.z
276
+ .union([zod_1.z.string().datetime(), zod_1.z.date()])
277
+ .transform((val) => (val instanceof Date ? val.toISOString() : val)),
278
+ updatedAt: zod_1.z
279
+ .union([zod_1.z.string().datetime(), zod_1.z.date()])
280
+ .transform((val) => (val instanceof Date ? val.toISOString() : val)),
281
+ createdById: zod_1.z.string().uuid().nullable().optional(),
282
+ createdBy: summary_schemas_1.UserSummarySchema.nullable().optional(),
283
+ creationSource: exports.CreationSourceSchema.nullable().optional(),
284
+ distanceKm: zod_1.z.coerce.number().nullable().optional(),
285
+ filledPositions: zod_1.z.coerce.number().int().min(0).default(0),
286
+ startDate: exports.JobStartDateSchema.nullable().optional().describe('Start date'),
287
+ })
288
+ .openapi({ title: 'JobListItem' });
289
+ // FeedJobItem mirrors JobListItem (flat tradeId, JobQualificationSchema-shaped
290
+ // jobQualifications) — names for trades/qualifications are resolved on the
291
+ // client from the shared trades/qualifications context, not denormalized here.
292
+ exports.FeedJobItemSchema = exports.JobListItemSchema.extend({
293
+ // Legacy/imported jobs may not have a trade. The jobs table deliberately
294
+ // permits this and the feed UI renders an explicit no-trade state.
295
+ tradeId: zod_1.z.string().uuid().nullable(),
296
+ availableSince: zod_1.z
297
+ .union([zod_1.z.string().datetime(), zod_1.z.date()])
298
+ .transform((val) => (val instanceof Date ? val.toISOString() : val))
299
+ .nullable(),
300
+ }).openapi({ title: 'FeedJobItem' });
301
+ exports.PaginatedJobListResponseSchema = (0, pagination_schema_1.createPaginatedResponseSchema)(exports.JobListItemSchema)
302
+ .describe('Jobs retrieved successfully')
303
+ .openapi({ title: 'JobListPaginatedResponse' });
205
304
  /**
206
305
  * Lightweight schema for map marker data.
207
306
  * Contains only the fields needed to place and identify markers on a map.
@@ -215,13 +314,23 @@ exports.JobMapMarkerSchema = zod_1.z
215
314
  latitude: zod_1.z.number().describe('Latitude coordinate'),
216
315
  longitude: zod_1.z.number().describe('Longitude coordinate'),
217
316
  postcode: zod_1.z.string().nullable().optional().describe('Postcode'),
218
- numberOfPositions: zod_1.z.number().int().min(1).describe('Number of positions'),
317
+ numberOfPositions: zod_1.z.number().int().min(1).describe('Positions'),
219
318
  filledPositions: zod_1.z
220
319
  .number()
221
320
  .int()
222
321
  .min(0)
223
322
  .default(0)
224
323
  .describe('Filled positions count'),
324
+ createdAt: zod_1.z
325
+ .string()
326
+ .datetime()
327
+ .describe('Job creation timestamp (ISO) — used for demand-trend bucketing'),
328
+ clusterId: zod_1.z
329
+ .string()
330
+ .uuid()
331
+ .nullable()
332
+ .optional()
333
+ .describe("Id of this job's CONFIRMED duplicate cluster, or null. The Breakdown collapses markers sharing a clusterId into one demand unit."),
225
334
  })
226
335
  .openapi({ title: 'JobMapMarker' });
227
336
  exports.JobMapMarkersResponseSchema = zod_1.z
@@ -231,37 +340,129 @@ exports.JobMapMarkersResponseSchema = zod_1.z
231
340
  excludedCount: zod_1.z
232
341
  .number()
233
342
  .int()
234
- .describe('Jobs excluded due to missing coordinates'),
343
+ .describe('Jobs beyond the 1000-marker render cap (all returned markers have coordinates)'),
235
344
  })
236
345
  .openapi({ title: 'JobMapMarkersResponse' });
237
346
  /**
238
- * Create Job Schema
347
+ * Demand/Supply breakdown (spec 2026-07-11-demand-supply-accuracy-design).
348
+ * A "demand unit" is a cluster-deduped availability episode island; see
349
+ * apps/api demand-breakdown.sql.ts for derivation.
239
350
  */
240
- exports.CreateJobSchema = zod_1.z
351
+ exports.DemandWindowSchema = zod_1.z
241
352
  .object({
242
- description: zod_1.z.string().min(10).describe('Job Description'),
243
- location: common_schemas_1.CreateLocationSchema.optional()
244
- .nullable()
245
- .describe('Job Location'),
246
- numberOfPositions: zod_1.z
353
+ from: zod_1.z.string().date().describe('Window start (inclusive, yyyy-MM-dd)'),
354
+ to: zod_1.z.string().date().describe('Window end (inclusive, yyyy-MM-dd)'),
355
+ })
356
+ .refine((w) => w.from <= w.to, { message: 'window.from must be <= window.to' })
357
+ .refine((w) => (Date.parse(w.to) - Date.parse(w.from)) / 86400000 <= 366, { message: 'window must span at most 366 days' })
358
+ .openapi({ title: 'DemandWindow' });
359
+ const demandBreakdownFilterShape = {
360
+ window: exports.DemandWindowSchema,
361
+ tradeId: zod_1.z.string().uuid().optional().nullable().describe('Filter by trade'),
362
+ companyId: zod_1.z.string().uuid().optional().nullable().describe('Search Company'),
363
+ clientId: zod_1.z.string().uuid().optional().nullable().describe('Search Client'),
364
+ userId: zod_1.z.string().uuid().optional().nullable().describe('Search First Agent'),
365
+ location: common_schemas_1.LocationFilterSchema.optional().nullable().describe('Filter by location'),
366
+ pay: common_schemas_1.PayRangeSchema.optional().nullable().describe('Filter by pay rate range'),
367
+ qualificationFilters: zod_1.z
368
+ .array(common_schemas_1.QualificationFilterSchema)
369
+ .optional()
370
+ .describe('Qualifications'),
371
+ };
372
+ exports.DemandBreakdownFilterSchema = zod_1.z
373
+ .object(demandBreakdownFilterShape)
374
+ .openapi({ title: 'DemandBreakdownFilter' });
375
+ exports.DemandBreakdownRowSchema = zod_1.z
376
+ .object({
377
+ area: zod_1.z.string().describe('Postcode area (outward letters, e.g. "SW")'),
378
+ tradeId: zod_1.z.string().uuid(),
379
+ tradeName: zod_1.z.string(),
380
+ units: zod_1.z.number().int().describe('Demand units in window (cluster-deduped)'),
381
+ episodes: zod_1.z.number().int().describe('Raw episodes folded into those units'),
382
+ positionEpisodes: zod_1.z
247
383
  .number()
248
384
  .int()
249
- .min(1)
250
- .max(100)
251
- .describe('Number of Positions'),
252
- workHours: zod_1.z
385
+ .describe('Σ unit positions (post-collapse) — the flow numerator'),
386
+ filledInWindow: zod_1.z
253
387
  .number()
254
- .min(0.01)
255
- .max(60)
256
- .default(8)
257
- .describe('Number of Work Hours'),
258
- pay: exports.CreatePaySchema.describe('Payment Details'),
388
+ .int()
389
+ .describe('Filled-status bookings created in window on scoped jobs'),
390
+ stockUnfilled: zod_1.z
391
+ .number()
392
+ .int()
393
+ .describe('Unfilled positions on currently-AVAILABLE jobs (deduped)'),
394
+ unitsFirstHalf: zod_1.z.number().int(),
395
+ unitsSecondHalf: zod_1.z.number().int(),
396
+ centroidLongitude: zod_1.z.number().nullable(),
397
+ centroidLatitude: zod_1.z.number().nullable(),
398
+ })
399
+ .openapi({ title: 'DemandBreakdownRow' });
400
+ exports.DemandBreakdownResponseSchema = zod_1.z
401
+ .object({
402
+ rows: zod_1.z.array(exports.DemandBreakdownRowSchema),
403
+ totals: zod_1.z.object({
404
+ units: zod_1.z.number().int(),
405
+ episodes: zod_1.z.number().int(),
406
+ positionEpisodes: zod_1.z.number().int(),
407
+ filledInWindow: zod_1.z.number().int(),
408
+ stockUnfilled: zod_1.z.number().int(),
409
+ }),
410
+ excludedNoLocation: zod_1.z
411
+ .number()
412
+ .int()
413
+ .describe('Scoped jobs skipped: missing/unparseable postcode'),
414
+ excludedNoTrade: zod_1.z.number().int().describe('Scoped jobs skipped: no trade'),
415
+ })
416
+ .openapi({ title: 'DemandBreakdownResponse' });
417
+ exports.DemandEpisodeSchema = zod_1.z
418
+ .object({
419
+ jobId: zod_1.z.string().uuid(),
420
+ occurredAt: zod_1.z.string().describe('Episode timestamp (ISO)'),
421
+ positions: zod_1.z.number().int(),
422
+ kind: zod_1.z.enum(['CREATED', 'REOPEN']),
423
+ })
424
+ .openapi({ title: 'DemandEpisode' });
425
+ exports.DemandUnitSchema = zod_1.z
426
+ .object({
427
+ unitStart: zod_1.z.string().describe('First episode timestamp (ISO)'),
428
+ positions: zod_1.z.number().int().describe('Max positions across merged episodes'),
429
+ clusterStatus: zod_1.z.enum(['CONFIRMED', 'PENDING', 'NONE']),
430
+ episodes: zod_1.z.array(exports.DemandEpisodeSchema),
431
+ jobs: zod_1.z.array(zod_1.z.object({
432
+ jobId: zod_1.z.string().uuid(),
433
+ status: exports.JobStatusSchema,
434
+ positions: zod_1.z.number().int(),
435
+ })),
436
+ filledInWindow: zod_1.z.number().int(),
437
+ stockUnfilled: zod_1.z.number().int(),
438
+ })
439
+ .openapi({ title: 'DemandUnit' });
440
+ exports.DemandBreakdownDetailQuerySchema = zod_1.z
441
+ .object({
442
+ ...demandBreakdownFilterShape,
443
+ area: zod_1.z.string().min(1).describe('Postcode area key, e.g. "SW"'),
444
+ tradeId: zod_1.z.string().uuid().describe('Trade (required here)'),
445
+ })
446
+ .openapi({ title: 'DemandBreakdownDetailQuery' });
447
+ exports.DemandBreakdownDetailResponseSchema = zod_1.z
448
+ .object({ units: zod_1.z.array(exports.DemandUnitSchema) })
449
+ .openapi({ title: 'DemandBreakdownDetailResponse' });
450
+ /**
451
+ * Create Job Schema
452
+ */
453
+ exports.CreateJobSchema = zod_1.z
454
+ .object({
455
+ description: zod_1.z.string().min(10).describe('Description'),
456
+ location: common_schemas_1.CreateLocationSchema.optional().nullable().describe('Location'),
259
457
  tradeId: zod_1.z
260
458
  .string()
261
459
  .min(1, { message: 'Trade is required' })
262
460
  .pipe(zod_1.z.string().uuid())
263
461
  .describe('Trade'),
264
- currentCollaboration: zod_1.z
462
+ numberOfPositions: zod_1.z.number().int().min(1).max(100).describe('Positions'),
463
+ workHours: zod_1.z.number().min(0.01).max(60).default(8).describe('Work Hours'),
464
+ pay: exports.CreatePaySchema.describe('Payment Details'),
465
+ collaboration: zod_1.z
265
466
  .object({
266
467
  id: zod_1.z
267
468
  .string()
@@ -271,85 +472,51 @@ exports.CreateJobSchema = zod_1.z
271
472
  })
272
473
  .optional()
273
474
  .nullable()
274
- .describe('Current Collaboration'),
475
+ .describe('Collaboration'),
476
+ status: exports.JobStatusSchema.optional().describe('Status'),
275
477
  jobQualifications: zod_1.z
276
478
  .array(exports.CreateJobQualificationSchema)
277
479
  .optional()
278
- .describe('Job Qualifications'),
279
- status: exports.JobStatusSchema.optional().describe('Job Status'),
280
- })
281
- .superRefine((data, ctx) => {
282
- // If no collaboration is provided, status must be DRAFT (or will default to DRAFT)
283
- const hasCollaboration = data.currentCollaboration && data.currentCollaboration.id;
284
- if (!hasCollaboration) {
285
- // If status is explicitly set to non-DRAFT, fail validation
286
- if (data.status !== undefined && data.status !== 'DRAFT') {
287
- ctx.addIssue({
288
- code: zod_1.z.ZodIssueCode.custom,
289
- message: 'A collaboration is required when creating a job with non-draft status.',
290
- path: ['currentCollaboration'],
291
- });
292
- }
293
- }
294
- })
295
- .transform((data) => {
296
- // If no collaboration, default status to DRAFT
297
- const hasCollaboration = data.currentCollaboration && data.currentCollaboration.id;
298
- return {
299
- ...data,
300
- status: hasCollaboration ? (data.status ?? 'AVAILABLE') : 'DRAFT',
301
- };
480
+ .describe('Qualifications'),
481
+ acknowledgedDuplicateIds: zod_1.z
482
+ .array(zod_1.z.string().uuid())
483
+ .optional()
484
+ .describe('Ids of suspected-duplicate jobs the creator has reviewed and confirmed are NOT the same job. Presence (even empty) skips the duplicate probe and records rejected pairs against these ids.'),
485
+ startDate: exports.JobStartDateSchema.nullable().optional(),
302
486
  })
487
+ .transform((data) => ({
488
+ ...data,
489
+ status: data.status ?? 'AVAILABLE',
490
+ }))
303
491
  .openapi({ title: 'CreateJob' });
304
492
  /**
305
- * Create Draft Job Schema - For bot-created jobs without collaboration
493
+ * Update Job Schema
306
494
  */
307
- exports.CreateDraftJobSchema = zod_1.z
495
+ exports.UpdateJobSchema = zod_1.z
308
496
  .object({
309
- description: zod_1.z.string().min(10).describe('Job Description'),
310
- location: common_schemas_1.CreateLocationSchema.optional()
311
- .nullable()
312
- .describe('Job Location'),
313
- numberOfPositions: zod_1.z
314
- .number()
315
- .int()
316
- .min(1)
317
- .max(100)
318
- .describe('Number of Positions'),
319
- workHours: zod_1.z
320
- .number()
321
- .min(0.01)
322
- .max(60)
323
- .default(8)
324
- .describe('Number of Work Hours'),
325
- pay: exports.CreatePaySchema.describe('Payment Details'),
497
+ description: zod_1.z.string().min(10).optional().describe('Description'),
498
+ location: common_schemas_1.CreateLocationSchema.optional().nullable().describe('Location'),
326
499
  tradeId: zod_1.z
327
500
  .string()
328
501
  .min(1, { message: 'Trade is required' })
329
502
  .pipe(zod_1.z.string().uuid())
330
- .describe('Trade'),
331
- jobQualifications: zod_1.z
332
- .array(exports.CreateJobQualificationSchema)
333
503
  .optional()
334
- .describe('Job Qualifications'),
335
- })
336
- .openapi({ title: 'CreateDraftJob' });
337
- /**
338
- * Update Job Schema
339
- */
340
- exports.UpdateJobSchema = zod_1.z
341
- .object({
342
- description: zod_1.z.string().min(10).optional().describe('Job Description'),
343
- location: common_schemas_1.CreateLocationSchema.optional()
344
- .nullable()
345
- .describe('Job Location'),
504
+ .describe('Trade'),
346
505
  numberOfPositions: zod_1.z
347
506
  .number()
348
507
  .int()
349
508
  .min(1)
350
509
  .max(100)
351
510
  .optional()
352
- .describe('Number of Positions'),
511
+ .describe('Positions'),
512
+ positionsAreRemaining: zod_1.z
513
+ .boolean()
514
+ .optional()
515
+ .describe('When true, numberOfPositions is the count STILL NEEDED (remaining); the API sets total = currentFilled + numberOfPositions. Omitted/false = absolute total. Set by the bot on reposts; never by the web form.'),
516
+ declaredFilled: zod_1.z
517
+ .boolean()
518
+ .optional()
519
+ .describe('When closing a job (status -> NOT_AVAILABLE), marks it as DECLARED filled (sourced externally, e.g. a "filled" reply in the group) rather than the default BOOKINGS-derived close. Set by the bot on "filled" closes only; never by the web form or on cancellations.'),
353
520
  workHours: zod_1.z
354
521
  .number()
355
522
  .min(0.01)
@@ -357,13 +524,7 @@ exports.UpdateJobSchema = zod_1.z
357
524
  .optional()
358
525
  .describe('Number of Work Hours'),
359
526
  pay: exports.CreatePaySchema.optional().describe('Payment Details'),
360
- tradeId: zod_1.z
361
- .string()
362
- .min(1, { message: 'Trade is required' })
363
- .pipe(zod_1.z.string().uuid())
364
- .optional()
365
- .describe('Trade'),
366
- currentCollaboration: zod_1.z
527
+ collaboration: zod_1.z
367
528
  .preprocess((val) => (val === '' ? null : val), zod_1.z
368
529
  .object({
369
530
  id: zod_1.z
@@ -385,32 +546,13 @@ exports.UpdateJobSchema = zod_1.z
385
546
  }
386
547
  return val;
387
548
  })
388
- .describe('Current Collaboration'),
549
+ .describe('Collaboration'),
550
+ status: exports.JobStatusSchema.optional().describe('Job Status'),
389
551
  jobQualifications: zod_1.z
390
552
  .array(exports.CreateJobQualificationSchema)
391
553
  .optional()
392
554
  .describe('Job Qualifications'),
393
- status: exports.JobStatusSchema.optional().describe('Job Status'),
394
- })
395
- .superRefine((data, ctx) => {
396
- // If status is being set to something other than DRAFT,
397
- // and currentCollaboration is null or an empty object (form with no selection),
398
- // then require a collaboration.
399
- // Note: We check for null or missing id specifically, not `!data.currentCollaboration`,
400
- // because undefined means the field wasn't provided in the request (PATCH),
401
- // and the service layer will handle checking the existing job's collaboration.
402
- const hasNoCollaboration = data.currentCollaboration === null ||
403
- (data.currentCollaboration !== undefined &&
404
- !data.currentCollaboration.id);
405
- if (data.status !== undefined &&
406
- data.status !== 'DRAFT' &&
407
- hasNoCollaboration) {
408
- ctx.addIssue({
409
- code: zod_1.z.ZodIssueCode.custom,
410
- message: 'A collaboration is required when setting status to a non-draft value.',
411
- path: ['currentCollaboration'],
412
- });
413
- }
555
+ startDate: exports.JobStartDateSchema.nullable().optional(),
414
556
  })
415
557
  .openapi({ title: 'UpdateJob' });
416
558
  exports.BatchUpdateJobSchema = zod_1.z
@@ -446,40 +588,53 @@ exports.BatchDeleteJobResponseSchema = zod_1.z
446
588
  * Filter Job Schema
447
589
  */
448
590
  exports.FilterJobSchema = pagination_query_schema_1.PaginationQuerySchema.extend({
449
- tradeId: zod_1.z.string().uuid().optional().nullable().describe('Filter by trade'),
450
- qualificationFilters: zod_1.z
451
- .array(curated_workers_contract_1.QualificationFilterSchema)
452
- .optional()
453
- .describe('Filter by qualifications'),
454
- status: exports.JobStatusSchema.optional()
591
+ status: exports.JobStatusSchema.optional().nullable().describe('Status'),
592
+ creationSource: exports.CreationSourceSchema.optional()
455
593
  .nullable()
456
- .describe('Filter by job status'),
594
+ .describe('Filter by creation source'),
595
+ tradeId: zod_1.z.string().uuid().optional().nullable().describe('Filter by trade'),
596
+ description: zod_1.z.string().optional().nullable().describe('Paste job post'),
597
+ companyId: zod_1.z.string().uuid().optional().nullable().describe('Search Company'),
598
+ clientId: zod_1.z.string().uuid().optional().nullable().describe('Search Client'),
457
599
  userId: zod_1.z
458
600
  .string()
459
601
  .uuid()
460
602
  .optional()
461
603
  .nullable()
462
604
  .describe('Search First Agent'),
463
- clientId: zod_1.z.string().uuid().optional().nullable().describe('Search Client'),
464
- companyId: zod_1.z.string().uuid().optional().nullable().describe('Search Company'),
465
605
  location: common_schemas_1.LocationFilterSchema.optional()
466
606
  .nullable()
467
607
  .describe('Filter by location'),
468
608
  pay: common_schemas_1.PayRangeSchema.optional()
469
609
  .nullable()
470
610
  .describe('Filter by pay rate range'),
471
- sortBy: exports.JobSortableFieldsSchema.optional()
472
- .nullable()
473
- .describe('The field to sort the results by'),
474
- sortOrder: common_schemas_1.SortOrderSchema.optional()
475
- .nullable()
476
- .describe('The order to sort the results by'),
611
+ qualificationFilters: zod_1.z
612
+ .array(common_schemas_1.QualificationFilterSchema)
613
+ .optional()
614
+ .describe('Qualifications'),
477
615
  createdAt: common_schemas_1.DateRangeSchema.optional()
478
616
  .nullable()
479
617
  .describe('Filter by created date range'),
480
618
  updatedAt: common_schemas_1.DateRangeSchema.optional()
481
619
  .nullable()
482
620
  .describe('Filter by updated date range'),
621
+ sort: (0, common_schemas_1.createSortArraySchema)(exports.JobSortableFieldsSchema),
622
+ });
623
+ exports.JOB_FEED_PAGE_SIZE = 300;
624
+ exports.JobFeedQuerySchema = exports.FilterJobSchema.extend({
625
+ page: zod_1.z.coerce.number().int().min(1).default(1),
626
+ limit: zod_1.z.coerce
627
+ .number()
628
+ .int()
629
+ .min(1)
630
+ .max(exports.JOB_FEED_PAGE_SIZE)
631
+ .default(exports.JOB_FEED_PAGE_SIZE),
632
+ });
633
+ exports.JobFeedResponseSchema = zod_1.z.object({
634
+ items: exports.FeedJobItemSchema.array().max(exports.JOB_FEED_PAGE_SIZE),
635
+ page: zod_1.z.number().int().min(1),
636
+ limit: zod_1.z.number().int().min(1).max(exports.JOB_FEED_PAGE_SIZE),
637
+ hasMore: zod_1.z.boolean(),
483
638
  });
484
639
  exports.PaginatedJobResponseSchema = (0, pagination_schema_1.createPaginatedResponseSchema)(exports.JobSchema)
485
640
  .describe('Jobs retrieved successfully')
@@ -488,34 +643,32 @@ exports.PaginatedJobResponseSchema = (0, pagination_schema_1.createPaginatedResp
488
643
  * Filter schema for map markers — same filters as job list, but no pagination.
489
644
  */
490
645
  exports.FilterMapMarkersSchema = zod_1.z.object({
646
+ status: exports.JobStatusSchema.optional().nullable().describe('Status'),
491
647
  tradeId: zod_1.z.string().uuid().optional().nullable().describe('Filter by trade'),
492
- status: exports.JobStatusSchema.optional()
493
- .nullable()
494
- .describe('Filter by job status'),
648
+ companyId: zod_1.z.string().uuid().optional().nullable().describe('Search Company'),
649
+ clientId: zod_1.z.string().uuid().optional().nullable().describe('Search Client'),
495
650
  userId: zod_1.z
496
651
  .string()
497
652
  .uuid()
498
653
  .optional()
499
654
  .nullable()
500
655
  .describe('Search First Agent'),
501
- clientId: zod_1.z.string().uuid().optional().nullable().describe('Search Client'),
502
- companyId: zod_1.z.string().uuid().optional().nullable().describe('Search Company'),
503
656
  location: common_schemas_1.LocationFilterSchema.optional()
504
657
  .nullable()
505
658
  .describe('Filter by location'),
506
659
  pay: common_schemas_1.PayRangeSchema.optional()
507
660
  .nullable()
508
661
  .describe('Filter by pay rate range'),
662
+ qualificationFilters: zod_1.z
663
+ .array(common_schemas_1.QualificationFilterSchema)
664
+ .optional()
665
+ .describe('Qualifications'),
509
666
  createdAt: common_schemas_1.DateRangeSchema.optional()
510
667
  .nullable()
511
668
  .describe('Filter by created date range'),
512
669
  updatedAt: common_schemas_1.DateRangeSchema.optional()
513
670
  .nullable()
514
671
  .describe('Filter by updated date range'),
515
- qualificationFilters: zod_1.z
516
- .array(curated_workers_contract_1.QualificationFilterSchema)
517
- .optional()
518
- .describe('Filter by qualifications'),
519
672
  });
520
673
  /**
521
674
  * Search Job Schema - For trigram-based duplicate detection
@@ -525,12 +678,15 @@ exports.SearchJobQuerySchema = zod_1.z
525
678
  description: zod_1.z
526
679
  .string()
527
680
  .min(10)
528
- .describe('Job description to search for similar jobs'),
529
- userId: zod_1.z
681
+ .describe('Description to search for similar jobs'),
682
+ userId: zod_1.z.string().uuid().optional().describe('Search First Agent'),
683
+ tradeId: zod_1.z.string().uuid().optional().describe('Trade'),
684
+ postcode: zod_1.z
530
685
  .string()
531
- .uuid()
686
+ .min(1)
687
+ .max(8)
532
688
  .optional()
533
- .describe('Filter by user who created the job'),
689
+ .describe('Postcode for structured fallback when trigram finds no matches'),
534
690
  threshold: zod_1.z.coerce
535
691
  .number()
536
692
  .min(0.1)
@@ -544,11 +700,28 @@ exports.SearchJobResultSchema = zod_1.z
544
700
  .object({
545
701
  similarity: zod_1.z.number().describe('Similarity score (0-1)'),
546
702
  job: exports.JobSchema.describe('The matching job'),
703
+ lastCloseSource: exports.JobCloseSourceSchema.nullable()
704
+ .optional()
705
+ .describe('closeSource of the last close event, when job is NOT_AVAILABLE'),
706
+ lastClosedAt: zod_1.z
707
+ .string()
708
+ .datetime()
709
+ .nullable()
710
+ .optional()
711
+ .describe('occurredAt of the last close event, when job is NOT_AVAILABLE'),
547
712
  })
548
713
  .openapi({ title: 'SearchJobResult' });
549
714
  exports.SearchJobResponseSchema = zod_1.z
550
715
  .array(exports.SearchJobResultSchema)
551
716
  .openapi({ title: 'SearchJobResponse' });
717
+ exports.DuplicateJobConflictSchema = zod_1.z
718
+ .object({
719
+ code: zod_1.z.literal('DUPLICATE_JOB_SUSPECTED'),
720
+ candidates: zod_1.z
721
+ .array(exports.SearchJobResultSchema)
722
+ .describe('Existing open jobs that look like duplicates of the submission'),
723
+ })
724
+ .openapi({ title: 'DuplicateJobConflict' });
552
725
  const c = (0, core_1.initContract)();
553
726
  exports.jobsContractRouter = c.router({
554
727
  create: {
@@ -556,28 +729,17 @@ exports.jobsContractRouter = c.router({
556
729
  path: '/v2/jobs',
557
730
  responses: {
558
731
  201: exports.JobSchema,
559
- 409: error_schemas_1.ErrorResponseSchema,
732
+ 409: exports.DuplicateJobConflictSchema,
560
733
  },
561
734
  body: exports.CreateJobSchema,
562
735
  summary: 'Create a new job',
563
736
  metadata: { tags: ['Jobs'], openApi: { operationId: 'createJob' } },
564
737
  },
565
- createDraft: {
566
- method: 'POST',
567
- path: '/v2/jobs/draft',
568
- responses: {
569
- 201: exports.JobSchema,
570
- 409: error_schemas_1.ErrorResponseSchema,
571
- },
572
- body: exports.CreateDraftJobSchema,
573
- summary: 'Create a draft job (without collaboration)',
574
- metadata: { tags: ['Jobs'], openApi: { operationId: 'createDraftJob' } },
575
- },
576
738
  findAll: {
577
739
  method: 'GET',
578
740
  path: '/v2/jobs',
579
741
  responses: {
580
- 200: exports.PaginatedJobResponseSchema,
742
+ 200: exports.PaginatedJobListResponseSchema,
581
743
  },
582
744
  query: exports.FilterJobSchema,
583
745
  summary: 'Get all jobs',
@@ -606,6 +768,25 @@ exports.jobsContractRouter = c.router({
606
768
  openApi: { operationId: 'getJobMapMarkers' },
607
769
  },
608
770
  },
771
+ getDemandBreakdown: {
772
+ method: 'GET',
773
+ path: '/v2/jobs/demand-breakdown',
774
+ responses: { 200: exports.DemandBreakdownResponseSchema },
775
+ query: exports.DemandBreakdownFilterSchema,
776
+ summary: 'Area×trade demand rollup: units/flow, stock, trend halves, centroids',
777
+ metadata: { tags: ['Jobs'], openApi: { operationId: 'getDemandBreakdown' } },
778
+ },
779
+ getDemandBreakdownDetail: {
780
+ method: 'GET',
781
+ path: '/v2/jobs/demand-breakdown/detail',
782
+ responses: { 200: exports.DemandBreakdownDetailResponseSchema },
783
+ query: exports.DemandBreakdownDetailQuerySchema,
784
+ summary: 'Evidence drill-down: demand units with episodes for one area×trade',
785
+ metadata: {
786
+ tags: ['Jobs'],
787
+ openApi: { operationId: 'getDemandBreakdownDetail' },
788
+ },
789
+ },
609
790
  batchUpdate: {
610
791
  method: 'PATCH',
611
792
  path: '/v2/jobs/batch',
@@ -639,6 +820,16 @@ exports.jobsContractRouter = c.router({
639
820
  openApi: { operationId: 'batchDeleteJobs' },
640
821
  },
641
822
  },
823
+ feed: {
824
+ method: 'GET',
825
+ path: '/v2/jobs/feed',
826
+ query: exports.JobFeedQuerySchema,
827
+ responses: {
828
+ 200: exports.JobFeedResponseSchema,
829
+ },
830
+ summary: 'Get a paginated live jobs feed; AVAILABLE jobs are retained and unavailable jobs expire after 30 minutes',
831
+ metadata: { tags: ['Jobs'], openApi: { operationId: 'getJobFeed' } },
832
+ },
642
833
  findOne: {
643
834
  method: 'GET',
644
835
  path: '/v2/jobs/:id',
@@ -652,6 +843,19 @@ exports.jobsContractRouter = c.router({
652
843
  summary: 'Get a job by ID',
653
844
  metadata: { tags: ['Jobs'], openApi: { operationId: 'findJobById' } },
654
845
  },
846
+ events: {
847
+ method: 'GET',
848
+ path: '/v2/jobs/:id/events',
849
+ responses: {
850
+ 200: zod_1.z.object({ items: exports.JobEventSchema.array() }),
851
+ 404: error_schemas_1.ErrorResponseSchema,
852
+ },
853
+ pathParams: zod_1.z.object({
854
+ id: zod_1.z.string().uuid().describe('Job ID'),
855
+ }),
856
+ summary: 'Get the lifecycle event history for a job (newest first)',
857
+ metadata: { tags: ['Jobs'], openApi: { operationId: 'getJobEvents' } },
858
+ },
655
859
  update: {
656
860
  method: 'PATCH',
657
861
  path: '/v2/jobs/:id',