@open-mercato/core 0.10.1-develop.7717.1.2befe9c634 → 0.10.1-develop.7721.1.b5c4a00a68

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 (384) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/staff_support_routing_rule/index.js +21 -0
  3. package/dist/generated/entities/staff_support_routing_rule/index.js.map +7 -0
  4. package/dist/generated/entities/staff_support_ticket/index.js +37 -0
  5. package/dist/generated/entities/staff_support_ticket/index.js.map +7 -0
  6. package/dist/generated/entities/staff_time_project/index.js +2 -0
  7. package/dist/generated/entities/staff_time_project/index.js.map +2 -2
  8. package/dist/generated/entities/staff_time_project_member/index.js +2 -0
  9. package/dist/generated/entities/staff_time_project_member/index.js.map +2 -2
  10. package/dist/generated/entities/staff_time_task/index.js +4 -0
  11. package/dist/generated/entities/staff_time_task/index.js.map +2 -2
  12. package/dist/generated/entities/staff_time_task_comment/index.js +9 -1
  13. package/dist/generated/entities/staff_time_task_comment/index.js.map +2 -2
  14. package/dist/generated/entities.ids.generated.js +2 -0
  15. package/dist/generated/entities.ids.generated.js.map +2 -2
  16. package/dist/generated/entity-fields-registry.js +38 -0
  17. package/dist/generated/entity-fields-registry.js.map +2 -2
  18. package/dist/helpers/integration/auth.js +1 -0
  19. package/dist/helpers/integration/auth.js.map +2 -2
  20. package/dist/helpers/integration/communicationChannelsFixtures.js +20 -0
  21. package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
  22. package/dist/modules/catalog/api/bulk-delete/route.js +12 -2
  23. package/dist/modules/catalog/api/bulk-delete/route.js.map +2 -2
  24. package/dist/modules/communication_channels/api/post/test-seed/route.js +17 -3
  25. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  26. package/dist/modules/communication_channels/lib/test-seed.js +38 -5
  27. package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
  28. package/dist/modules/messages/commands/messages.js +2 -3
  29. package/dist/modules/messages/commands/messages.js.map +2 -2
  30. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js +2 -2
  31. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js.map +2 -2
  32. package/dist/modules/staff/api/portal/support-tickets/[id]/attachments/route.js +299 -0
  33. package/dist/modules/staff/api/portal/support-tickets/[id]/attachments/route.js.map +7 -0
  34. package/dist/modules/staff/api/portal/support-tickets/[id]/messages/route.js +91 -0
  35. package/dist/modules/staff/api/portal/support-tickets/[id]/messages/route.js.map +7 -0
  36. package/dist/modules/staff/api/portal/support-tickets/[id]/route.js +146 -0
  37. package/dist/modules/staff/api/portal/support-tickets/[id]/route.js.map +7 -0
  38. package/dist/modules/staff/api/portal/support-tickets/options/route.js +60 -0
  39. package/dist/modules/staff/api/portal/support-tickets/options/route.js.map +7 -0
  40. package/dist/modules/staff/api/portal/support-tickets/route.js +220 -0
  41. package/dist/modules/staff/api/portal/support-tickets/route.js.map +7 -0
  42. package/dist/modules/staff/api/timesheets/settings/route.js +7 -1
  43. package/dist/modules/staff/api/timesheets/settings/route.js.map +2 -2
  44. package/dist/modules/staff/api/timesheets/support-routing-rules/fallback-project/route.js +122 -0
  45. package/dist/modules/staff/api/timesheets/support-routing-rules/fallback-project/route.js.map +7 -0
  46. package/dist/modules/staff/api/timesheets/support-routing-rules/preview/route.js +180 -0
  47. package/dist/modules/staff/api/timesheets/support-routing-rules/preview/route.js.map +7 -0
  48. package/dist/modules/staff/api/timesheets/support-routing-rules/route.js +147 -0
  49. package/dist/modules/staff/api/timesheets/support-routing-rules/route.js.map +7 -0
  50. package/dist/modules/staff/api/timesheets/support-tickets/options/route.js +133 -0
  51. package/dist/modules/staff/api/timesheets/support-tickets/options/route.js.map +7 -0
  52. package/dist/modules/staff/api/timesheets/tasks/[id]/claim/route.js +33 -0
  53. package/dist/modules/staff/api/timesheets/tasks/[id]/claim/route.js.map +7 -0
  54. package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js +25 -7
  55. package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js.map +2 -2
  56. package/dist/modules/staff/api/timesheets/tasks/[id]/release/route.js +32 -0
  57. package/dist/modules/staff/api/timesheets/tasks/[id]/release/route.js.map +7 -0
  58. package/dist/modules/staff/api/timesheets/tasks/route.js +94 -47
  59. package/dist/modules/staff/api/timesheets/tasks/route.js.map +2 -2
  60. package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js +3 -0
  61. package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js.map +2 -2
  62. package/dist/modules/staff/api/timesheets/time-projects/route.js +3 -0
  63. package/dist/modules/staff/api/timesheets/time-projects/route.js.map +2 -2
  64. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js +1 -0
  65. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js.map +2 -2
  66. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +54 -4
  67. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +2 -2
  68. package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js +21 -5
  69. package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js.map +2 -2
  70. package/dist/modules/staff/backend/staff/time-tracking/settings/page.js +319 -254
  71. package/dist/modules/staff/backend/staff/time-tracking/settings/page.js.map +2 -2
  72. package/dist/modules/staff/backend/staff/time-tracking/support/page.js +363 -0
  73. package/dist/modules/staff/backend/staff/time-tracking/support/page.js.map +7 -0
  74. package/dist/modules/staff/backend/staff/time-tracking/support/page.meta.js +18 -0
  75. package/dist/modules/staff/backend/staff/time-tracking/support/page.meta.js.map +7 -0
  76. package/dist/modules/staff/cli.js +27 -0
  77. package/dist/modules/staff/cli.js.map +2 -2
  78. package/dist/modules/staff/commands/index.js +3 -0
  79. package/dist/modules/staff/commands/index.js.map +2 -2
  80. package/dist/modules/staff/commands/shared.js +10 -1
  81. package/dist/modules/staff/commands/shared.js.map +2 -2
  82. package/dist/modules/staff/commands/support-routing-rules.js +505 -0
  83. package/dist/modules/staff/commands/support-routing-rules.js.map +7 -0
  84. package/dist/modules/staff/commands/support-tickets.js +513 -0
  85. package/dist/modules/staff/commands/support-tickets.js.map +7 -0
  86. package/dist/modules/staff/commands/timesheets-projects.js +72 -14
  87. package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
  88. package/dist/modules/staff/commands/timesheets-task-assignment.js +270 -0
  89. package/dist/modules/staff/commands/timesheets-task-assignment.js.map +7 -0
  90. package/dist/modules/staff/commands/timesheets-task-comments.js +58 -12
  91. package/dist/modules/staff/commands/timesheets-task-comments.js.map +2 -2
  92. package/dist/modules/staff/commands/timesheets-tasks.js +91 -9
  93. package/dist/modules/staff/commands/timesheets-tasks.js.map +3 -3
  94. package/dist/modules/staff/data/enrichers.js +141 -0
  95. package/dist/modules/staff/data/enrichers.js.map +2 -2
  96. package/dist/modules/staff/data/entities.js +143 -2
  97. package/dist/modules/staff/data/entities.js.map +2 -2
  98. package/dist/modules/staff/data/extensions.js +8 -0
  99. package/dist/modules/staff/data/extensions.js.map +2 -2
  100. package/dist/modules/staff/data/validators.js +34 -5
  101. package/dist/modules/staff/data/validators.js.map +2 -2
  102. package/dist/modules/staff/encryption.js +6 -0
  103. package/dist/modules/staff/encryption.js.map +2 -2
  104. package/dist/modules/staff/events.js +25 -0
  105. package/dist/modules/staff/events.js.map +2 -2
  106. package/dist/modules/staff/events.payloads.js +54 -0
  107. package/dist/modules/staff/events.payloads.js.map +2 -2
  108. package/dist/modules/staff/extension-points.js +1 -0
  109. package/dist/modules/staff/extension-points.js.map +2 -2
  110. package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.js +468 -0
  111. package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.js.map +7 -0
  112. package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.meta.js +12 -0
  113. package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.meta.js.map +7 -0
  114. package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.js +316 -0
  115. package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.js.map +7 -0
  116. package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.meta.js +12 -0
  117. package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.meta.js.map +7 -0
  118. package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.js +190 -0
  119. package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.js.map +7 -0
  120. package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.meta.js +19 -0
  121. package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.meta.js.map +7 -0
  122. package/dist/modules/staff/index.js +1 -1
  123. package/dist/modules/staff/index.js.map +2 -2
  124. package/dist/modules/staff/lib/crud.js +2 -0
  125. package/dist/modules/staff/lib/crud.js.map +2 -2
  126. package/dist/modules/staff/lib/support/attachments.js +36 -0
  127. package/dist/modules/staff/lib/support/attachments.js.map +7 -0
  128. package/dist/modules/staff/lib/support/dictionaries.js +87 -0
  129. package/dist/modules/staff/lib/support/dictionaries.js.map +7 -0
  130. package/dist/modules/staff/lib/support/notifications.js +111 -0
  131. package/dist/modules/staff/lib/support/notifications.js.map +7 -0
  132. package/dist/modules/staff/lib/support/portalAttachments.js +100 -0
  133. package/dist/modules/staff/lib/support/portalAttachments.js.map +7 -0
  134. package/dist/modules/staff/lib/support/portalBroadcast.js +117 -0
  135. package/dist/modules/staff/lib/support/portalBroadcast.js.map +7 -0
  136. package/dist/modules/staff/lib/support/portalRoute.js +99 -0
  137. package/dist/modules/staff/lib/support/portalRoute.js.map +7 -0
  138. package/dist/modules/staff/lib/support/portalStatus.js +12 -0
  139. package/dist/modules/staff/lib/support/portalStatus.js.map +7 -0
  140. package/dist/modules/staff/lib/support/portalTickets.js +148 -0
  141. package/dist/modules/staff/lib/support/portalTickets.js.map +7 -0
  142. package/dist/modules/staff/lib/support/routing.js +81 -0
  143. package/dist/modules/staff/lib/support/routing.js.map +7 -0
  144. package/dist/modules/staff/lib/support/routingRuleDraft.js +25 -0
  145. package/dist/modules/staff/lib/support/routingRuleDraft.js.map +7 -0
  146. package/dist/modules/staff/lib/support/seedDefaults.js +114 -0
  147. package/dist/modules/staff/lib/support/seedDefaults.js.map +7 -0
  148. package/dist/modules/staff/lib/support/supportActivity.js +26 -0
  149. package/dist/modules/staff/lib/support/supportActivity.js.map +7 -0
  150. package/dist/modules/staff/lib/support-ui/PortalSupportNotLinked.js +23 -0
  151. package/dist/modules/staff/lib/support-ui/PortalSupportNotLinked.js.map +7 -0
  152. package/dist/modules/staff/lib/support-ui/portalAttachmentValidation.js +112 -0
  153. package/dist/modules/staff/lib/support-ui/portalAttachmentValidation.js.map +7 -0
  154. package/dist/modules/staff/lib/support-ui/portalPendingUploads.js +45 -0
  155. package/dist/modules/staff/lib/support-ui/portalPendingUploads.js.map +7 -0
  156. package/dist/modules/staff/lib/support-ui/portalSupport.js +51 -0
  157. package/dist/modules/staff/lib/support-ui/portalSupport.js.map +7 -0
  158. package/dist/modules/staff/lib/time-tracking/access.js +3 -39
  159. package/dist/modules/staff/lib/time-tracking/access.js.map +2 -2
  160. package/dist/modules/staff/lib/time-tracking/listProjectAccess.js +54 -0
  161. package/dist/modules/staff/lib/time-tracking/listProjectAccess.js.map +7 -0
  162. package/dist/modules/staff/lib/time-tracking/portalRecipients.js +92 -2
  163. package/dist/modules/staff/lib/time-tracking/portalRecipients.js.map +2 -2
  164. package/dist/modules/staff/lib/time-tracking/projectAssignment.js +112 -0
  165. package/dist/modules/staff/lib/time-tracking/projectAssignment.js.map +7 -0
  166. package/dist/modules/staff/lib/time-tracking/settingKeys.js +14 -0
  167. package/dist/modules/staff/lib/time-tracking/settingKeys.js.map +2 -2
  168. package/dist/modules/staff/lib/time-tracking/settings.js +28 -1
  169. package/dist/modules/staff/lib/time-tracking/settings.js.map +2 -2
  170. package/dist/modules/staff/lib/time-tracking/taskAssignmentRoute.js +143 -0
  171. package/dist/modules/staff/lib/time-tracking/taskAssignmentRoute.js.map +7 -0
  172. package/dist/modules/staff/lib/time-tracking/workRecipients.js +92 -0
  173. package/dist/modules/staff/lib/time-tracking/workRecipients.js.map +7 -0
  174. package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js +32 -3
  175. package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js.map +2 -2
  176. package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js +29 -0
  177. package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js.map +2 -2
  178. package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js +4 -0
  179. package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js.map +2 -2
  180. package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js +141 -1
  181. package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js.map +2 -2
  182. package/dist/modules/staff/lib/time-tracking-ui/SupportAttachmentsSection.js +153 -0
  183. package/dist/modules/staff/lib/time-tracking-ui/SupportAttachmentsSection.js.map +7 -0
  184. package/dist/modules/staff/lib/time-tracking-ui/SupportRequestPanel.js +67 -0
  185. package/dist/modules/staff/lib/time-tracking-ui/SupportRequestPanel.js.map +7 -0
  186. package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js +3 -1
  187. package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js.map +2 -2
  188. package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js +80 -17
  189. package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js.map +2 -2
  190. package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js +230 -41
  191. package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js.map +2 -2
  192. package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js +21 -1
  193. package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js.map +2 -2
  194. package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js +16 -4
  195. package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js.map +2 -2
  196. package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js +3 -1
  197. package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js.map +2 -2
  198. package/dist/modules/staff/lib/time-tracking-ui/projectDefaultAssignee.js +68 -0
  199. package/dist/modules/staff/lib/time-tracking-ui/projectDefaultAssignee.js.map +7 -0
  200. package/dist/modules/staff/lib/time-tracking-ui/settingsTabs.js +7 -0
  201. package/dist/modules/staff/lib/time-tracking-ui/settingsTabs.js.map +7 -0
  202. package/dist/modules/staff/lib/time-tracking-ui/supportTicketData.js +50 -0
  203. package/dist/modules/staff/lib/time-tracking-ui/supportTicketData.js.map +7 -0
  204. package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js +13 -1
  205. package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js.map +2 -2
  206. package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js +36 -2
  207. package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js.map +2 -2
  208. package/dist/modules/staff/migrations/Migration20261009180543_staff.js +42 -0
  209. package/dist/modules/staff/migrations/Migration20261009180543_staff.js.map +7 -0
  210. package/dist/modules/staff/notifications.js +92 -0
  211. package/dist/modules/staff/notifications.js.map +2 -2
  212. package/dist/modules/staff/setup.js +6 -2
  213. package/dist/modules/staff/setup.js.map +2 -2
  214. package/dist/modules/staff/subscribers/support-portal-comment-created.js +26 -0
  215. package/dist/modules/staff/subscribers/support-portal-comment-created.js.map +7 -0
  216. package/dist/modules/staff/subscribers/support-portal-comment-deleted.js +26 -0
  217. package/dist/modules/staff/subscribers/support-portal-comment-deleted.js.map +7 -0
  218. package/dist/modules/staff/subscribers/support-portal-comment-updated.js +26 -0
  219. package/dist/modules/staff/subscribers/support-portal-comment-updated.js.map +7 -0
  220. package/dist/modules/staff/subscribers/support-portal-status-column-updated.js +24 -0
  221. package/dist/modules/staff/subscribers/support-portal-status-column-updated.js.map +7 -0
  222. package/dist/modules/staff/subscribers/support-portal-task-status-changed.js +25 -0
  223. package/dist/modules/staff/subscribers/support-portal-task-status-changed.js.map +7 -0
  224. package/dist/modules/staff/subscribers/support-portal-task-updated.js +25 -0
  225. package/dist/modules/staff/subscribers/support-portal-task-updated.js.map +7 -0
  226. package/dist/modules/staff/subscribers/support-ticket-created-notification.js +25 -0
  227. package/dist/modules/staff/subscribers/support-ticket-created-notification.js.map +7 -0
  228. package/dist/modules/staff/subscribers/support-ticket-customer-replied-notification.js +25 -0
  229. package/dist/modules/staff/subscribers/support-ticket-customer-replied-notification.js.map +7 -0
  230. package/dist/modules/staff/subscribers/support-ticket-unnotified-clear.js +26 -0
  231. package/dist/modules/staff/subscribers/support-ticket-unnotified-clear.js.map +7 -0
  232. package/dist/modules/staff/subscribers/time-task-assignee-notification.js +83 -0
  233. package/dist/modules/staff/subscribers/time-task-assignee-notification.js.map +7 -0
  234. package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.client.js +112 -0
  235. package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.client.js.map +7 -0
  236. package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.js +17 -0
  237. package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.js.map +7 -0
  238. package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.client.js +870 -0
  239. package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.client.js.map +7 -0
  240. package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.js +17 -0
  241. package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.js.map +7 -0
  242. package/dist/modules/staff/widgets/injection-table.js +16 -1
  243. package/dist/modules/staff/widgets/injection-table.js.map +2 -2
  244. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +4 -18
  245. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  246. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +4 -18
  247. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  248. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +4 -18
  249. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  250. package/dist/modules/wms/lib/inventoryCsvExport.js +19 -0
  251. package/dist/modules/wms/lib/inventoryCsvExport.js.map +7 -0
  252. package/generated/entities/staff_support_routing_rule/index.ts +9 -0
  253. package/generated/entities/staff_support_ticket/index.ts +17 -0
  254. package/generated/entities/staff_time_project/index.ts +1 -0
  255. package/generated/entities/staff_time_project_member/index.ts +1 -0
  256. package/generated/entities/staff_time_task/index.ts +2 -0
  257. package/generated/entities/staff_time_task_comment/index.ts +4 -0
  258. package/generated/entities.ids.generated.ts +2 -0
  259. package/generated/entity-fields-registry.ts +38 -0
  260. package/package.json +8 -8
  261. package/src/helpers/integration/auth.ts +1 -1
  262. package/src/helpers/integration/communicationChannelsFixtures.ts +60 -2
  263. package/src/modules/catalog/api/bulk-delete/route.ts +12 -2
  264. package/src/modules/communication_channels/api/post/test-seed/route.ts +29 -12
  265. package/src/modules/communication_channels/lib/test-seed.ts +49 -10
  266. package/src/modules/messages/commands/messages.ts +8 -10
  267. package/src/modules/portal/frontend/[orgSlug]/portal/dashboard/page.tsx +2 -2
  268. package/src/modules/staff/AGENTS.md +22 -6
  269. package/src/modules/staff/api/portal/support-tickets/[id]/attachments/route.ts +327 -0
  270. package/src/modules/staff/api/portal/support-tickets/[id]/messages/route.ts +94 -0
  271. package/src/modules/staff/api/portal/support-tickets/[id]/route.ts +160 -0
  272. package/src/modules/staff/api/portal/support-tickets/options/route.ts +60 -0
  273. package/src/modules/staff/api/portal/support-tickets/route.ts +253 -0
  274. package/src/modules/staff/api/timesheets/settings/route.ts +7 -1
  275. package/src/modules/staff/api/timesheets/support-routing-rules/fallback-project/route.ts +131 -0
  276. package/src/modules/staff/api/timesheets/support-routing-rules/preview/route.ts +248 -0
  277. package/src/modules/staff/api/timesheets/support-routing-rules/route.ts +150 -0
  278. package/src/modules/staff/api/timesheets/support-tickets/options/route.ts +181 -0
  279. package/src/modules/staff/api/timesheets/tasks/[id]/claim/route.ts +31 -0
  280. package/src/modules/staff/api/timesheets/tasks/[id]/comments/route.ts +25 -7
  281. package/src/modules/staff/api/timesheets/tasks/[id]/release/route.ts +30 -0
  282. package/src/modules/staff/api/timesheets/tasks/route.ts +119 -67
  283. package/src/modules/staff/api/timesheets/time-projects/[id]/employees/route.ts +3 -0
  284. package/src/modules/staff/api/timesheets/time-projects/route.ts +3 -0
  285. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.tsx +1 -0
  286. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +67 -2
  287. package/src/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.ts +22 -3
  288. package/src/modules/staff/backend/staff/time-tracking/settings/page.tsx +405 -308
  289. package/src/modules/staff/backend/staff/time-tracking/support/page.meta.ts +14 -0
  290. package/src/modules/staff/backend/staff/time-tracking/support/page.tsx +428 -0
  291. package/src/modules/staff/cli.ts +28 -0
  292. package/src/modules/staff/commands/index.ts +3 -0
  293. package/src/modules/staff/commands/shared.ts +22 -1
  294. package/src/modules/staff/commands/support-routing-rules.ts +595 -0
  295. package/src/modules/staff/commands/support-tickets.ts +580 -0
  296. package/src/modules/staff/commands/timesheets-projects.ts +84 -13
  297. package/src/modules/staff/commands/timesheets-task-assignment.ts +319 -0
  298. package/src/modules/staff/commands/timesheets-task-comments.ts +70 -15
  299. package/src/modules/staff/commands/timesheets-tasks.ts +106 -15
  300. package/src/modules/staff/data/enrichers.ts +203 -0
  301. package/src/modules/staff/data/entities.ts +133 -2
  302. package/src/modules/staff/data/extensions.ts +9 -1
  303. package/src/modules/staff/data/validators.ts +36 -0
  304. package/src/modules/staff/encryption.ts +6 -0
  305. package/src/modules/staff/events.payloads.ts +87 -1
  306. package/src/modules/staff/events.ts +26 -0
  307. package/src/modules/staff/extension-points.ts +1 -0
  308. package/src/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.meta.ts +10 -0
  309. package/src/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.tsx +553 -0
  310. package/src/modules/staff/frontend/[orgSlug]/portal/support/new/page.meta.ts +10 -0
  311. package/src/modules/staff/frontend/[orgSlug]/portal/support/new/page.tsx +346 -0
  312. package/src/modules/staff/frontend/[orgSlug]/portal/support/page.meta.ts +17 -0
  313. package/src/modules/staff/frontend/[orgSlug]/portal/support/page.tsx +253 -0
  314. package/src/modules/staff/i18n/de.json +291 -0
  315. package/src/modules/staff/i18n/en.json +291 -0
  316. package/src/modules/staff/i18n/es.json +291 -0
  317. package/src/modules/staff/i18n/ko.json +291 -0
  318. package/src/modules/staff/i18n/pl.json +291 -0
  319. package/src/modules/staff/index.ts +1 -1
  320. package/src/modules/staff/lib/crud.ts +2 -1
  321. package/src/modules/staff/lib/support/attachments.ts +43 -0
  322. package/src/modules/staff/lib/support/dictionaries.ts +120 -0
  323. package/src/modules/staff/lib/support/notifications.ts +138 -0
  324. package/src/modules/staff/lib/support/portalAttachments.ts +140 -0
  325. package/src/modules/staff/lib/support/portalBroadcast.ts +161 -0
  326. package/src/modules/staff/lib/support/portalRoute.ts +108 -0
  327. package/src/modules/staff/lib/support/portalStatus.ts +15 -0
  328. package/src/modules/staff/lib/support/portalTickets.ts +233 -0
  329. package/src/modules/staff/lib/support/routing.ts +117 -0
  330. package/src/modules/staff/lib/support/routingRuleDraft.ts +45 -0
  331. package/src/modules/staff/lib/support/seedDefaults.ts +151 -0
  332. package/src/modules/staff/lib/support/supportActivity.ts +39 -0
  333. package/src/modules/staff/lib/support-ui/PortalSupportNotLinked.tsx +20 -0
  334. package/src/modules/staff/lib/support-ui/portalAttachmentValidation.ts +125 -0
  335. package/src/modules/staff/lib/support-ui/portalPendingUploads.ts +49 -0
  336. package/src/modules/staff/lib/support-ui/portalSupport.ts +116 -0
  337. package/src/modules/staff/lib/time-tracking/access.ts +2 -62
  338. package/src/modules/staff/lib/time-tracking/listProjectAccess.ts +78 -0
  339. package/src/modules/staff/lib/time-tracking/portalRecipients.ts +173 -5
  340. package/src/modules/staff/lib/time-tracking/projectAssignment.ts +172 -0
  341. package/src/modules/staff/lib/time-tracking/settingKeys.ts +11 -0
  342. package/src/modules/staff/lib/time-tracking/settings.ts +46 -1
  343. package/src/modules/staff/lib/time-tracking/taskAssignmentRoute.ts +165 -0
  344. package/src/modules/staff/lib/time-tracking/workRecipients.ts +183 -0
  345. package/src/modules/staff/lib/time-tracking-ui/BoardFilterChips.tsx +36 -1
  346. package/src/modules/staff/lib/time-tracking-ui/KanbanBoard.tsx +30 -0
  347. package/src/modules/staff/lib/time-tracking-ui/KanbanCard.tsx +9 -0
  348. package/src/modules/staff/lib/time-tracking-ui/ProjectFormSections.tsx +185 -6
  349. package/src/modules/staff/lib/time-tracking-ui/SupportAttachmentsSection.tsx +188 -0
  350. package/src/modules/staff/lib/time-tracking-ui/SupportRequestPanel.tsx +102 -0
  351. package/src/modules/staff/lib/time-tracking-ui/TaskBoardScreen.tsx +2 -0
  352. package/src/modules/staff/lib/time-tracking-ui/TaskCommentThread.tsx +105 -22
  353. package/src/modules/staff/lib/time-tracking-ui/TaskDrawer.tsx +278 -43
  354. package/src/modules/staff/lib/time-tracking-ui/boardDirectory.ts +21 -0
  355. package/src/modules/staff/lib/time-tracking-ui/boardFilters.ts +16 -2
  356. package/src/modules/staff/lib/time-tracking-ui/kanbanBoardData.ts +4 -0
  357. package/src/modules/staff/lib/time-tracking-ui/projectDefaultAssignee.ts +117 -0
  358. package/src/modules/staff/lib/time-tracking-ui/settingsTabs.ts +17 -0
  359. package/src/modules/staff/lib/time-tracking-ui/supportTicketData.ts +71 -0
  360. package/src/modules/staff/lib/time-tracking-ui/taskDrawerData.ts +15 -0
  361. package/src/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.ts +48 -1
  362. package/src/modules/staff/migrations/.snapshot-open-mercato.json +714 -0
  363. package/src/modules/staff/migrations/Migration20261009180543_staff.ts +50 -0
  364. package/src/modules/staff/notifications.ts +92 -0
  365. package/src/modules/staff/setup.ts +6 -2
  366. package/src/modules/staff/subscribers/support-portal-comment-created.ts +35 -0
  367. package/src/modules/staff/subscribers/support-portal-comment-deleted.ts +35 -0
  368. package/src/modules/staff/subscribers/support-portal-comment-updated.ts +35 -0
  369. package/src/modules/staff/subscribers/support-portal-status-column-updated.ts +36 -0
  370. package/src/modules/staff/subscribers/support-portal-task-status-changed.ts +34 -0
  371. package/src/modules/staff/subscribers/support-portal-task-updated.ts +34 -0
  372. package/src/modules/staff/subscribers/support-ticket-created-notification.ts +27 -0
  373. package/src/modules/staff/subscribers/support-ticket-customer-replied-notification.ts +27 -0
  374. package/src/modules/staff/subscribers/support-ticket-unnotified-clear.ts +29 -0
  375. package/src/modules/staff/subscribers/time-task-assignee-notification.ts +102 -0
  376. package/src/modules/staff/widgets/injection/portal-support-tickets/widget.client.tsx +151 -0
  377. package/src/modules/staff/widgets/injection/portal-support-tickets/widget.ts +16 -0
  378. package/src/modules/staff/widgets/injection/time-tracking-settings-support/widget.client.tsx +1058 -0
  379. package/src/modules/staff/widgets/injection/time-tracking-settings-support/widget.ts +17 -0
  380. package/src/modules/staff/widgets/injection-table.ts +15 -0
  381. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +4 -20
  382. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +4 -20
  383. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +4 -19
  384. package/src/modules/wms/lib/inventoryCsvExport.ts +18 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/staff/data/validators.ts"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport { PROJECT_COLOR_KEYS } from '../lib/timesheets-ui/colors'\nimport { hasTimeEntrySource, timeEntrySourceIds } from '../lib/time-tracking/timeEntrySources'\nimport { hasReportGrouping, reportGroupingIds } from '../lib/timesheets-reports/reportGroupings'\nimport {\n buildTimeTrackingSettingsSchema,\n timeTrackingRoundingDirectionSchema,\n timeTrackingRoundingUnitMinutesSchema,\n} from '../lib/time-tracking/settingKeys'\n\nconst projectColorSchema = z\n .string()\n .refine(\n (value) => (PROJECT_COLOR_KEYS as readonly string[]).includes(value),\n { message: 'Invalid project color key.' },\n )\n\nconst tagsSchema = z.array(z.string().min(1)).optional().default([])\n\nexport const optimisticUpdatedAtSchema = z.string().refine(\n (value) => !Number.isNaN(new Date(value).getTime()),\n { message: 'Invalid datetime' },\n)\n\nconst scopedCreateFields = {\n tenantId: z.string().uuid(),\n organizationId: z.string().uuid(),\n}\n\nconst scopedUpdateFields = {\n id: z.string().uuid(),\n}\n\nexport const staffTeamCreateSchema = z.object({\n ...scopedCreateFields,\n name: z.string().min(1),\n description: z.string().optional().nullable(),\n isActive: z.boolean().optional(),\n})\n\nexport const staffTeamUpdateSchema = z.object({\n ...scopedUpdateFields,\n name: z.string().min(1).optional(),\n description: z.string().optional().nullable(),\n isActive: z.boolean().optional(),\n})\n\nexport const staffTeamRoleCreateSchema = z.object({\n ...scopedCreateFields,\n teamId: z.string().uuid().optional().nullable(),\n name: z.string().min(1),\n description: z.string().optional().nullable(),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n})\n\nexport const staffTeamRoleUpdateSchema = z.object({\n ...scopedUpdateFields,\n teamId: z.string().uuid().optional().nullable(),\n name: z.string().min(1).optional(),\n description: z.string().optional().nullable(),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n})\n\nexport const staffTeamMemberCreateSchema = z.object({\n ...scopedCreateFields,\n teamId: z.string().uuid().optional().nullable(),\n displayName: z.string().min(1),\n description: z.string().optional().nullable(),\n userId: z.string().uuid().optional().nullable(),\n roleIds: z.array(z.string().uuid()).optional().default([]),\n tags: tagsSchema,\n availabilityRuleSetId: z.string().uuid().optional().nullable(),\n isActive: z.boolean().optional(),\n})\n\nexport const staffTeamMemberUpdateSchema = z.object({\n ...scopedUpdateFields,\n teamId: z.string().uuid().optional().nullable(),\n displayName: z.string().min(1).optional(),\n description: z.string().optional().nullable(),\n userId: z.string().uuid().optional().nullable(),\n roleIds: z.array(z.string().uuid()).optional(),\n tags: z.array(z.string().min(1)).optional(),\n availabilityRuleSetId: z.string().uuid().optional().nullable(),\n isActive: z.boolean().optional(),\n})\n\nexport const staffTeamMemberActivityCreateSchema = z.object({\n ...scopedCreateFields,\n entityId: z.string().uuid(),\n activityType: z.string().min(1).max(100),\n subject: z.string().max(200).optional(),\n body: z.string().max(8000).optional(),\n occurredAt: z.coerce.date().optional(),\n authorUserId: z.string().uuid().optional(),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n})\n\nexport const staffTeamMemberActivityUpdateSchema = z\n .object({\n id: z.string().uuid(),\n })\n .merge(staffTeamMemberActivityCreateSchema.partial())\n\nexport const staffTeamMemberJobHistoryCreateSchema = z.object({\n ...scopedCreateFields,\n entityId: z.string().uuid(),\n name: z.string().min(1).max(200),\n companyName: z.string().max(200).optional().nullable(),\n description: z.string().max(2000).optional().nullable(),\n startDate: z.coerce.date(),\n endDate: z.coerce.date().optional().nullable(),\n})\n\nexport const staffTeamMemberJobHistoryUpdateSchema = z\n .object({\n id: z.string().uuid(),\n updatedAt: optimisticUpdatedAtSchema.optional(),\n })\n .merge(staffTeamMemberJobHistoryCreateSchema.partial())\n\nexport const staffTeamMemberCommentCreateSchema = z.object({\n ...scopedCreateFields,\n entityId: z.string().uuid(),\n body: z.string().min(1).max(8000),\n authorUserId: z.string().uuid().optional(),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n})\n\nexport const staffTeamMemberCommentUpdateSchema = z\n .object({\n id: z.string().uuid(),\n })\n .merge(staffTeamMemberCommentCreateSchema.partial())\n\nexport const staffTeamMemberAddressCreateSchema = z.object({\n ...scopedCreateFields,\n entityId: z.string().uuid(),\n name: z.string().max(150).optional(),\n purpose: z.string().max(150).optional(),\n companyName: z.string().max(200).optional(),\n addressLine1: z.string().min(1).max(300),\n addressLine2: z.string().max(300).optional(),\n buildingNumber: z.string().max(50).optional(),\n flatNumber: z.string().max(50).optional(),\n city: z.string().max(150).optional(),\n region: z.string().max(150).optional(),\n postalCode: z.string().max(30).optional(),\n country: z.string().max(150).optional(),\n latitude: z.coerce.number().optional(),\n longitude: z.coerce.number().optional(),\n isPrimary: z.boolean().optional(),\n})\n\nexport const staffTeamMemberAddressUpdateSchema = z\n .object({\n id: z.string().uuid(),\n })\n .merge(staffTeamMemberAddressCreateSchema.partial())\n\nexport const staffTeamMemberTagAssignmentSchema = z.object({\n ...scopedCreateFields,\n memberId: z.string().uuid(),\n tag: z.string().min(1),\n})\n\nconst staffLeaveRequestStatusSchema = z.enum(['pending', 'approved', 'rejected'])\n\nconst validateStaffLeaveRequestDateRange = (\n value: { startDate?: Date; endDate?: Date },\n ctx: z.RefinementCtx,\n) => {\n if (!value.startDate || !value.endDate) return\n if (value.endDate < value.startDate) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'End date must be after start date.',\n path: ['endDate'],\n })\n }\n}\n\nexport const staffLeaveRequestCreateSchema = z\n .object({\n ...scopedCreateFields,\n memberId: z.string().uuid(),\n timezone: z.string().min(1),\n startDate: z.coerce.date(),\n endDate: z.coerce.date(),\n unavailabilityReasonEntryId: z.string().uuid().optional().nullable(),\n unavailabilityReasonValue: z.string().trim().min(1).max(150).optional().nullable(),\n note: z.string().max(2000).optional().nullable(),\n submittedByUserId: z.string().uuid().optional().nullable(),\n })\n .superRefine(validateStaffLeaveRequestDateRange)\n\nexport const staffLeaveRequestUpdateSchema = z\n .object({\n ...scopedUpdateFields,\n timezone: z.string().min(1).optional(),\n memberId: z.string().uuid().optional(),\n startDate: z.coerce.date().optional(),\n endDate: z.coerce.date().optional(),\n unavailabilityReasonEntryId: z.string().uuid().optional().nullable(),\n unavailabilityReasonValue: z.string().trim().min(1).max(150).optional().nullable(),\n note: z.string().max(2000).optional().nullable(),\n })\n .superRefine(validateStaffLeaveRequestDateRange)\n\nexport const staffLeaveRequestDecisionSchema = z.object({\n id: z.string().uuid(),\n decisionComment: z.string().max(2000).optional().nullable(),\n decidedByUserId: z.string().uuid().optional().nullable(),\n})\n\nexport const staffTeamMemberSelfCreateSchema = z.object({\n ...scopedCreateFields,\n displayName: z.string().min(1),\n description: z.string().max(2000).optional().nullable(),\n})\n\nexport type StaffTeamCreateInput = z.infer<typeof staffTeamCreateSchema>\nexport type StaffTeamUpdateInput = z.infer<typeof staffTeamUpdateSchema>\nexport type StaffTeamRoleCreateInput = z.infer<typeof staffTeamRoleCreateSchema>\nexport type StaffTeamRoleUpdateInput = z.infer<typeof staffTeamRoleUpdateSchema>\nexport type StaffTeamMemberCreateInput = z.infer<typeof staffTeamMemberCreateSchema>\nexport type StaffTeamMemberUpdateInput = z.infer<typeof staffTeamMemberUpdateSchema>\nexport type StaffTeamMemberTagAssignmentInput = z.infer<typeof staffTeamMemberTagAssignmentSchema>\nexport type StaffTeamMemberActivityCreateInput = z.infer<typeof staffTeamMemberActivityCreateSchema>\nexport type StaffTeamMemberActivityUpdateInput = z.infer<typeof staffTeamMemberActivityUpdateSchema>\nexport type StaffTeamMemberJobHistoryCreateInput = z.infer<typeof staffTeamMemberJobHistoryCreateSchema>\nexport type StaffTeamMemberJobHistoryUpdateInput = z.infer<typeof staffTeamMemberJobHistoryUpdateSchema>\nexport type StaffTeamMemberCommentCreateInput = z.infer<typeof staffTeamMemberCommentCreateSchema>\nexport type StaffTeamMemberCommentUpdateInput = z.infer<typeof staffTeamMemberCommentUpdateSchema>\nexport type StaffTeamMemberAddressCreateInput = z.infer<typeof staffTeamMemberAddressCreateSchema>\nexport type StaffTeamMemberAddressUpdateInput = z.infer<typeof staffTeamMemberAddressUpdateSchema>\nexport type StaffLeaveRequestStatus = z.infer<typeof staffLeaveRequestStatusSchema>\nexport type StaffLeaveRequestCreateInput = z.infer<typeof staffLeaveRequestCreateSchema>\nexport type StaffLeaveRequestUpdateInput = z.infer<typeof staffLeaveRequestUpdateSchema>\nexport type StaffLeaveRequestDecisionInput = z.infer<typeof staffLeaveRequestDecisionSchema>\nexport type StaffTeamMemberSelfCreateInput = z.infer<typeof staffTeamMemberSelfCreateSchema>\n\n// --- Timesheets validators (Phase 1) ---\n\n/**\n * EP-37: validated against the time-entry source registry rather than a literal\n * enum, so a contributed source is accepted on write the moment its module is\n * enabled. `superRefine` rather than `z.enum(...)` because the accepted set is\n * only known at call time.\n */\nconst timeEntrySourceSchema = z\n .string()\n .superRefine((value, ctx) => {\n if (hasTimeEntrySource(value)) return\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `[internal] unknown time entry source: ${value}`,\n params: { accepted: timeEntrySourceIds() },\n })\n })\nconst timeProjectStatusSchema = z.enum(['active', 'on_hold', 'completed'])\nconst timeProjectMemberStatusSchema = z.enum(['active', 'inactive'])\nconst timeEntrySegmentTypeSchema = z.enum(['work', 'break'])\nconst projectCodeSchema = z.string().min(1).max(50).regex(/^[a-zA-Z0-9-]+$/)\nconst moneyAmountSchema = z.number().min(0).max(99_999_999)\nconst timeProjectBudgetKindSchema = z.enum(['none', 'hours', 'amount'])\n\n// Upper-cased at the boundary so every writer stores canonical ISO 4217. The report\n// single-currency assertion compares codes case-sensitively, so `pln` and `PLN` would\n// otherwise read as two currencies and wrongly block a customer report.\nconst currencyCodeSchema = z.string().trim().length(3).transform((value) => value.toUpperCase())\n\n// numeric(14,4): ten integer digits, four decimals, never negative.\nconst numericAmountPattern = /^\\d{1,10}(?:\\.\\d{1,4})?$/\n\n/**\n * `numeric(14,4)` columns are surfaced by MikroORM as strings, and the project\n * form posts a typed decimal string, so the canonical representation for a stored\n * amount is a STRING end to end \u2014 a JSON number would push a 14-significant-digit\n * amount through a float on the way in. Plain numbers stay accepted for API\n * callers and are normalized to the same decimal string. (Entry-level money keeps\n * `moneyAmountSchema` above: `rate_override_amount` is consumed by the cost\n * calculator as a number, not written straight onto a numeric column.)\n */\nconst numericAmountSchema = z\n .union([z.number(), z.string()])\n .transform((value, ctx) => {\n const raw = typeof value === 'number' ? String(value) : value.trim().replace(',', '.')\n if (raw.length === 0) return null\n if (!numericAmountPattern.test(raw)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Expected a non-negative amount with at most 10 digits and 4 decimals.',\n })\n return z.NEVER\n }\n return raw\n })\n\nexport const staffTimeEntryCreateSchema = z.object({\n ...scopedCreateFields,\n staffMemberId: z.string().uuid(),\n date: z.coerce.date(),\n durationMinutes: z.number().int().min(0).max(1440),\n startedAt: z.coerce.date().optional().nullable(),\n endedAt: z.coerce.date().optional().nullable(),\n timeProjectId: z.string().uuid().optional().nullable(),\n customerId: z.string().uuid().optional().nullable(),\n dealId: z.string().uuid().optional().nullable(),\n orderId: z.string().uuid().optional().nullable(),\n notes: z.string().max(2000).optional().nullable(),\n source: timeEntrySourceSchema.optional().default('manual'),\n taskId: z.string().uuid().optional().nullable(),\n description: z.string().max(2000).optional().nullable(),\n isBillable: z.boolean().optional(),\n tagIds: z.array(z.string().uuid()).max(50).optional(),\n rateOverrideAmount: moneyAmountSchema.optional().nullable(),\n})\n\n/**\n * `startedAt` / `endedAt` mirror the create schema key for key: without them zod\n * strips the two clocks the entry form sends on every save, so correcting a start\n * or an end reported success and changed nothing. Nullable because clearing a\n * clock is a real edit, optional because omitting one must leave it alone \u2014 the\n * update command reads `undefined` as \"not part of this write\" and `null` as\n * \"clear it\". US-D3 keeps the three time fields consistent in the command, not\n * here: a request may legitimately carry all three and let the clocks win.\n */\nexport const staffTimeEntryUpdateSchema = z.object({\n ...scopedUpdateFields,\n date: z.coerce.date().optional(),\n durationMinutes: z.number().int().min(0).max(1440).optional(),\n startedAt: z.coerce.date().optional().nullable(),\n endedAt: z.coerce.date().optional().nullable(),\n timeProjectId: z.string().uuid().optional().nullable(),\n customerId: z.string().uuid().optional().nullable(),\n dealId: z.string().uuid().optional().nullable(),\n orderId: z.string().uuid().optional().nullable(),\n notes: z.string().max(2000).optional().nullable(),\n taskId: z.string().uuid().optional().nullable(),\n description: z.string().max(2000).optional().nullable(),\n isBillable: z.boolean().optional(),\n tagIds: z.array(z.string().uuid()).max(50).optional(),\n rateOverrideAmount: moneyAmountSchema.optional().nullable(),\n})\n\n/**\n * `taskId` is what makes starting a timer from a board card or the task drawer a\n * single write. Without it the surface has to start a project-level timer and\n * then PATCH the task onto it, and a failure between the two leaves a running\n * timer filed against the wrong thing.\n */\nexport const staffTimeEntryStartTimerSchema = z.object({\n ...scopedCreateFields,\n staffMemberId: z.string().uuid(),\n date: z.coerce.date(),\n timeProjectId: z.string().uuid().optional().nullable(),\n taskId: z.string().uuid().optional().nullable(),\n notes: z.string().max(2000).optional().nullable(),\n})\n\nexport const staffTimeEntryBulkItemSchema = z.object({\n id: z.string().uuid().optional().nullable(),\n date: z.coerce.date(),\n // Optional only because a task carries its project: a row naming a `taskId`\n // inherits the project from it, exactly as the single-entry path does. The\n // route refuses a row that names neither with `staff.timesheets.errors.projectRequired`,\n // so every stored row still lands on a project \u2014 the (project, date) cell the\n // lock gate addresses is never blank.\n timeProjectId: z.string().uuid().optional().nullable(),\n durationMinutes: z.number().int().min(0).max(1440),\n notes: z.string().max(2000).optional().nullable(),\n taskId: z.string().uuid().optional().nullable(),\n description: z.string().max(2000).optional().nullable(),\n isBillable: z.boolean().optional(),\n // Accepted by the schema and REFUSED by the route with 422: assigning tags\n // means dispatching the tag commands, which fork their own EntityManager and\n // cannot participate in this route's per-row transaction. Kept in the schema\n // so the refusal is explicit \u2014 dropping the key would let zod strip it and\n // restore the silent no-op.\n tagIds: z.array(z.string().uuid()).max(50).optional(),\n rateOverrideAmount: moneyAmountSchema.optional().nullable(),\n})\n\nexport const staffTimeEntryBulkSaveSchema = z.object({\n entries: z.array(staffTimeEntryBulkItemSchema).min(1).max(200),\n})\n\nexport const staffTimeEntrySegmentCreateSchema = z.object({\n ...scopedCreateFields,\n timeEntryId: z.string().uuid(),\n startedAt: z.coerce.date(),\n endedAt: z.coerce.date().optional().nullable(),\n segmentType: timeEntrySegmentTypeSchema.optional().default('work'),\n})\n\nexport const staffTimeEntrySegmentUpdateSchema = z.object({\n ...scopedUpdateFields,\n startedAt: z.coerce.date().optional(),\n endedAt: z.coerce.date().optional().nullable(),\n segmentType: timeEntrySegmentTypeSchema.optional(),\n})\n\nexport const staffTimeProjectCreateSchema = z.object({\n ...scopedCreateFields,\n name: z.string().min(1).max(255),\n // D-9 / US-B1: time is organised per customer, so a new project always names one.\n // Rows created before this change keep their null customer and stay editable\n // (see the update schema below), which is why only create is constrained.\n customerId: z.string().uuid(),\n customerSnapshot: z.record(z.string(), z.unknown()).optional().nullable(),\n code: projectCodeSchema,\n description: z.string().max(2000).optional().nullable(),\n projectType: z.string().max(100).optional().nullable(),\n color: projectColorSchema.optional().nullable(),\n status: timeProjectStatusSchema.optional().default('active'),\n ownerUserId: z.string().uuid().optional().nullable(),\n costCenter: z.string().max(100).optional().nullable(),\n startDate: z.coerce.date().optional().nullable(),\n hourlyRate: numericAmountSchema.optional().nullable(),\n // D-3: the currency may be chosen once, at creation. Every later change goes\n // through `POST .../change-currency`, which carries the non-conversion\n // acknowledgement and refuses while entries sit frozen in a closed report.\n currencyCode: currencyCodeSchema.optional().nullable(),\n billableByDefault: z.boolean().optional(),\n budgetKind: timeProjectBudgetKindSchema.optional().default('none'),\n budgetValue: numericAmountSchema.optional().nullable(),\n budgetWarnAtPercent: z.number().int().min(1).max(100).optional(),\n})\n\n/**\n * Deliberately has NO `currencyCode`: D-3 routes every post-creation currency\n * change through the dedicated change-currency action, so a plain PUT that\n * carries the key has it stripped here rather than relabelling the project\n * behind the acknowledgement and the locked-entry check.\n */\nexport const staffTimeProjectUpdateSchema = z.object({\n ...scopedUpdateFields,\n name: z.string().min(1).max(255).optional(),\n customerId: z.string().uuid().optional().nullable(),\n customerSnapshot: z.record(z.string(), z.unknown()).optional().nullable(),\n code: projectCodeSchema.optional(),\n description: z.string().max(2000).optional().nullable(),\n projectType: z.string().max(100).optional().nullable(),\n color: projectColorSchema.optional().nullable(),\n status: timeProjectStatusSchema.optional(),\n ownerUserId: z.string().uuid().optional().nullable(),\n costCenter: z.string().max(100).optional().nullable(),\n startDate: z.coerce.date().optional().nullable(),\n hourlyRate: numericAmountSchema.optional().nullable(),\n billableByDefault: z.boolean().optional(),\n budgetKind: timeProjectBudgetKindSchema.optional(),\n budgetValue: numericAmountSchema.optional().nullable(),\n budgetWarnAtPercent: z.number().int().min(1).max(100).optional(),\n})\n\nexport const staffTimeProjectMemberAssignSchema = z.object({\n ...scopedCreateFields,\n timeProjectId: z.string().uuid(),\n staffMemberId: z.string().uuid(),\n role: z.string().max(100).optional().nullable(),\n status: timeProjectMemberStatusSchema.optional().default('active'),\n assignedStartDate: z.coerce.date(),\n assignedEndDate: z.coerce.date().optional().nullable(),\n})\n\nexport const staffTimeProjectMemberUpdateSchema = z.object({\n ...scopedUpdateFields,\n role: z.string().max(100).optional().nullable(),\n status: timeProjectMemberStatusSchema.optional(),\n assignedEndDate: z.coerce.date().optional().nullable(),\n})\n\nexport const staffMyProjectVisibilityUpdateSchema = z.object({\n showInGrid: z.boolean(),\n})\n\nexport type StaffTimeEntryCreateInput = z.infer<typeof staffTimeEntryCreateSchema>\nexport type StaffTimeEntryUpdateInput = z.infer<typeof staffTimeEntryUpdateSchema>\nexport type StaffTimeEntryStartTimerInput = z.infer<typeof staffTimeEntryStartTimerSchema>\nexport type StaffTimeEntryBulkSaveInput = z.infer<typeof staffTimeEntryBulkSaveSchema>\nexport type StaffTimeEntrySegmentCreateInput = z.infer<typeof staffTimeEntrySegmentCreateSchema>\nexport type StaffTimeEntrySegmentUpdateInput = z.infer<typeof staffTimeEntrySegmentUpdateSchema>\nexport type StaffTimeProjectCreateInput = z.infer<typeof staffTimeProjectCreateSchema>\nexport type StaffTimeProjectUpdateInput = z.infer<typeof staffTimeProjectUpdateSchema>\nexport type StaffTimeProjectMemberAssignInput = z.infer<typeof staffTimeProjectMemberAssignSchema>\nexport type StaffTimeProjectMemberUpdateInput = z.infer<typeof staffTimeProjectMemberUpdateSchema>\nexport type StaffMyProjectVisibilityUpdateInput = z.infer<typeof staffMyProjectVisibilityUpdateSchema>\n\n// --- Time tracking consulting suite validators (tasks, tags, reports, settings) ---\n\nconst timeSlugSchema = z.string().trim().min(1).max(60).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/)\nconst timeReportPeriodKindSchema = z.enum(['week', 'month', 'year', 'custom'])\n/** EP-36: validated against the report grouping registry, not a literal enum. */\nconst timeReportGroupingSchema = z\n .string()\n .superRefine((value, ctx) => {\n if (hasReportGrouping(value)) return\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `[internal] unknown report grouping: ${value}`,\n params: { accepted: reportGroupingIds() },\n })\n })\nconst timeReportNonbillableModeSchema = z.enum(['separate', 'exclude'])\nconst timeRoundingDirectionSchema = timeTrackingRoundingDirectionSchema\nconst timeRoundingUnitMinutesSchema = timeTrackingRoundingUnitMinutesSchema\nconst positionSchema = z.number().int().min(0).max(1_000_000)\n\nexport const staffTimeTaskStatusCreateSchema = z.object({\n ...scopedCreateFields,\n timeProjectId: z.string().uuid(),\n name: z.string().trim().min(1).max(100),\n slug: timeSlugSchema.optional(),\n color: projectColorSchema.optional().nullable(),\n position: positionSchema.optional(),\n isDefault: z.boolean().optional(),\n isDone: z.boolean().optional(),\n})\n\nexport const staffTimeTaskStatusUpdateSchema = z.object({\n ...scopedUpdateFields,\n name: z.string().trim().min(1).max(100).optional(),\n color: projectColorSchema.optional().nullable(),\n position: positionSchema.optional(),\n isDefault: z.boolean().optional(),\n isDone: z.boolean().optional(),\n})\n\nexport const staffTimeTaskStatusReorderSchema = z.object({\n statuses: z\n .array(\n z.object({\n id: z.string().uuid(),\n position: positionSchema,\n }),\n )\n .min(1)\n .max(100),\n})\n\nexport const staffTimeTaskCreateSchema = z.object({\n ...scopedCreateFields,\n timeProjectId: z.string().uuid(),\n parentTaskId: z.string().uuid().optional().nullable(),\n taskStatusId: z.string().uuid().optional().nullable(),\n title: z.string().trim().min(1).max(255),\n description: z.string().max(8000).optional().nullable(),\n assigneeStaffMemberId: z.string().uuid().optional().nullable(),\n position: positionSchema.optional(),\n tagIds: z.array(z.string().uuid()).max(50).optional(),\n})\n\nexport const staffTimeTaskUpdateSchema = z.object({\n ...scopedUpdateFields,\n parentTaskId: z.string().uuid().optional().nullable(),\n taskStatusId: z.string().uuid().optional(),\n title: z.string().trim().min(1).max(255).optional(),\n description: z.string().max(8000).optional().nullable(),\n assigneeStaffMemberId: z.string().uuid().optional().nullable(),\n position: positionSchema.optional(),\n tagIds: z.array(z.string().uuid()).max(50).optional(),\n})\n\nexport const staffTimeTaskStatusChangeSchema = z.object({\n taskStatusId: z.string().uuid(),\n position: positionSchema.optional(),\n})\n\nexport const staffTimeTaskCommentCreateSchema = z.object({\n ...scopedCreateFields,\n taskId: z.string().uuid(),\n body: z.string().trim().min(1).max(5000),\n authorUserId: z.string().uuid().optional().nullable(),\n})\n\nexport const staffTimeTaskCommentUpdateSchema = z.object({\n ...scopedUpdateFields,\n body: z.string().trim().min(1).max(5000),\n})\n\nexport const staffTimeTagCreateSchema = z.object({\n ...scopedCreateFields,\n slug: timeSlugSchema,\n label: z.string().trim().min(1).max(100),\n color: projectColorSchema.optional().nullable(),\n})\n\nexport const staffTimeTaskTagAssignmentSchema = z.object({\n ...scopedCreateFields,\n taskId: z.string().uuid(),\n tagIds: z.array(z.string().uuid()).max(50),\n})\n\nexport const staffTimeEntryTagAssignmentSchema = z.object({\n ...scopedCreateFields,\n timeEntryId: z.string().uuid(),\n tagIds: z.array(z.string().uuid()).max(50),\n})\n\nconst validateStaffTimeReportPeriod = (\n value: { periodFrom?: Date; periodTo?: Date },\n ctx: z.RefinementCtx,\n) => {\n if (!value.periodFrom || !value.periodTo) return\n if (value.periodTo < value.periodFrom) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Period end must be after period start.',\n path: ['periodTo'],\n })\n }\n}\n\nexport const staffTimeReportCreateSchema = z\n .object({\n ...scopedCreateFields,\n customerId: z.string().uuid(),\n title: z.string().trim().min(1).max(255),\n periodKind: timeReportPeriodKindSchema,\n periodFrom: z.coerce.date(),\n periodTo: z.coerce.date(),\n grouping: timeReportGroupingSchema.optional().default('project_task'),\n nonbillableMode: timeReportNonbillableModeSchema.optional().default('separate'),\n includeAlreadyReported: z.boolean().optional().default(false),\n showRates: z.boolean().optional().default(true),\n timeProjectIds: z.array(z.string().uuid()).min(1).max(100),\n })\n .superRefine(validateStaffTimeReportPeriod)\n\nexport const staffTimeReportUpdateSchema = z\n .object({\n ...scopedUpdateFields,\n customerId: z.string().uuid().optional(),\n title: z.string().trim().min(1).max(255).optional(),\n periodKind: timeReportPeriodKindSchema.optional(),\n periodFrom: z.coerce.date().optional(),\n periodTo: z.coerce.date().optional(),\n grouping: timeReportGroupingSchema.optional(),\n nonbillableMode: timeReportNonbillableModeSchema.optional(),\n includeAlreadyReported: z.boolean().optional(),\n showRates: z.boolean().optional(),\n timeProjectIds: z.array(z.string().uuid()).min(1).max(100).optional(),\n })\n .superRefine(validateStaffTimeReportPeriod)\n\nexport const staffTimeReportPreviewSchema = z\n .object({\n customerId: z.string().uuid().optional().nullable(),\n periodKind: timeReportPeriodKindSchema.optional().default('custom'),\n periodFrom: z.coerce.date(),\n periodTo: z.coerce.date(),\n grouping: timeReportGroupingSchema.optional().default('project_task'),\n nonbillableMode: timeReportNonbillableModeSchema.optional().default('separate'),\n includeAlreadyReported: z.boolean().optional().default(false),\n showRates: z.boolean().optional().default(true),\n timeProjectIds: z.array(z.string().uuid()).min(1).max(100),\n })\n .superRefine(validateStaffTimeReportPeriod)\n\nexport const staffTimeReportCloseSchema = z.object({\n id: z.string().uuid(),\n})\n\nexport const staffTimeReportUnlockSchema = z.object({\n id: z.string().uuid(),\n reason: z.string().trim().min(1).max(2000),\n})\n\nexport const staffTimeProjectChangeCurrencySchema = z.object({\n currencyCode: currencyCodeSchema,\n acknowledged: z.literal(true),\n})\n\n/**\n * EP-42 \u2014 built from the setting-key registry rather than a literal, so a module can\n * contribute a key without patching this file. With no contribution the shape is the\n * eight built-in keys in their five groups, exactly as it was.\n *\n * This constant is evaluated once at module load. A key registered later still\n * validates on the wire because the settings route parses with\n * `buildTimeTrackingSettingsSchema()` per request and publishes it through an\n * OpenAPI getter.\n */\nexport const staffTimeTrackingSettingsSchema = buildTimeTrackingSettingsSchema()\n\nexport type StaffTimeReportPeriodKind = z.infer<typeof timeReportPeriodKindSchema>\nexport type StaffTimeReportGrouping = z.infer<typeof timeReportGroupingSchema>\nexport type StaffTimeReportNonbillableMode = z.infer<typeof timeReportNonbillableModeSchema>\nexport type StaffTimeRoundingDirection = z.infer<typeof timeRoundingDirectionSchema>\nexport type StaffTimeRoundingUnitMinutes = z.infer<typeof timeRoundingUnitMinutesSchema>\nexport type StaffTimeTaskStatusCreateInput = z.infer<typeof staffTimeTaskStatusCreateSchema>\nexport type StaffTimeTaskStatusUpdateInput = z.infer<typeof staffTimeTaskStatusUpdateSchema>\nexport type StaffTimeTaskStatusReorderInput = z.infer<typeof staffTimeTaskStatusReorderSchema>\nexport type StaffTimeTaskCreateInput = z.infer<typeof staffTimeTaskCreateSchema>\nexport type StaffTimeTaskUpdateInput = z.infer<typeof staffTimeTaskUpdateSchema>\nexport type StaffTimeTaskStatusChangeInput = z.infer<typeof staffTimeTaskStatusChangeSchema>\nexport type StaffTimeTaskCommentCreateInput = z.infer<typeof staffTimeTaskCommentCreateSchema>\nexport type StaffTimeTaskCommentUpdateInput = z.infer<typeof staffTimeTaskCommentUpdateSchema>\nexport type StaffTimeTagCreateInput = z.infer<typeof staffTimeTagCreateSchema>\nexport type StaffTimeTaskTagAssignmentInput = z.infer<typeof staffTimeTaskTagAssignmentSchema>\nexport type StaffTimeEntryTagAssignmentInput = z.infer<typeof staffTimeEntryTagAssignmentSchema>\nexport type StaffTimeReportCreateInput = z.infer<typeof staffTimeReportCreateSchema>\nexport type StaffTimeReportUpdateInput = z.infer<typeof staffTimeReportUpdateSchema>\nexport type StaffTimeReportPreviewInput = z.infer<typeof staffTimeReportPreviewSchema>\nexport type StaffTimeReportCloseInput = z.infer<typeof staffTimeReportCloseSchema>\nexport type StaffTimeReportUnlockInput = z.infer<typeof staffTimeReportUnlockSchema>\nexport type StaffTimeProjectChangeCurrencyInput = z.infer<typeof staffTimeProjectChangeCurrencySchema>\nexport type StaffTimeTrackingSettingsInput = z.infer<typeof staffTimeTrackingSettingsSchema>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { z } from 'zod'\nimport { PROJECT_COLOR_KEYS } from '../lib/timesheets-ui/colors'\nimport { hasTimeEntrySource, timeEntrySourceIds } from '../lib/time-tracking/timeEntrySources'\nimport { hasReportGrouping, reportGroupingIds } from '../lib/timesheets-reports/reportGroupings'\nimport {\n buildTimeTrackingSettingsSchema,\n timeTrackingRoundingDirectionSchema,\n timeTrackingRoundingUnitMinutesSchema,\n} from '../lib/time-tracking/settingKeys'\n\nconst projectColorSchema = z\n .string()\n .refine(\n (value) => (PROJECT_COLOR_KEYS as readonly string[]).includes(value),\n { message: 'Invalid project color key.' },\n )\n\nconst tagsSchema = z.array(z.string().min(1)).optional().default([])\n\nexport const optimisticUpdatedAtSchema = z.string().refine(\n (value) => !Number.isNaN(new Date(value).getTime()),\n { message: 'Invalid datetime' },\n)\n\nconst scopedCreateFields = {\n tenantId: z.string().uuid(),\n organizationId: z.string().uuid(),\n}\n\nconst scopedUpdateFields = {\n id: z.string().uuid(),\n}\n\nexport const staffTeamCreateSchema = z.object({\n ...scopedCreateFields,\n name: z.string().min(1),\n description: z.string().optional().nullable(),\n isActive: z.boolean().optional(),\n})\n\nexport const staffTeamUpdateSchema = z.object({\n ...scopedUpdateFields,\n name: z.string().min(1).optional(),\n description: z.string().optional().nullable(),\n isActive: z.boolean().optional(),\n})\n\nexport const staffTeamRoleCreateSchema = z.object({\n ...scopedCreateFields,\n teamId: z.string().uuid().optional().nullable(),\n name: z.string().min(1),\n description: z.string().optional().nullable(),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n})\n\nexport const staffTeamRoleUpdateSchema = z.object({\n ...scopedUpdateFields,\n teamId: z.string().uuid().optional().nullable(),\n name: z.string().min(1).optional(),\n description: z.string().optional().nullable(),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n})\n\nexport const staffTeamMemberCreateSchema = z.object({\n ...scopedCreateFields,\n teamId: z.string().uuid().optional().nullable(),\n displayName: z.string().min(1),\n description: z.string().optional().nullable(),\n userId: z.string().uuid().optional().nullable(),\n roleIds: z.array(z.string().uuid()).optional().default([]),\n tags: tagsSchema,\n availabilityRuleSetId: z.string().uuid().optional().nullable(),\n isActive: z.boolean().optional(),\n})\n\nexport const staffTeamMemberUpdateSchema = z.object({\n ...scopedUpdateFields,\n teamId: z.string().uuid().optional().nullable(),\n displayName: z.string().min(1).optional(),\n description: z.string().optional().nullable(),\n userId: z.string().uuid().optional().nullable(),\n roleIds: z.array(z.string().uuid()).optional(),\n tags: z.array(z.string().min(1)).optional(),\n availabilityRuleSetId: z.string().uuid().optional().nullable(),\n isActive: z.boolean().optional(),\n})\n\nexport const staffTeamMemberActivityCreateSchema = z.object({\n ...scopedCreateFields,\n entityId: z.string().uuid(),\n activityType: z.string().min(1).max(100),\n subject: z.string().max(200).optional(),\n body: z.string().max(8000).optional(),\n occurredAt: z.coerce.date().optional(),\n authorUserId: z.string().uuid().optional(),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n})\n\nexport const staffTeamMemberActivityUpdateSchema = z\n .object({\n id: z.string().uuid(),\n })\n .merge(staffTeamMemberActivityCreateSchema.partial())\n\nexport const staffTeamMemberJobHistoryCreateSchema = z.object({\n ...scopedCreateFields,\n entityId: z.string().uuid(),\n name: z.string().min(1).max(200),\n companyName: z.string().max(200).optional().nullable(),\n description: z.string().max(2000).optional().nullable(),\n startDate: z.coerce.date(),\n endDate: z.coerce.date().optional().nullable(),\n})\n\nexport const staffTeamMemberJobHistoryUpdateSchema = z\n .object({\n id: z.string().uuid(),\n updatedAt: optimisticUpdatedAtSchema.optional(),\n })\n .merge(staffTeamMemberJobHistoryCreateSchema.partial())\n\nexport const staffTeamMemberCommentCreateSchema = z.object({\n ...scopedCreateFields,\n entityId: z.string().uuid(),\n body: z.string().min(1).max(8000),\n authorUserId: z.string().uuid().optional(),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n})\n\nexport const staffTeamMemberCommentUpdateSchema = z\n .object({\n id: z.string().uuid(),\n })\n .merge(staffTeamMemberCommentCreateSchema.partial())\n\nexport const staffTeamMemberAddressCreateSchema = z.object({\n ...scopedCreateFields,\n entityId: z.string().uuid(),\n name: z.string().max(150).optional(),\n purpose: z.string().max(150).optional(),\n companyName: z.string().max(200).optional(),\n addressLine1: z.string().min(1).max(300),\n addressLine2: z.string().max(300).optional(),\n buildingNumber: z.string().max(50).optional(),\n flatNumber: z.string().max(50).optional(),\n city: z.string().max(150).optional(),\n region: z.string().max(150).optional(),\n postalCode: z.string().max(30).optional(),\n country: z.string().max(150).optional(),\n latitude: z.coerce.number().optional(),\n longitude: z.coerce.number().optional(),\n isPrimary: z.boolean().optional(),\n})\n\nexport const staffTeamMemberAddressUpdateSchema = z\n .object({\n id: z.string().uuid(),\n })\n .merge(staffTeamMemberAddressCreateSchema.partial())\n\nexport const staffTeamMemberTagAssignmentSchema = z.object({\n ...scopedCreateFields,\n memberId: z.string().uuid(),\n tag: z.string().min(1),\n})\n\nconst staffLeaveRequestStatusSchema = z.enum(['pending', 'approved', 'rejected'])\n\nconst validateStaffLeaveRequestDateRange = (\n value: { startDate?: Date; endDate?: Date },\n ctx: z.RefinementCtx,\n) => {\n if (!value.startDate || !value.endDate) return\n if (value.endDate < value.startDate) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'End date must be after start date.',\n path: ['endDate'],\n })\n }\n}\n\nexport const staffLeaveRequestCreateSchema = z\n .object({\n ...scopedCreateFields,\n memberId: z.string().uuid(),\n timezone: z.string().min(1),\n startDate: z.coerce.date(),\n endDate: z.coerce.date(),\n unavailabilityReasonEntryId: z.string().uuid().optional().nullable(),\n unavailabilityReasonValue: z.string().trim().min(1).max(150).optional().nullable(),\n note: z.string().max(2000).optional().nullable(),\n submittedByUserId: z.string().uuid().optional().nullable(),\n })\n .superRefine(validateStaffLeaveRequestDateRange)\n\nexport const staffLeaveRequestUpdateSchema = z\n .object({\n ...scopedUpdateFields,\n timezone: z.string().min(1).optional(),\n memberId: z.string().uuid().optional(),\n startDate: z.coerce.date().optional(),\n endDate: z.coerce.date().optional(),\n unavailabilityReasonEntryId: z.string().uuid().optional().nullable(),\n unavailabilityReasonValue: z.string().trim().min(1).max(150).optional().nullable(),\n note: z.string().max(2000).optional().nullable(),\n })\n .superRefine(validateStaffLeaveRequestDateRange)\n\nexport const staffLeaveRequestDecisionSchema = z.object({\n id: z.string().uuid(),\n decisionComment: z.string().max(2000).optional().nullable(),\n decidedByUserId: z.string().uuid().optional().nullable(),\n})\n\nexport const staffTeamMemberSelfCreateSchema = z.object({\n ...scopedCreateFields,\n displayName: z.string().min(1),\n description: z.string().max(2000).optional().nullable(),\n})\n\nexport type StaffTeamCreateInput = z.infer<typeof staffTeamCreateSchema>\nexport type StaffTeamUpdateInput = z.infer<typeof staffTeamUpdateSchema>\nexport type StaffTeamRoleCreateInput = z.infer<typeof staffTeamRoleCreateSchema>\nexport type StaffTeamRoleUpdateInput = z.infer<typeof staffTeamRoleUpdateSchema>\nexport type StaffTeamMemberCreateInput = z.infer<typeof staffTeamMemberCreateSchema>\nexport type StaffTeamMemberUpdateInput = z.infer<typeof staffTeamMemberUpdateSchema>\nexport type StaffTeamMemberTagAssignmentInput = z.infer<typeof staffTeamMemberTagAssignmentSchema>\nexport type StaffTeamMemberActivityCreateInput = z.infer<typeof staffTeamMemberActivityCreateSchema>\nexport type StaffTeamMemberActivityUpdateInput = z.infer<typeof staffTeamMemberActivityUpdateSchema>\nexport type StaffTeamMemberJobHistoryCreateInput = z.infer<typeof staffTeamMemberJobHistoryCreateSchema>\nexport type StaffTeamMemberJobHistoryUpdateInput = z.infer<typeof staffTeamMemberJobHistoryUpdateSchema>\nexport type StaffTeamMemberCommentCreateInput = z.infer<typeof staffTeamMemberCommentCreateSchema>\nexport type StaffTeamMemberCommentUpdateInput = z.infer<typeof staffTeamMemberCommentUpdateSchema>\nexport type StaffTeamMemberAddressCreateInput = z.infer<typeof staffTeamMemberAddressCreateSchema>\nexport type StaffTeamMemberAddressUpdateInput = z.infer<typeof staffTeamMemberAddressUpdateSchema>\nexport type StaffLeaveRequestStatus = z.infer<typeof staffLeaveRequestStatusSchema>\nexport type StaffLeaveRequestCreateInput = z.infer<typeof staffLeaveRequestCreateSchema>\nexport type StaffLeaveRequestUpdateInput = z.infer<typeof staffLeaveRequestUpdateSchema>\nexport type StaffLeaveRequestDecisionInput = z.infer<typeof staffLeaveRequestDecisionSchema>\nexport type StaffTeamMemberSelfCreateInput = z.infer<typeof staffTeamMemberSelfCreateSchema>\n\n// --- Timesheets validators (Phase 1) ---\n\n/**\n * EP-37: validated against the time-entry source registry rather than a literal\n * enum, so a contributed source is accepted on write the moment its module is\n * enabled. `superRefine` rather than `z.enum(...)` because the accepted set is\n * only known at call time.\n */\nconst timeEntrySourceSchema = z\n .string()\n .superRefine((value, ctx) => {\n if (hasTimeEntrySource(value)) return\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `[internal] unknown time entry source: ${value}`,\n params: { accepted: timeEntrySourceIds() },\n })\n })\nconst timeProjectStatusSchema = z.enum(['active', 'on_hold', 'completed'])\nconst timeProjectMemberStatusSchema = z.enum(['active', 'inactive'])\nconst timeEntrySegmentTypeSchema = z.enum(['work', 'break'])\nconst projectCodeSchema = z.string().min(1).max(50).regex(/^[a-zA-Z0-9-]+$/)\nconst moneyAmountSchema = z.number().min(0).max(99_999_999)\nconst timeProjectBudgetKindSchema = z.enum(['none', 'hours', 'amount'])\n\n// Upper-cased at the boundary so every writer stores canonical ISO 4217. The report\n// single-currency assertion compares codes case-sensitively, so `pln` and `PLN` would\n// otherwise read as two currencies and wrongly block a customer report.\nconst currencyCodeSchema = z.string().trim().length(3).transform((value) => value.toUpperCase())\n\n// numeric(14,4): ten integer digits, four decimals, never negative.\nconst numericAmountPattern = /^\\d{1,10}(?:\\.\\d{1,4})?$/\n\n/**\n * `numeric(14,4)` columns are surfaced by MikroORM as strings, and the project\n * form posts a typed decimal string, so the canonical representation for a stored\n * amount is a STRING end to end \u2014 a JSON number would push a 14-significant-digit\n * amount through a float on the way in. Plain numbers stay accepted for API\n * callers and are normalized to the same decimal string. (Entry-level money keeps\n * `moneyAmountSchema` above: `rate_override_amount` is consumed by the cost\n * calculator as a number, not written straight onto a numeric column.)\n */\nconst numericAmountSchema = z\n .union([z.number(), z.string()])\n .transform((value, ctx) => {\n const raw = typeof value === 'number' ? String(value) : value.trim().replace(',', '.')\n if (raw.length === 0) return null\n if (!numericAmountPattern.test(raw)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Expected a non-negative amount with at most 10 digits and 4 decimals.',\n })\n return z.NEVER\n }\n return raw\n })\n\nexport const staffTimeEntryCreateSchema = z.object({\n ...scopedCreateFields,\n staffMemberId: z.string().uuid(),\n date: z.coerce.date(),\n durationMinutes: z.number().int().min(0).max(1440),\n startedAt: z.coerce.date().optional().nullable(),\n endedAt: z.coerce.date().optional().nullable(),\n timeProjectId: z.string().uuid().optional().nullable(),\n customerId: z.string().uuid().optional().nullable(),\n dealId: z.string().uuid().optional().nullable(),\n orderId: z.string().uuid().optional().nullable(),\n notes: z.string().max(2000).optional().nullable(),\n source: timeEntrySourceSchema.optional().default('manual'),\n taskId: z.string().uuid().optional().nullable(),\n description: z.string().max(2000).optional().nullable(),\n isBillable: z.boolean().optional(),\n tagIds: z.array(z.string().uuid()).max(50).optional(),\n rateOverrideAmount: moneyAmountSchema.optional().nullable(),\n})\n\n/**\n * `startedAt` / `endedAt` mirror the create schema key for key: without them zod\n * strips the two clocks the entry form sends on every save, so correcting a start\n * or an end reported success and changed nothing. Nullable because clearing a\n * clock is a real edit, optional because omitting one must leave it alone \u2014 the\n * update command reads `undefined` as \"not part of this write\" and `null` as\n * \"clear it\". US-D3 keeps the three time fields consistent in the command, not\n * here: a request may legitimately carry all three and let the clocks win.\n */\nexport const staffTimeEntryUpdateSchema = z.object({\n ...scopedUpdateFields,\n date: z.coerce.date().optional(),\n durationMinutes: z.number().int().min(0).max(1440).optional(),\n startedAt: z.coerce.date().optional().nullable(),\n endedAt: z.coerce.date().optional().nullable(),\n timeProjectId: z.string().uuid().optional().nullable(),\n customerId: z.string().uuid().optional().nullable(),\n dealId: z.string().uuid().optional().nullable(),\n orderId: z.string().uuid().optional().nullable(),\n notes: z.string().max(2000).optional().nullable(),\n taskId: z.string().uuid().optional().nullable(),\n description: z.string().max(2000).optional().nullable(),\n isBillable: z.boolean().optional(),\n tagIds: z.array(z.string().uuid()).max(50).optional(),\n rateOverrideAmount: moneyAmountSchema.optional().nullable(),\n})\n\n/**\n * `taskId` is what makes starting a timer from a board card or the task drawer a\n * single write. Without it the surface has to start a project-level timer and\n * then PATCH the task onto it, and a failure between the two leaves a running\n * timer filed against the wrong thing.\n */\nexport const staffTimeEntryStartTimerSchema = z.object({\n ...scopedCreateFields,\n staffMemberId: z.string().uuid(),\n date: z.coerce.date(),\n timeProjectId: z.string().uuid().optional().nullable(),\n taskId: z.string().uuid().optional().nullable(),\n notes: z.string().max(2000).optional().nullable(),\n})\n\nexport const staffTimeEntryBulkItemSchema = z.object({\n id: z.string().uuid().optional().nullable(),\n date: z.coerce.date(),\n // Optional only because a task carries its project: a row naming a `taskId`\n // inherits the project from it, exactly as the single-entry path does. The\n // route refuses a row that names neither with `staff.timesheets.errors.projectRequired`,\n // so every stored row still lands on a project \u2014 the (project, date) cell the\n // lock gate addresses is never blank.\n timeProjectId: z.string().uuid().optional().nullable(),\n durationMinutes: z.number().int().min(0).max(1440),\n notes: z.string().max(2000).optional().nullable(),\n taskId: z.string().uuid().optional().nullable(),\n description: z.string().max(2000).optional().nullable(),\n isBillable: z.boolean().optional(),\n // Accepted by the schema and REFUSED by the route with 422: assigning tags\n // means dispatching the tag commands, which fork their own EntityManager and\n // cannot participate in this route's per-row transaction. Kept in the schema\n // so the refusal is explicit \u2014 dropping the key would let zod strip it and\n // restore the silent no-op.\n tagIds: z.array(z.string().uuid()).max(50).optional(),\n rateOverrideAmount: moneyAmountSchema.optional().nullable(),\n})\n\nexport const staffTimeEntryBulkSaveSchema = z.object({\n entries: z.array(staffTimeEntryBulkItemSchema).min(1).max(200),\n})\n\nexport const staffTimeEntrySegmentCreateSchema = z.object({\n ...scopedCreateFields,\n timeEntryId: z.string().uuid(),\n startedAt: z.coerce.date(),\n endedAt: z.coerce.date().optional().nullable(),\n segmentType: timeEntrySegmentTypeSchema.optional().default('work'),\n})\n\nexport const staffTimeEntrySegmentUpdateSchema = z.object({\n ...scopedUpdateFields,\n startedAt: z.coerce.date().optional(),\n endedAt: z.coerce.date().optional().nullable(),\n segmentType: timeEntrySegmentTypeSchema.optional(),\n})\n\nexport const staffTimeProjectCreateSchema = z.object({\n ...scopedCreateFields,\n name: z.string().min(1).max(255),\n // D-9 / US-B1: time is organised per customer, so a new project always names one.\n // Rows created before this change keep their null customer and stay editable\n // (see the update schema below), which is why only create is constrained.\n customerId: z.string().uuid(),\n customerSnapshot: z.record(z.string(), z.unknown()).optional().nullable(),\n code: projectCodeSchema,\n description: z.string().max(2000).optional().nullable(),\n projectType: z.string().max(100).optional().nullable(),\n color: projectColorSchema.optional().nullable(),\n status: timeProjectStatusSchema.optional().default('active'),\n ownerUserId: z.string().uuid().optional().nullable(),\n costCenter: z.string().max(100).optional().nullable(),\n startDate: z.coerce.date().optional().nullable(),\n hourlyRate: numericAmountSchema.optional().nullable(),\n // D-3: the currency may be chosen once, at creation. Every later change goes\n // through `POST .../change-currency`, which carries the non-conversion\n // acknowledgement and refuses while entries sit frozen in a closed report.\n currencyCode: currencyCodeSchema.optional().nullable(),\n billableByDefault: z.boolean().optional(),\n budgetKind: timeProjectBudgetKindSchema.optional().default('none'),\n budgetValue: numericAmountSchema.optional().nullable(),\n budgetWarnAtPercent: z.number().int().min(1).max(100).optional(),\n})\n\n/**\n * Deliberately has NO `currencyCode`: D-3 routes every post-creation currency\n * change through the dedicated change-currency action, so a plain PUT that\n * carries the key has it stripped here rather than relabelling the project\n * behind the acknowledgement and the locked-entry check.\n */\nexport const staffTimeProjectUpdateSchema = z.object({\n ...scopedUpdateFields,\n name: z.string().min(1).max(255).optional(),\n customerId: z.string().uuid().optional().nullable(),\n customerSnapshot: z.record(z.string(), z.unknown()).optional().nullable(),\n code: projectCodeSchema.optional(),\n description: z.string().max(2000).optional().nullable(),\n projectType: z.string().max(100).optional().nullable(),\n color: projectColorSchema.optional().nullable(),\n status: timeProjectStatusSchema.optional(),\n ownerUserId: z.string().uuid().optional().nullable(),\n costCenter: z.string().max(100).optional().nullable(),\n startDate: z.coerce.date().optional().nullable(),\n hourlyRate: numericAmountSchema.optional().nullable(),\n billableByDefault: z.boolean().optional(),\n budgetKind: timeProjectBudgetKindSchema.optional(),\n budgetValue: numericAmountSchema.optional().nullable(),\n budgetWarnAtPercent: z.number().int().min(1).max(100).optional(),\n defaultAssigneeStaffMemberId: z.string().uuid().optional().nullable(),\n})\n\nexport const staffTimeProjectMemberAssignSchema = z.object({\n ...scopedCreateFields,\n timeProjectId: z.string().uuid(),\n staffMemberId: z.string().uuid(),\n role: z.string().max(100).optional().nullable(),\n status: timeProjectMemberStatusSchema.optional().default('active'),\n assignedStartDate: z.coerce.date(),\n assignedEndDate: z.coerce.date().optional().nullable(),\n isAssigner: z.boolean().optional(),\n})\n\nexport const staffTimeProjectMemberUpdateSchema = z.object({\n ...scopedUpdateFields,\n role: z.string().max(100).optional().nullable(),\n status: timeProjectMemberStatusSchema.optional(),\n assignedEndDate: z.coerce.date().optional().nullable(),\n isAssigner: z.boolean().optional(),\n})\n\nexport const staffMyProjectVisibilityUpdateSchema = z.object({\n showInGrid: z.boolean(),\n})\n\nexport type StaffTimeEntryCreateInput = z.infer<typeof staffTimeEntryCreateSchema>\nexport type StaffTimeEntryUpdateInput = z.infer<typeof staffTimeEntryUpdateSchema>\nexport type StaffTimeEntryStartTimerInput = z.infer<typeof staffTimeEntryStartTimerSchema>\nexport type StaffTimeEntryBulkSaveInput = z.infer<typeof staffTimeEntryBulkSaveSchema>\nexport type StaffTimeEntrySegmentCreateInput = z.infer<typeof staffTimeEntrySegmentCreateSchema>\nexport type StaffTimeEntrySegmentUpdateInput = z.infer<typeof staffTimeEntrySegmentUpdateSchema>\nexport type StaffTimeProjectCreateInput = z.infer<typeof staffTimeProjectCreateSchema>\nexport type StaffTimeProjectUpdateInput = z.infer<typeof staffTimeProjectUpdateSchema>\nexport type StaffTimeProjectMemberAssignInput = z.infer<typeof staffTimeProjectMemberAssignSchema>\nexport type StaffTimeProjectMemberUpdateInput = z.infer<typeof staffTimeProjectMemberUpdateSchema>\nexport type StaffMyProjectVisibilityUpdateInput = z.infer<typeof staffMyProjectVisibilityUpdateSchema>\n\n// --- Time tracking consulting suite validators (tasks, tags, reports, settings) ---\n\nconst timeSlugSchema = z.string().trim().min(1).max(60).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/)\nconst timeReportPeriodKindSchema = z.enum(['week', 'month', 'year', 'custom'])\n/** EP-36: validated against the report grouping registry, not a literal enum. */\nconst timeReportGroupingSchema = z\n .string()\n .superRefine((value, ctx) => {\n if (hasReportGrouping(value)) return\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `[internal] unknown report grouping: ${value}`,\n params: { accepted: reportGroupingIds() },\n })\n })\nconst timeReportNonbillableModeSchema = z.enum(['separate', 'exclude'])\nconst timeRoundingDirectionSchema = timeTrackingRoundingDirectionSchema\nconst timeRoundingUnitMinutesSchema = timeTrackingRoundingUnitMinutesSchema\nconst positionSchema = z.number().int().min(0).max(1_000_000)\n\nexport const staffTimeTaskStatusCreateSchema = z.object({\n ...scopedCreateFields,\n timeProjectId: z.string().uuid(),\n name: z.string().trim().min(1).max(100),\n slug: timeSlugSchema.optional(),\n color: projectColorSchema.optional().nullable(),\n position: positionSchema.optional(),\n isDefault: z.boolean().optional(),\n isDone: z.boolean().optional(),\n})\n\nexport const staffTimeTaskStatusUpdateSchema = z.object({\n ...scopedUpdateFields,\n name: z.string().trim().min(1).max(100).optional(),\n color: projectColorSchema.optional().nullable(),\n position: positionSchema.optional(),\n isDefault: z.boolean().optional(),\n isDone: z.boolean().optional(),\n})\n\nexport const staffTimeTaskStatusReorderSchema = z.object({\n statuses: z\n .array(\n z.object({\n id: z.string().uuid(),\n position: positionSchema,\n }),\n )\n .min(1)\n .max(100),\n})\n\nexport const staffTimeTaskCreateSchema = z.object({\n ...scopedCreateFields,\n timeProjectId: z.string().uuid(),\n parentTaskId: z.string().uuid().optional().nullable(),\n taskStatusId: z.string().uuid().optional().nullable(),\n title: z.string().trim().min(1).max(255),\n description: z.string().max(8000).optional().nullable(),\n assigneeStaffMemberId: z.string().uuid().optional().nullable(),\n position: positionSchema.optional(),\n tagIds: z.array(z.string().uuid()).max(50).optional(),\n})\n\nexport const staffTimeTaskUpdateSchema = z.object({\n ...scopedUpdateFields,\n parentTaskId: z.string().uuid().optional().nullable(),\n taskStatusId: z.string().uuid().optional(),\n title: z.string().trim().min(1).max(255).optional(),\n description: z.string().max(8000).optional().nullable(),\n assigneeStaffMemberId: z.string().uuid().optional().nullable(),\n position: positionSchema.optional(),\n tagIds: z.array(z.string().uuid()).max(50).optional(),\n})\n\nexport const staffTimeTaskStatusChangeSchema = z.object({\n taskStatusId: z.string().uuid(),\n position: positionSchema.optional(),\n})\n\nexport const staffTimeTaskCommentCreateSchema = z.object({\n ...scopedCreateFields,\n taskId: z.string().uuid(),\n body: z.string().trim().min(1).max(5000),\n authorUserId: z.string().uuid().optional().nullable(),\n visibility: z.enum(['internal', 'customer']).optional(),\n})\n\nexport const staffTimeTaskCommentUpdateSchema = z.object({\n ...scopedUpdateFields,\n body: z.string().trim().min(1).max(5000),\n visibility: z.enum(['internal', 'customer']).optional(),\n})\n\nexport const staffTimeTaskCommentUpdateRequestSchema = staffTimeTaskCommentUpdateSchema\n .extend({\n body: z.string().trim().min(1).max(5000).optional(),\n })\n .refine((value) => value.body !== undefined || value.visibility !== undefined, {\n message: 'body or visibility is required',\n path: ['body'],\n })\n\nexport const staffTimeTagCreateSchema = z.object({\n ...scopedCreateFields,\n slug: timeSlugSchema,\n label: z.string().trim().min(1).max(100),\n color: projectColorSchema.optional().nullable(),\n})\n\nexport const staffTimeTaskTagAssignmentSchema = z.object({\n ...scopedCreateFields,\n taskId: z.string().uuid(),\n tagIds: z.array(z.string().uuid()).max(50),\n})\n\nexport const staffTimeEntryTagAssignmentSchema = z.object({\n ...scopedCreateFields,\n timeEntryId: z.string().uuid(),\n tagIds: z.array(z.string().uuid()).max(50),\n})\n\nconst validateStaffTimeReportPeriod = (\n value: { periodFrom?: Date; periodTo?: Date },\n ctx: z.RefinementCtx,\n) => {\n if (!value.periodFrom || !value.periodTo) return\n if (value.periodTo < value.periodFrom) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Period end must be after period start.',\n path: ['periodTo'],\n })\n }\n}\n\nexport const staffTimeReportCreateSchema = z\n .object({\n ...scopedCreateFields,\n customerId: z.string().uuid(),\n title: z.string().trim().min(1).max(255),\n periodKind: timeReportPeriodKindSchema,\n periodFrom: z.coerce.date(),\n periodTo: z.coerce.date(),\n grouping: timeReportGroupingSchema.optional().default('project_task'),\n nonbillableMode: timeReportNonbillableModeSchema.optional().default('separate'),\n includeAlreadyReported: z.boolean().optional().default(false),\n showRates: z.boolean().optional().default(true),\n timeProjectIds: z.array(z.string().uuid()).min(1).max(100),\n })\n .superRefine(validateStaffTimeReportPeriod)\n\nexport const staffTimeReportUpdateSchema = z\n .object({\n ...scopedUpdateFields,\n customerId: z.string().uuid().optional(),\n title: z.string().trim().min(1).max(255).optional(),\n periodKind: timeReportPeriodKindSchema.optional(),\n periodFrom: z.coerce.date().optional(),\n periodTo: z.coerce.date().optional(),\n grouping: timeReportGroupingSchema.optional(),\n nonbillableMode: timeReportNonbillableModeSchema.optional(),\n includeAlreadyReported: z.boolean().optional(),\n showRates: z.boolean().optional(),\n timeProjectIds: z.array(z.string().uuid()).min(1).max(100).optional(),\n })\n .superRefine(validateStaffTimeReportPeriod)\n\nexport const staffTimeReportPreviewSchema = z\n .object({\n customerId: z.string().uuid().optional().nullable(),\n periodKind: timeReportPeriodKindSchema.optional().default('custom'),\n periodFrom: z.coerce.date(),\n periodTo: z.coerce.date(),\n grouping: timeReportGroupingSchema.optional().default('project_task'),\n nonbillableMode: timeReportNonbillableModeSchema.optional().default('separate'),\n includeAlreadyReported: z.boolean().optional().default(false),\n showRates: z.boolean().optional().default(true),\n timeProjectIds: z.array(z.string().uuid()).min(1).max(100),\n })\n .superRefine(validateStaffTimeReportPeriod)\n\nexport const staffTimeReportCloseSchema = z.object({\n id: z.string().uuid(),\n})\n\nexport const staffTimeReportUnlockSchema = z.object({\n id: z.string().uuid(),\n reason: z.string().trim().min(1).max(2000),\n})\n\nexport const staffTimeProjectChangeCurrencySchema = z.object({\n currencyCode: currencyCodeSchema,\n acknowledged: z.literal(true),\n})\n\n/**\n * EP-42 \u2014 built from the setting-key registry rather than a literal, so a module can\n * contribute a key without patching this file. With no contribution the shape is the\n * eight built-in keys in their five groups, exactly as it was.\n *\n * This constant is evaluated once at module load. A key registered later still\n * validates on the wire because the settings route parses with\n * `buildTimeTrackingSettingsSchema()` per request and publishes it through an\n * OpenAPI getter.\n */\nexport const staffTimeTrackingSettingsSchema = buildTimeTrackingSettingsSchema()\n\nexport type StaffTimeReportPeriodKind = z.infer<typeof timeReportPeriodKindSchema>\nexport type StaffTimeReportGrouping = z.infer<typeof timeReportGroupingSchema>\nexport type StaffTimeReportNonbillableMode = z.infer<typeof timeReportNonbillableModeSchema>\nexport type StaffTimeRoundingDirection = z.infer<typeof timeRoundingDirectionSchema>\nexport type StaffTimeRoundingUnitMinutes = z.infer<typeof timeRoundingUnitMinutesSchema>\nexport type StaffTimeTaskStatusCreateInput = z.infer<typeof staffTimeTaskStatusCreateSchema>\nexport type StaffTimeTaskStatusUpdateInput = z.infer<typeof staffTimeTaskStatusUpdateSchema>\nexport type StaffTimeTaskStatusReorderInput = z.infer<typeof staffTimeTaskStatusReorderSchema>\nexport type StaffTimeTaskCreateInput = z.infer<typeof staffTimeTaskCreateSchema>\nexport type StaffTimeTaskUpdateInput = z.infer<typeof staffTimeTaskUpdateSchema>\nexport type StaffTimeTaskStatusChangeInput = z.infer<typeof staffTimeTaskStatusChangeSchema>\nexport type StaffTimeTaskCommentCreateInput = z.infer<typeof staffTimeTaskCommentCreateSchema>\nexport type StaffTimeTaskCommentUpdateInput = z.infer<typeof staffTimeTaskCommentUpdateSchema>\nexport type StaffTimeTaskCommentUpdateRequestInput = z.infer<typeof staffTimeTaskCommentUpdateRequestSchema>\nexport type StaffTimeTagCreateInput = z.infer<typeof staffTimeTagCreateSchema>\nexport type StaffTimeTaskTagAssignmentInput = z.infer<typeof staffTimeTaskTagAssignmentSchema>\nexport type StaffTimeEntryTagAssignmentInput = z.infer<typeof staffTimeEntryTagAssignmentSchema>\nexport type StaffTimeReportCreateInput = z.infer<typeof staffTimeReportCreateSchema>\nexport type StaffTimeReportUpdateInput = z.infer<typeof staffTimeReportUpdateSchema>\nexport type StaffTimeReportPreviewInput = z.infer<typeof staffTimeReportPreviewSchema>\nexport type StaffTimeReportCloseInput = z.infer<typeof staffTimeReportCloseSchema>\nexport type StaffTimeReportUnlockInput = z.infer<typeof staffTimeReportUnlockSchema>\nexport type StaffTimeProjectChangeCurrencyInput = z.infer<typeof staffTimeProjectChangeCurrencySchema>\nexport type StaffTimeTrackingSettingsInput = z.infer<typeof staffTimeTrackingSettingsSchema>\n\nexport const staffSupportRoutingRuleCreateSchema = z.object({\n ...scopedCreateFields,\n categoryValue: z.string().trim().min(1).max(150).optional().nullable(),\n timeProjectId: z.string().uuid(),\n isActive: z.boolean().optional().default(true),\n})\n\nexport const staffSupportRoutingRuleUpdateSchema = z.object({\n ...scopedUpdateFields,\n timeProjectId: z.string().uuid().optional(),\n isActive: z.boolean().optional(),\n})\n\nexport const staffSupportFallbackProjectCreateSchema = z.object({\n ...scopedCreateFields,\n})\n\nexport type StaffSupportRoutingRuleCreateInput = z.infer<typeof staffSupportRoutingRuleCreateSchema>\nexport type StaffSupportRoutingRuleUpdateInput = z.infer<typeof staffSupportRoutingRuleUpdateSchema>\nexport type StaffSupportFallbackProjectCreateInput = z.infer<typeof staffSupportFallbackProjectCreateSchema>\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -6,6 +6,12 @@ const defaultEncryptionMaps = [
6
6
  { field: "decision_comment" },
7
7
  { field: "unavailability_reason_value" }
8
8
  ]
9
+ },
10
+ {
11
+ entityId: "staff:staff_support_ticket",
12
+ fields: [
13
+ { field: "customer_request_snapshot" }
14
+ ]
9
15
  }
10
16
  ];
11
17
  var encryption_default = defaultEncryptionMaps;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/staff/encryption.ts"],
4
- "sourcesContent": ["import type { ModuleEncryptionMap } from '@open-mercato/shared/modules/encryption'\n\nexport const defaultEncryptionMaps: ModuleEncryptionMap[] = [\n {\n entityId: 'staff:staff_leave_request',\n fields: [\n { field: 'note' },\n { field: 'decision_comment' },\n { field: 'unavailability_reason_value' },\n ],\n },\n]\n\nexport default defaultEncryptionMaps\n"],
5
- "mappings": "AAEO,MAAM,wBAA+C;AAAA,EAC1D;AAAA,IACE,UAAU;AAAA,IACV,QAAQ;AAAA,MACN,EAAE,OAAO,OAAO;AAAA,MAChB,EAAE,OAAO,mBAAmB;AAAA,MAC5B,EAAE,OAAO,8BAA8B;AAAA,IACzC;AAAA,EACF;AACF;AAEA,IAAO,qBAAQ;",
4
+ "sourcesContent": ["import type { ModuleEncryptionMap } from '@open-mercato/shared/modules/encryption'\n\nexport const defaultEncryptionMaps: ModuleEncryptionMap[] = [\n {\n entityId: 'staff:staff_leave_request',\n fields: [\n { field: 'note' },\n { field: 'decision_comment' },\n { field: 'unavailability_reason_value' },\n ],\n },\n {\n entityId: 'staff:staff_support_ticket',\n fields: [\n { field: 'customer_request_snapshot' },\n ],\n },\n]\n\nexport default defaultEncryptionMaps\n"],
5
+ "mappings": "AAEO,MAAM,wBAA+C;AAAA,EAC1D;AAAA,IACE,UAAU;AAAA,IACV,QAAQ;AAAA,MACN,EAAE,OAAO,OAAO;AAAA,MAChB,EAAE,OAAO,mBAAmB;AAAA,MAC5B,EAAE,OAAO,8BAA8B;AAAA,IACzC;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,QAAQ;AAAA,MACN,EAAE,OAAO,4BAA4B;AAAA,IACvC;AAAA,EACF;AACF;AAEA,IAAO,qBAAQ;",
6
6
  "names": []
7
7
  }
@@ -41,6 +41,7 @@ const events = [
41
41
  { id: "staff.timesheets.time_task.updated", label: "Time Task Updated", entity: "time_task", category: "crud" },
42
42
  { id: "staff.timesheets.time_task.deleted", label: "Time Task Deleted", entity: "time_task", category: "crud" },
43
43
  { id: "staff.timesheets.time_task.status_changed", label: "Time Task Status Changed", entity: "time_task", category: "lifecycle", clientBroadcast: true },
44
+ { id: "staff.timesheets.time_task.assignee_changed", label: "Time Task Assignee Changed", entity: "time_task", category: "lifecycle", clientBroadcast: true },
44
45
  { id: "staff.timesheets.time_task_status.created", label: "Time Task Status Created", entity: "time_task_status", category: "crud" },
45
46
  { id: "staff.timesheets.time_task_status.updated", label: "Time Task Status Updated", entity: "time_task_status", category: "crud" },
46
47
  { id: "staff.timesheets.time_task_status.deleted", label: "Time Task Status Deleted", entity: "time_task_status", category: "crud" },
@@ -113,6 +114,30 @@ const events = [
113
114
  category: "lifecycle",
114
115
  portalBroadcast: true,
115
116
  excludeFromTriggers: true
117
+ },
118
+ // Customer support tickets. `created` and `customer_replied` name the customer, so
119
+ // they stay server-side; `activity_recorded` carries ids only and is what open
120
+ // backoffice screens refetch on. `portal_updated` is emitted only by
121
+ // `lib/support/portalBroadcast.ts` (driven by the `subscribers/support-portal-*.ts`
122
+ // subscribers), always with the ticket's own customer users pinned in
123
+ // `recipientUserIds`, and never when that list is empty.
124
+ { id: "staff.support_ticket.created", label: "Support Ticket Created", entity: "support_ticket", category: "lifecycle" },
125
+ { id: "staff.support_ticket.customer_replied", label: "Support Ticket Customer Replied", entity: "support_ticket", category: "lifecycle" },
126
+ {
127
+ id: "staff.support_ticket.activity_recorded",
128
+ label: "Support Ticket Activity Recorded",
129
+ entity: "support_ticket",
130
+ category: "lifecycle",
131
+ clientBroadcast: true,
132
+ excludeFromTriggers: true
133
+ },
134
+ {
135
+ id: "staff.support_ticket.portal_updated",
136
+ label: "Support Ticket Updated For Portal",
137
+ entity: "support_ticket",
138
+ category: "lifecycle",
139
+ portalBroadcast: true,
140
+ excludeFromTriggers: true
116
141
  }
117
142
  ];
118
143
  const eventsConfig = createModuleEvents({
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/staff/events.ts"],
4
- "sourcesContent": ["import { createModuleEvents } from '@open-mercato/shared/modules/events'\n\nconst events = [\n { id: 'staff.team.created', label: 'Team Created', entity: 'team', category: 'crud' },\n { id: 'staff.team.updated', label: 'Team Updated', entity: 'team', category: 'crud' },\n { id: 'staff.team.deleted', label: 'Team Deleted', entity: 'team', category: 'crud' },\n { id: 'staff.team_role.created', label: 'Team Role Created', entity: 'team_role', category: 'crud' },\n { id: 'staff.team_role.updated', label: 'Team Role Updated', entity: 'team_role', category: 'crud' },\n { id: 'staff.team_role.deleted', label: 'Team Role Deleted', entity: 'team_role', category: 'crud' },\n { id: 'staff.team_member.created', label: 'Team Member Created', entity: 'team_member', category: 'crud' },\n { id: 'staff.team_member.updated', label: 'Team Member Updated', entity: 'team_member', category: 'crud' },\n { id: 'staff.team_member.deleted', label: 'Team Member Deleted', entity: 'team_member', category: 'crud' },\n { id: 'staff.leave_request.created', label: 'Leave Request Created', entity: 'leave_request', category: 'crud' },\n { id: 'staff.leave_request.updated', label: 'Leave Request Updated', entity: 'leave_request', category: 'crud' },\n { id: 'staff.leave_request.deleted', label: 'Leave Request Deleted', entity: 'leave_request', category: 'crud' },\n { id: 'staff.address.created', label: 'Staff Address Created', entity: 'address', category: 'crud' },\n { id: 'staff.address.updated', label: 'Staff Address Updated', entity: 'address', category: 'crud' },\n { id: 'staff.address.deleted', label: 'Staff Address Deleted', entity: 'address', category: 'crud' },\n { id: 'staff.comment.created', label: 'Staff Comment Created', entity: 'comment', category: 'crud' },\n { id: 'staff.comment.updated', label: 'Staff Comment Updated', entity: 'comment', category: 'crud' },\n { id: 'staff.comment.deleted', label: 'Staff Comment Deleted', entity: 'comment', category: 'crud' },\n { id: 'staff.activity.created', label: 'Staff Activity Created', entity: 'activity', category: 'crud' },\n { id: 'staff.activity.updated', label: 'Staff Activity Updated', entity: 'activity', category: 'crud' },\n { id: 'staff.activity.deleted', label: 'Staff Activity Deleted', entity: 'activity', category: 'crud' },\n { id: 'staff.job_history.created', label: 'Job History Created', entity: 'job_history', category: 'crud' },\n { id: 'staff.job_history.updated', label: 'Job History Updated', entity: 'job_history', category: 'crud' },\n { id: 'staff.job_history.deleted', label: 'Job History Deleted', entity: 'job_history', category: 'crud' },\n\n // Timesheets (Phase 1)\n { id: 'staff.timesheets.time_entry.created', label: 'Time Entry Created', entity: 'time_entry', category: 'crud', clientBroadcast: true },\n { id: 'staff.timesheets.time_entry.updated', label: 'Time Entry Updated', entity: 'time_entry', category: 'crud', clientBroadcast: true },\n { id: 'staff.timesheets.time_entry.deleted', label: 'Time Entry Deleted', entity: 'time_entry', category: 'crud', clientBroadcast: true },\n { id: 'staff.timesheets.time_entry.timer_started', label: 'Timer Started', entity: 'time_entry', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_entry.timer_stopped', label: 'Timer Stopped', entity: 'time_entry', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_project.created', label: 'Time Project Created', entity: 'time_project', category: 'crud' },\n { id: 'staff.timesheets.time_project.updated', label: 'Time Project Updated', entity: 'time_project', category: 'crud' },\n { id: 'staff.timesheets.time_project.deleted', label: 'Time Project Deleted', entity: 'time_project', category: 'crud' },\n { id: 'staff.timesheets.time_project_member.created', label: 'Time Project Member Assigned', entity: 'time_project_member', category: 'crud' },\n { id: 'staff.timesheets.time_project_member.updated', label: 'Time Project Member Updated', entity: 'time_project_member', category: 'crud' },\n { id: 'staff.timesheets.time_project_member.deleted', label: 'Time Project Member Unassigned', entity: 'time_project_member', category: 'crud' },\n\n // Time tracking (Phase 2)\n { id: 'staff.timesheets.time_task.created', label: 'Time Task Created', entity: 'time_task', category: 'crud' },\n { id: 'staff.timesheets.time_task.updated', label: 'Time Task Updated', entity: 'time_task', category: 'crud' },\n { id: 'staff.timesheets.time_task.deleted', label: 'Time Task Deleted', entity: 'time_task', category: 'crud' },\n { id: 'staff.timesheets.time_task.status_changed', label: 'Time Task Status Changed', entity: 'time_task', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_task_status.created', label: 'Time Task Status Created', entity: 'time_task_status', category: 'crud' },\n { id: 'staff.timesheets.time_task_status.updated', label: 'Time Task Status Updated', entity: 'time_task_status', category: 'crud' },\n { id: 'staff.timesheets.time_task_status.deleted', label: 'Time Task Status Deleted', entity: 'time_task_status', category: 'crud' },\n { id: 'staff.timesheets.time_tag.created', label: 'Time Tag Created', entity: 'time_tag', category: 'crud' },\n { id: 'staff.timesheets.time_tag.updated', label: 'Time Tag Updated', entity: 'time_tag', category: 'crud' },\n { id: 'staff.timesheets.time_tag.deleted', label: 'Time Tag Deleted', entity: 'time_tag', category: 'crud' },\n { id: 'staff.timesheets.time_task_comment.created', label: 'Time Task Comment Created', entity: 'time_task_comment', category: 'crud' },\n { id: 'staff.timesheets.time_task_comment.updated', label: 'Time Task Comment Updated', entity: 'time_task_comment', category: 'crud' },\n { id: 'staff.timesheets.time_task_comment.deleted', label: 'Time Task Comment Deleted', entity: 'time_task_comment', category: 'crud' },\n { id: 'staff.timesheets.time_report.created', label: 'Time Report Created', entity: 'time_report', category: 'crud' },\n { id: 'staff.timesheets.time_report.updated', label: 'Time Report Updated', entity: 'time_report', category: 'crud' },\n { id: 'staff.timesheets.time_report.deleted', label: 'Time Report Deleted', entity: 'time_report', category: 'crud' },\n { id: 'staff.timesheets.time_report.closed', label: 'Time Report Closed', entity: 'time_report', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_report.unlocked', label: 'Time Report Unlocked', entity: 'time_report', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_project.budget_threshold_reached', label: 'Time Project Budget Threshold Reached', entity: 'time_project', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.project_access.requested', label: 'Time Project Access Requested', entity: 'time_project', category: 'lifecycle' },\n\n // `clientBroadcast: true` above puts the event on the DOM Event Bridge, whose only\n // audience filter is tenant + organization (`events/api/stream/route.ts`): every\n // signed-in user of the organization receives the payload, with no feature check.\n // So a broadcast payload MUST NOT carry a rate, a cost or an amount \u2014 money is\n // gated on `staff.timesheets.rates.view` (staff/AGENTS.md), a gate SSE cannot\n // apply. `time_report.closed` and `time_project.budget_threshold_reached` emit\n // their money fields conditionally for exactly this reason; see their emitters.\n //\n // Money is not the only thing that audience decides. The same absence of a feature\n // check is why `time_report.unlocked` broadcasts no `reason` \u2014 the operator's\n // mandatory, free-text unlock justification, which lives on the audit row instead \u2014\n // and why `time_report.closed` broadcasts no `customerId`.\n\n // Time tracking (Phase 3) \u2014 transitions owned by the hand-rolled routes that sit\n // beside the CRUD factory resources. Declared here so a third-party module can\n // subscribe to a bulk grid save, a copy, a segment edit, an export or a settings\n // change with the same contract the CRUD ids already offer.\n { id: 'staff.timesheets.time_entry.bulk_updated', label: 'Time Entries Bulk Saved', entity: 'time_entry', category: 'lifecycle' },\n { id: 'staff.timesheets.time_entry.copied', label: 'Time Entry Copied', entity: 'time_entry', category: 'lifecycle' },\n { id: 'staff.timesheets.time_entry.locked', label: 'Time Entries Locked', entity: 'time_entry', category: 'lifecycle' },\n { id: 'staff.timesheets.time_entry.unlocked', label: 'Time Entries Unlocked', entity: 'time_entry', category: 'lifecycle' },\n { id: 'staff.timesheets.time_entry_segment.created', label: 'Time Entry Segment Created', entity: 'time_entry_segment', category: 'crud' },\n { id: 'staff.timesheets.time_entry_segment.updated', label: 'Time Entry Segment Updated', entity: 'time_entry_segment', category: 'crud' },\n { id: 'staff.timesheets.time_entry_segment.deleted', label: 'Time Entry Segment Deleted', entity: 'time_entry_segment', category: 'crud' },\n { id: 'staff.timesheets.time_report.exported', label: 'Time Report Exported', entity: 'time_report', category: 'lifecycle' },\n { id: 'staff.timesheets.time_project.currency_changed', label: 'Time Project Currency Changed', entity: 'time_project', category: 'lifecycle' },\n { id: 'staff.timesheets.time_project_access.granted', label: 'Time Project Access Granted', entity: 'time_project', category: 'lifecycle' },\n { id: 'staff.timesheets.time_project_access.denied', label: 'Time Project Access Denied', entity: 'time_project', category: 'lifecycle' },\n { id: 'staff.timesheets.time_tracking.settings_updated', label: 'Time Tracking Settings Updated', entity: 'time_tracking', category: 'lifecycle' },\n { id: 'staff.timesheets.time_tracking.rounding_reapplied', label: 'Time Tracking Rounding Reapplied', entity: 'time_tracking', category: 'lifecycle' },\n\n // Time tracking (Phase 6) \u2014 the customer-portal bridge (EP-06 / EP-50).\n //\n // This is a SEPARATE id rather than `portalBroadcast: true` on\n // `time_report.closed`, and the difference is a disclosure, not a style choice.\n // The portal SSE stream (`customer_accounts/api/portal/events/stream.ts`)\n // filters a broadcast by tenant + organization and narrows to specific people\n // only when the payload carries `recipientUserId(s)`. One organization serves\n // many customers, so flagging `time_report.closed` \u2014 which carries `reference`\n // and the minute totals \u2014 would hand every client of the tenant a running feed\n // of every other client's reports. `time_report.closed` also has\n // `clientBroadcast: true` and a published webhook payload, so it cannot be\n // narrowed without breaking its backoffice consumers.\n //\n // `subscribers/time-report-portal-broadcast.ts` is the only emitter: it pins\n // `recipientUserIds` to the portal users of the report's own customer and does\n // not emit at all when that list is empty \u2014 the rule\n // `warranty_claims/AGENTS.md` states for its own portal event.\n //\n // Exports are deliberately not mirrored. An export changes nothing the portal\n // renders; the portal reads the report, not the file.\n {\n id: 'staff.timesheets.time_report.portal_published',\n label: 'Time Report Published To Portal',\n entity: 'time_report',\n category: 'lifecycle',\n portalBroadcast: true,\n excludeFromTriggers: true,\n },\n] as const\n\nexport const eventsConfig = createModuleEvents({\n moduleId: 'staff',\n events,\n})\n\nexport const emitStaffEvent = eventsConfig.emit\n\nexport type StaffEventId = typeof events[number]['id']\n\nexport default eventsConfig\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { createModuleEvents } from '@open-mercato/shared/modules/events'\n\nconst events = [\n { id: 'staff.team.created', label: 'Team Created', entity: 'team', category: 'crud' },\n { id: 'staff.team.updated', label: 'Team Updated', entity: 'team', category: 'crud' },\n { id: 'staff.team.deleted', label: 'Team Deleted', entity: 'team', category: 'crud' },\n { id: 'staff.team_role.created', label: 'Team Role Created', entity: 'team_role', category: 'crud' },\n { id: 'staff.team_role.updated', label: 'Team Role Updated', entity: 'team_role', category: 'crud' },\n { id: 'staff.team_role.deleted', label: 'Team Role Deleted', entity: 'team_role', category: 'crud' },\n { id: 'staff.team_member.created', label: 'Team Member Created', entity: 'team_member', category: 'crud' },\n { id: 'staff.team_member.updated', label: 'Team Member Updated', entity: 'team_member', category: 'crud' },\n { id: 'staff.team_member.deleted', label: 'Team Member Deleted', entity: 'team_member', category: 'crud' },\n { id: 'staff.leave_request.created', label: 'Leave Request Created', entity: 'leave_request', category: 'crud' },\n { id: 'staff.leave_request.updated', label: 'Leave Request Updated', entity: 'leave_request', category: 'crud' },\n { id: 'staff.leave_request.deleted', label: 'Leave Request Deleted', entity: 'leave_request', category: 'crud' },\n { id: 'staff.address.created', label: 'Staff Address Created', entity: 'address', category: 'crud' },\n { id: 'staff.address.updated', label: 'Staff Address Updated', entity: 'address', category: 'crud' },\n { id: 'staff.address.deleted', label: 'Staff Address Deleted', entity: 'address', category: 'crud' },\n { id: 'staff.comment.created', label: 'Staff Comment Created', entity: 'comment', category: 'crud' },\n { id: 'staff.comment.updated', label: 'Staff Comment Updated', entity: 'comment', category: 'crud' },\n { id: 'staff.comment.deleted', label: 'Staff Comment Deleted', entity: 'comment', category: 'crud' },\n { id: 'staff.activity.created', label: 'Staff Activity Created', entity: 'activity', category: 'crud' },\n { id: 'staff.activity.updated', label: 'Staff Activity Updated', entity: 'activity', category: 'crud' },\n { id: 'staff.activity.deleted', label: 'Staff Activity Deleted', entity: 'activity', category: 'crud' },\n { id: 'staff.job_history.created', label: 'Job History Created', entity: 'job_history', category: 'crud' },\n { id: 'staff.job_history.updated', label: 'Job History Updated', entity: 'job_history', category: 'crud' },\n { id: 'staff.job_history.deleted', label: 'Job History Deleted', entity: 'job_history', category: 'crud' },\n\n // Timesheets (Phase 1)\n { id: 'staff.timesheets.time_entry.created', label: 'Time Entry Created', entity: 'time_entry', category: 'crud', clientBroadcast: true },\n { id: 'staff.timesheets.time_entry.updated', label: 'Time Entry Updated', entity: 'time_entry', category: 'crud', clientBroadcast: true },\n { id: 'staff.timesheets.time_entry.deleted', label: 'Time Entry Deleted', entity: 'time_entry', category: 'crud', clientBroadcast: true },\n { id: 'staff.timesheets.time_entry.timer_started', label: 'Timer Started', entity: 'time_entry', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_entry.timer_stopped', label: 'Timer Stopped', entity: 'time_entry', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_project.created', label: 'Time Project Created', entity: 'time_project', category: 'crud' },\n { id: 'staff.timesheets.time_project.updated', label: 'Time Project Updated', entity: 'time_project', category: 'crud' },\n { id: 'staff.timesheets.time_project.deleted', label: 'Time Project Deleted', entity: 'time_project', category: 'crud' },\n { id: 'staff.timesheets.time_project_member.created', label: 'Time Project Member Assigned', entity: 'time_project_member', category: 'crud' },\n { id: 'staff.timesheets.time_project_member.updated', label: 'Time Project Member Updated', entity: 'time_project_member', category: 'crud' },\n { id: 'staff.timesheets.time_project_member.deleted', label: 'Time Project Member Unassigned', entity: 'time_project_member', category: 'crud' },\n\n // Time tracking (Phase 2)\n { id: 'staff.timesheets.time_task.created', label: 'Time Task Created', entity: 'time_task', category: 'crud' },\n { id: 'staff.timesheets.time_task.updated', label: 'Time Task Updated', entity: 'time_task', category: 'crud' },\n { id: 'staff.timesheets.time_task.deleted', label: 'Time Task Deleted', entity: 'time_task', category: 'crud' },\n { id: 'staff.timesheets.time_task.status_changed', label: 'Time Task Status Changed', entity: 'time_task', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_task.assignee_changed', label: 'Time Task Assignee Changed', entity: 'time_task', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_task_status.created', label: 'Time Task Status Created', entity: 'time_task_status', category: 'crud' },\n { id: 'staff.timesheets.time_task_status.updated', label: 'Time Task Status Updated', entity: 'time_task_status', category: 'crud' },\n { id: 'staff.timesheets.time_task_status.deleted', label: 'Time Task Status Deleted', entity: 'time_task_status', category: 'crud' },\n { id: 'staff.timesheets.time_tag.created', label: 'Time Tag Created', entity: 'time_tag', category: 'crud' },\n { id: 'staff.timesheets.time_tag.updated', label: 'Time Tag Updated', entity: 'time_tag', category: 'crud' },\n { id: 'staff.timesheets.time_tag.deleted', label: 'Time Tag Deleted', entity: 'time_tag', category: 'crud' },\n { id: 'staff.timesheets.time_task_comment.created', label: 'Time Task Comment Created', entity: 'time_task_comment', category: 'crud' },\n { id: 'staff.timesheets.time_task_comment.updated', label: 'Time Task Comment Updated', entity: 'time_task_comment', category: 'crud' },\n { id: 'staff.timesheets.time_task_comment.deleted', label: 'Time Task Comment Deleted', entity: 'time_task_comment', category: 'crud' },\n { id: 'staff.timesheets.time_report.created', label: 'Time Report Created', entity: 'time_report', category: 'crud' },\n { id: 'staff.timesheets.time_report.updated', label: 'Time Report Updated', entity: 'time_report', category: 'crud' },\n { id: 'staff.timesheets.time_report.deleted', label: 'Time Report Deleted', entity: 'time_report', category: 'crud' },\n { id: 'staff.timesheets.time_report.closed', label: 'Time Report Closed', entity: 'time_report', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_report.unlocked', label: 'Time Report Unlocked', entity: 'time_report', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.time_project.budget_threshold_reached', label: 'Time Project Budget Threshold Reached', entity: 'time_project', category: 'lifecycle', clientBroadcast: true },\n { id: 'staff.timesheets.project_access.requested', label: 'Time Project Access Requested', entity: 'time_project', category: 'lifecycle' },\n\n // `clientBroadcast: true` above puts the event on the DOM Event Bridge, whose only\n // audience filter is tenant + organization (`events/api/stream/route.ts`): every\n // signed-in user of the organization receives the payload, with no feature check.\n // So a broadcast payload MUST NOT carry a rate, a cost or an amount \u2014 money is\n // gated on `staff.timesheets.rates.view` (staff/AGENTS.md), a gate SSE cannot\n // apply. `time_report.closed` and `time_project.budget_threshold_reached` emit\n // their money fields conditionally for exactly this reason; see their emitters.\n //\n // Money is not the only thing that audience decides. The same absence of a feature\n // check is why `time_report.unlocked` broadcasts no `reason` \u2014 the operator's\n // mandatory, free-text unlock justification, which lives on the audit row instead \u2014\n // and why `time_report.closed` broadcasts no `customerId`.\n\n // Time tracking (Phase 3) \u2014 transitions owned by the hand-rolled routes that sit\n // beside the CRUD factory resources. Declared here so a third-party module can\n // subscribe to a bulk grid save, a copy, a segment edit, an export or a settings\n // change with the same contract the CRUD ids already offer.\n { id: 'staff.timesheets.time_entry.bulk_updated', label: 'Time Entries Bulk Saved', entity: 'time_entry', category: 'lifecycle' },\n { id: 'staff.timesheets.time_entry.copied', label: 'Time Entry Copied', entity: 'time_entry', category: 'lifecycle' },\n { id: 'staff.timesheets.time_entry.locked', label: 'Time Entries Locked', entity: 'time_entry', category: 'lifecycle' },\n { id: 'staff.timesheets.time_entry.unlocked', label: 'Time Entries Unlocked', entity: 'time_entry', category: 'lifecycle' },\n { id: 'staff.timesheets.time_entry_segment.created', label: 'Time Entry Segment Created', entity: 'time_entry_segment', category: 'crud' },\n { id: 'staff.timesheets.time_entry_segment.updated', label: 'Time Entry Segment Updated', entity: 'time_entry_segment', category: 'crud' },\n { id: 'staff.timesheets.time_entry_segment.deleted', label: 'Time Entry Segment Deleted', entity: 'time_entry_segment', category: 'crud' },\n { id: 'staff.timesheets.time_report.exported', label: 'Time Report Exported', entity: 'time_report', category: 'lifecycle' },\n { id: 'staff.timesheets.time_project.currency_changed', label: 'Time Project Currency Changed', entity: 'time_project', category: 'lifecycle' },\n { id: 'staff.timesheets.time_project_access.granted', label: 'Time Project Access Granted', entity: 'time_project', category: 'lifecycle' },\n { id: 'staff.timesheets.time_project_access.denied', label: 'Time Project Access Denied', entity: 'time_project', category: 'lifecycle' },\n { id: 'staff.timesheets.time_tracking.settings_updated', label: 'Time Tracking Settings Updated', entity: 'time_tracking', category: 'lifecycle' },\n { id: 'staff.timesheets.time_tracking.rounding_reapplied', label: 'Time Tracking Rounding Reapplied', entity: 'time_tracking', category: 'lifecycle' },\n\n // Time tracking (Phase 6) \u2014 the customer-portal bridge (EP-06 / EP-50).\n //\n // This is a SEPARATE id rather than `portalBroadcast: true` on\n // `time_report.closed`, and the difference is a disclosure, not a style choice.\n // The portal SSE stream (`customer_accounts/api/portal/events/stream.ts`)\n // filters a broadcast by tenant + organization and narrows to specific people\n // only when the payload carries `recipientUserId(s)`. One organization serves\n // many customers, so flagging `time_report.closed` \u2014 which carries `reference`\n // and the minute totals \u2014 would hand every client of the tenant a running feed\n // of every other client's reports. `time_report.closed` also has\n // `clientBroadcast: true` and a published webhook payload, so it cannot be\n // narrowed without breaking its backoffice consumers.\n //\n // `subscribers/time-report-portal-broadcast.ts` is the only emitter: it pins\n // `recipientUserIds` to the portal users of the report's own customer and does\n // not emit at all when that list is empty \u2014 the rule\n // `warranty_claims/AGENTS.md` states for its own portal event.\n //\n // Exports are deliberately not mirrored. An export changes nothing the portal\n // renders; the portal reads the report, not the file.\n {\n id: 'staff.timesheets.time_report.portal_published',\n label: 'Time Report Published To Portal',\n entity: 'time_report',\n category: 'lifecycle',\n portalBroadcast: true,\n excludeFromTriggers: true,\n },\n\n // Customer support tickets. `created` and `customer_replied` name the customer, so\n // they stay server-side; `activity_recorded` carries ids only and is what open\n // backoffice screens refetch on. `portal_updated` is emitted only by\n // `lib/support/portalBroadcast.ts` (driven by the `subscribers/support-portal-*.ts`\n // subscribers), always with the ticket's own customer users pinned in\n // `recipientUserIds`, and never when that list is empty.\n { id: 'staff.support_ticket.created', label: 'Support Ticket Created', entity: 'support_ticket', category: 'lifecycle' },\n { id: 'staff.support_ticket.customer_replied', label: 'Support Ticket Customer Replied', entity: 'support_ticket', category: 'lifecycle' },\n {\n id: 'staff.support_ticket.activity_recorded',\n label: 'Support Ticket Activity Recorded',\n entity: 'support_ticket',\n category: 'lifecycle',\n clientBroadcast: true,\n excludeFromTriggers: true,\n },\n {\n id: 'staff.support_ticket.portal_updated',\n label: 'Support Ticket Updated For Portal',\n entity: 'support_ticket',\n category: 'lifecycle',\n portalBroadcast: true,\n excludeFromTriggers: true,\n },\n] as const\n\nexport const eventsConfig = createModuleEvents({\n moduleId: 'staff',\n events,\n})\n\nexport const emitStaffEvent = eventsConfig.emit\n\nexport type StaffEventId = typeof events[number]['id']\n\nexport default eventsConfig\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -42,6 +42,14 @@ const taskStatusChanged = scope.extend({
42
42
  previousTaskStatusId: z.string().nullable().optional(),
43
43
  taskStatusId: z.string().optional()
44
44
  }).passthrough();
45
+ const taskAssigneeChanged = scope.extend({
46
+ id: z.string(),
47
+ timeProjectId: z.string(),
48
+ previousAssigneeStaffMemberId: z.string().nullable(),
49
+ assigneeStaffMemberId: z.string().nullable(),
50
+ changeKind: z.enum(["default", "claim", "release", "manual"]),
51
+ actorUserId: z.string().nullable().optional()
52
+ }).passthrough();
45
53
  const reportClosed = scope.extend({
46
54
  id: z.string(),
47
55
  reportId: z.string(),
@@ -133,6 +141,7 @@ const staffTimeTrackingEventPayloadSchemas = {
133
141
  "staff.timesheets.time_task.updated": crudPayload,
134
142
  "staff.timesheets.time_task.deleted": crudPayload,
135
143
  "staff.timesheets.time_task.status_changed": taskStatusChanged,
144
+ "staff.timesheets.time_task.assignee_changed": taskAssigneeChanged,
136
145
  "staff.timesheets.time_task_status.created": crudPayload,
137
146
  "staff.timesheets.time_task_status.updated": crudPayload,
138
147
  "staff.timesheets.time_task_status.deleted": crudPayload,
@@ -152,7 +161,52 @@ const staffTimeTrackingEventPayloadSchemas = {
152
161
  "staff.timesheets.time_tracking.settings_updated": settingsUpdated,
153
162
  "staff.timesheets.time_tracking.rounding_reapplied": roundingReapplied
154
163
  };
164
+ const supportTicketCreated = scope.extend({
165
+ id: z.string(),
166
+ taskId: z.string(),
167
+ projectId: z.string(),
168
+ customerId: z.string(),
169
+ supportReference: z.string(),
170
+ categoryValue: z.string()
171
+ }).passthrough();
172
+ const supportTicketCustomerReplied = scope.extend({
173
+ id: z.string(),
174
+ taskId: z.string(),
175
+ projectId: z.string(),
176
+ commentId: z.string(),
177
+ supportReference: z.string()
178
+ }).passthrough();
179
+ const supportTicketActivityRecorded = scope.extend({
180
+ id: z.string(),
181
+ taskId: z.string(),
182
+ projectId: z.string(),
183
+ kind: z.enum(["created", "customer_replied", "portal_status", "attachment_added", "attachment_removed"]),
184
+ /** The changed attachment for `attachment_added` / `attachment_removed`, so distinct changes stay distinct for the 500 ms duplicate filter. */
185
+ attachmentId: z.string().optional()
186
+ }).passthrough();
187
+ const supportTicketPortalUpdated = scope.extend({
188
+ id: z.string(),
189
+ ticketId: z.string(),
190
+ supportReference: z.string(),
191
+ portalStatus: z.enum(["received", "in_progress", "resolved"]),
192
+ kind: z.enum(["status", "reply"]),
193
+ /** The change announced: the task version for `status`, the comment id for `reply`. Keeps distinct changes distinct for the portal bridge's 500 ms duplicate filter. */
194
+ version: z.string().optional(),
195
+ /**
196
+ * The portal SSE stream narrows a broadcast to these customer-user ids. The
197
+ * emitter never publishes this event with an empty list, so a ticket update can
198
+ * only ever reach the portal users of the ticket's own customer.
199
+ */
200
+ recipientUserIds: z.array(z.string()).min(1)
201
+ }).passthrough();
202
+ const staffSupportTicketEventPayloadSchemas = {
203
+ "staff.support_ticket.created": supportTicketCreated,
204
+ "staff.support_ticket.customer_replied": supportTicketCustomerReplied,
205
+ "staff.support_ticket.activity_recorded": supportTicketActivityRecorded,
206
+ "staff.support_ticket.portal_updated": supportTicketPortalUpdated
207
+ };
155
208
  export {
209
+ staffSupportTicketEventPayloadSchemas,
156
210
  staffTimeTrackingEventPayloadSchemas
157
211
  };
158
212
  //# sourceMappingURL=events.payloads.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/staff/events.payloads.ts"],
4
- "sourcesContent": ["/**\n * Payload contracts for the `staff.timesheets.*` event family.\n *\n * **Why this file exists.** Outbound webhooks in this platform are not registered\n * per event: `packages/webhooks` subscribes once with `event: '*'`\n * (`subscribers/outbound-dispatch.ts`) and matches each emitted id against the\n * patterns a webhook endpoint subscribed to, so declaring an event in `events.ts`\n * IS its registration \u2014 it appears in `GET /api/webhooks/events` and is deliverable\n * from that moment (`packages/webhooks/AGENTS.md` \u2192 \"When You Need Outbound\n * Webhooks\", step 1). Two properties decide whether a declared event actually\n * reaches an endpoint, and neither is checked anywhere else:\n *\n * 1. the dispatcher drops any payload without a `tenantId` \u2014 it cannot resolve a\n * webhook without one, so an event emitted without tenant scope is silently\n * undeliverable;\n * 2. the delivered body IS the event payload, verbatim, so the payload is the\n * integration contract an external billing or PM system codes against.\n *\n * The webhooks package has no payload-schema registry to register with, so these\n * schemas are that contract, published here and pinned by\n * `__tests__/timeTrackingEventPayloads.test.ts`: every declared `staff.timesheets.*`\n * id must appear below, and every schema must require `tenantId`.\n *\n * Each schema is `passthrough()`: the listed keys are what a subscriber may rely on,\n * additional keys are allowed so a later emitter can add one without breaking a\n * consumer that validates against this schema.\n *\n * Money note: `time_report.closed` carries minute totals but no amount, and\n * `time_project.budget_threshold_reached` carries an `amount` budget's value only\n * when the budget is measured in hours. Both events are `clientBroadcast: true` and\n * the DOM Event Bridge has no feature gate, so the amounts are withheld from the\n * payload itself rather than from one of its two audiences.\n *\n * Money is not the only thing that audience decides. A `clientBroadcast: true`\n * payload must also carry no operator free text and no customer identity: SSE\n * reaches every signed-in user of the organization, so `time_report.unlocked` omits\n * its mandatory `reason` and `time_report.closed` omits `customerId`.\n * `__tests__/timeTrackingEventPayloads.test.ts` fails if either reappears.\n */\n\nimport { z } from 'zod'\n\nconst scope = z.object({\n tenantId: z.string(),\n organizationId: z.string().nullable().optional(),\n})\n\n/** The `{ id, tenantId, organizationId }` shape every CRUD lifecycle event carries. */\nconst crudPayload = scope.extend({ id: z.string() }).passthrough()\n\nconst timerStarted = scope\n .extend({\n id: z.string(),\n staffMemberId: z.string().nullable(),\n startedAt: z.string(),\n })\n .passthrough()\n\nconst timerStopped = scope\n .extend({\n id: z.string(),\n staffMemberId: z.string().nullable(),\n stoppedAt: z.string(),\n durationMinutes: z.number(),\n })\n .passthrough()\n\nconst entryBulkUpdated = scope\n .extend({\n staffMemberId: z.string(),\n created: z.number(),\n updated: z.number(),\n deleted: z.number(),\n entryIds: z.array(z.string()),\n })\n .passthrough()\n\n/** `sourceId` is the entry the copy was made from; `date` only on the copy-day path. */\nconst entryCopied = scope\n .extend({\n id: z.string(),\n sourceId: z.string(),\n staffMemberId: z.string().optional(),\n date: z.string().optional(),\n })\n .passthrough()\n\n/** Batch-level: a report freeze/unfreeze names the report, never one entry. */\nconst entryLockToggled = scope\n .extend({\n reportId: z.string(),\n })\n .passthrough()\n\nconst segmentPayload = scope\n .extend({\n id: z.string(),\n timeEntryId: z.string(),\n })\n .passthrough()\n\nconst taskStatusChanged = scope\n .extend({\n id: z.string(),\n taskId: z.string().optional(),\n timeProjectId: z.string().optional(),\n previousTaskStatusId: z.string().nullable().optional(),\n taskStatusId: z.string().optional(),\n })\n .passthrough()\n\n/**\n * No `customerId`: the event is `clientBroadcast: true` and the DOM Event Bridge\n * applies no feature check, so the one field linking a report to a named client is\n * withheld from the payload rather than from one of its two audiences \u2014 the same\n * trade the amount already makes. The emitter documents the field-by-field call.\n */\nconst reportClosed = scope\n .extend({\n id: z.string(),\n reportId: z.string(),\n reference: z.string(),\n lockedEntryCount: z.number(),\n totalBillableMinutes: z.number(),\n totalNonbillableMinutes: z.number(),\n })\n .passthrough()\n\n/**\n * No `reason`: unlocking demands a written justification of up to 2000 characters,\n * and this event reaches every browser in the organization with no feature check.\n * The prose lives on the `StaffTimeReportEvent` audit row, behind the ACL.\n */\nconst reportUnlocked = scope\n .extend({\n id: z.string(),\n reference: z.string(),\n actorUserId: z.string().nullable(),\n unlockedEntryCount: z.number(),\n })\n .passthrough()\n\nconst reportExported = scope\n .extend({\n id: z.string(),\n reference: z.string(),\n format: z.string(),\n grouping: z.string(),\n rowCount: z.number(),\n })\n .passthrough()\n\nconst reportPortalPublished = scope\n .extend({\n id: z.string(),\n reference: z.string(),\n periodFrom: z.string(),\n periodTo: z.string(),\n /**\n * The portal SSE stream narrows a broadcast to these customer-user ids. The\n * emitter never publishes this event with an empty list, so a report can only\n * ever reach the portal users of its own customer.\n */\n recipientUserIds: z.array(z.string()).min(1),\n })\n .passthrough()\n\nconst projectCurrencyChanged = scope\n .extend({\n id: z.string(),\n currencyCode: z.string(),\n previousCurrencyCode: z.string().nullable(),\n converted: z.boolean(),\n })\n .passthrough()\n\nconst budgetThresholdReached = scope\n .extend({\n id: z.string(),\n timeProjectId: z.string(),\n thresholdPercent: z.number(),\n percent: z.number().nullable(),\n budgetKind: z.string(),\n /** Present only for an `hours` budget \u2014 an `amount` budget states money. */\n budgetValue: z.number().nullable().optional(),\n /** Present only for an `hours` budget \u2014 see `budgetValue`. */\n usedValue: z.number().nullable().optional(),\n })\n .passthrough()\n\nconst projectAccessRequested = scope\n .extend({\n requesterUserId: z.string(),\n requesterName: z.string(),\n timeProjectId: z.string().nullable(),\n timeProjectName: z.string().nullable(),\n requestedAt: z.string(),\n })\n .passthrough()\n\nconst projectAccessDecision = scope.extend({ id: z.string() }).passthrough()\n\nconst settingsUpdated = scope.extend({ settings: z.record(z.string(), z.unknown()) }).passthrough()\n\nconst roundingReapplied = scope\n .extend({\n progressJobId: z.string(),\n candidateCount: z.number(),\n })\n .passthrough()\n\n/**\n * Every declared `staff.timesheets.*` event id and the payload a webhook endpoint\n * subscribed to it receives.\n */\nexport const staffTimeTrackingEventPayloadSchemas = {\n 'staff.timesheets.time_entry.created': crudPayload,\n 'staff.timesheets.time_entry.updated': crudPayload,\n 'staff.timesheets.time_entry.deleted': crudPayload,\n 'staff.timesheets.time_entry.timer_started': timerStarted,\n 'staff.timesheets.time_entry.timer_stopped': timerStopped,\n 'staff.timesheets.time_entry.bulk_updated': entryBulkUpdated,\n 'staff.timesheets.time_entry.copied': entryCopied,\n 'staff.timesheets.time_entry.locked': entryLockToggled,\n 'staff.timesheets.time_entry.unlocked': entryLockToggled,\n 'staff.timesheets.time_entry_segment.created': segmentPayload,\n 'staff.timesheets.time_entry_segment.updated': segmentPayload,\n 'staff.timesheets.time_entry_segment.deleted': segmentPayload,\n 'staff.timesheets.time_project.created': crudPayload,\n 'staff.timesheets.time_project.updated': crudPayload,\n 'staff.timesheets.time_project.deleted': crudPayload,\n 'staff.timesheets.time_project.currency_changed': projectCurrencyChanged,\n 'staff.timesheets.time_project.budget_threshold_reached': budgetThresholdReached,\n 'staff.timesheets.time_project_member.created': crudPayload,\n 'staff.timesheets.time_project_member.updated': crudPayload,\n 'staff.timesheets.time_project_member.deleted': crudPayload,\n 'staff.timesheets.time_project_access.granted': projectAccessDecision,\n 'staff.timesheets.time_project_access.denied': projectAccessDecision,\n 'staff.timesheets.project_access.requested': projectAccessRequested,\n 'staff.timesheets.time_task.created': crudPayload,\n 'staff.timesheets.time_task.updated': crudPayload,\n 'staff.timesheets.time_task.deleted': crudPayload,\n 'staff.timesheets.time_task.status_changed': taskStatusChanged,\n 'staff.timesheets.time_task_status.created': crudPayload,\n 'staff.timesheets.time_task_status.updated': crudPayload,\n 'staff.timesheets.time_task_status.deleted': crudPayload,\n 'staff.timesheets.time_tag.created': crudPayload,\n 'staff.timesheets.time_tag.updated': crudPayload,\n 'staff.timesheets.time_tag.deleted': crudPayload,\n 'staff.timesheets.time_task_comment.created': crudPayload,\n 'staff.timesheets.time_task_comment.updated': crudPayload,\n 'staff.timesheets.time_task_comment.deleted': crudPayload,\n 'staff.timesheets.time_report.created': crudPayload,\n 'staff.timesheets.time_report.updated': crudPayload,\n 'staff.timesheets.time_report.deleted': crudPayload,\n 'staff.timesheets.time_report.closed': reportClosed,\n 'staff.timesheets.time_report.unlocked': reportUnlocked,\n 'staff.timesheets.time_report.exported': reportExported,\n 'staff.timesheets.time_report.portal_published': reportPortalPublished,\n 'staff.timesheets.time_tracking.settings_updated': settingsUpdated,\n 'staff.timesheets.time_tracking.rounding_reapplied': roundingReapplied,\n} as const\n\nexport type StaffTimeTrackingEventId = keyof typeof staffTimeTrackingEventPayloadSchemas\n\nexport type StaffTimeTrackingEventPayload<TEventId extends StaffTimeTrackingEventId> = z.infer<\n typeof staffTimeTrackingEventPayloadSchemas[TEventId]\n>\n"],
5
- "mappings": "AAwCA,SAAS,SAAS;AAElB,MAAM,QAAQ,EAAE,OAAO;AAAA,EACrB,UAAU,EAAE,OAAO;AAAA,EACnB,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AACjD,CAAC;AAGD,MAAM,cAAc,MAAM,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,YAAY;AAEjE,MAAM,eAAe,MAClB,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,WAAW,EAAE,OAAO;AACtB,CAAC,EACA,YAAY;AAEf,MAAM,eAAe,MAClB,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,WAAW,EAAE,OAAO;AAAA,EACpB,iBAAiB,EAAE,OAAO;AAC5B,CAAC,EACA,YAAY;AAEf,MAAM,mBAAmB,MACtB,OAAO;AAAA,EACN,eAAe,EAAE,OAAO;AAAA,EACxB,SAAS,EAAE,OAAO;AAAA,EAClB,SAAS,EAAE,OAAO;AAAA,EAClB,SAAS,EAAE,OAAO;AAAA,EAClB,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;AAC9B,CAAC,EACA,YAAY;AAGf,MAAM,cAAc,MACjB,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,UAAU,EAAE,OAAO;AAAA,EACnB,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,MAAM,EAAE,OAAO,EAAE,SAAS;AAC5B,CAAC,EACA,YAAY;AAGf,MAAM,mBAAmB,MACtB,OAAO;AAAA,EACN,UAAU,EAAE,OAAO;AACrB,CAAC,EACA,YAAY;AAEf,MAAM,iBAAiB,MACpB,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,aAAa,EAAE,OAAO;AACxB,CAAC,EACA,YAAY;AAEf,MAAM,oBAAoB,MACvB,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,sBAAsB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACrD,cAAc,EAAE,OAAO,EAAE,SAAS;AACpC,CAAC,EACA,YAAY;AAQf,MAAM,eAAe,MAClB,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,UAAU,EAAE,OAAO;AAAA,EACnB,WAAW,EAAE,OAAO;AAAA,EACpB,kBAAkB,EAAE,OAAO;AAAA,EAC3B,sBAAsB,EAAE,OAAO;AAAA,EAC/B,yBAAyB,EAAE,OAAO;AACpC,CAAC,EACA,YAAY;AAOf,MAAM,iBAAiB,MACpB,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,WAAW,EAAE,OAAO;AAAA,EACpB,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,oBAAoB,EAAE,OAAO;AAC/B,CAAC,EACA,YAAY;AAEf,MAAM,iBAAiB,MACpB,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,WAAW,EAAE,OAAO;AAAA,EACpB,QAAQ,EAAE,OAAO;AAAA,EACjB,UAAU,EAAE,OAAO;AAAA,EACnB,UAAU,EAAE,OAAO;AACrB,CAAC,EACA,YAAY;AAEf,MAAM,wBAAwB,MAC3B,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,WAAW,EAAE,OAAO;AAAA,EACpB,YAAY,EAAE,OAAO;AAAA,EACrB,UAAU,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnB,kBAAkB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC;AAC7C,CAAC,EACA,YAAY;AAEf,MAAM,yBAAyB,MAC5B,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,cAAc,EAAE,OAAO;AAAA,EACvB,sBAAsB,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1C,WAAW,EAAE,QAAQ;AACvB,CAAC,EACA,YAAY;AAEf,MAAM,yBAAyB,MAC5B,OAAO;AAAA,EACN,IAAI,EAAE,OAAO;AAAA,EACb,eAAe,EAAE,OAAO;AAAA,EACxB,kBAAkB,EAAE,OAAO;AAAA,EAC3B,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,YAAY,EAAE,OAAO;AAAA;AAAA,EAErB,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA;AAAA,EAE5C,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAC5C,CAAC,EACA,YAAY;AAEf,MAAM,yBAAyB,MAC5B,OAAO;AAAA,EACN,iBAAiB,EAAE,OAAO;AAAA,EAC1B,eAAe,EAAE,OAAO;AAAA,EACxB,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,aAAa,EAAE,OAAO;AACxB,CAAC,EACA,YAAY;AAEf,MAAM,wBAAwB,MAAM,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,YAAY;AAE3E,MAAM,kBAAkB,MAAM,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,YAAY;AAElG,MAAM,oBAAoB,MACvB,OAAO;AAAA,EACN,eAAe,EAAE,OAAO;AAAA,EACxB,gBAAgB,EAAE,OAAO;AAC3B,CAAC,EACA,YAAY;AAMR,MAAM,uCAAuC;AAAA,EAClD,uCAAuC;AAAA,EACvC,uCAAuC;AAAA,EACvC,uCAAuC;AAAA,EACvC,6CAA6C;AAAA,EAC7C,6CAA6C;AAAA,EAC7C,4CAA4C;AAAA,EAC5C,sCAAsC;AAAA,EACtC,sCAAsC;AAAA,EACtC,wCAAwC;AAAA,EACxC,+CAA+C;AAAA,EAC/C,+CAA+C;AAAA,EAC/C,+CAA+C;AAAA,EAC/C,yCAAyC;AAAA,EACzC,yCAAyC;AAAA,EACzC,yCAAyC;AAAA,EACzC,kDAAkD;AAAA,EAClD,0DAA0D;AAAA,EAC1D,gDAAgD;AAAA,EAChD,gDAAgD;AAAA,EAChD,gDAAgD;AAAA,EAChD,gDAAgD;AAAA,EAChD,+CAA+C;AAAA,EAC/C,6CAA6C;AAAA,EAC7C,sCAAsC;AAAA,EACtC,sCAAsC;AAAA,EACtC,sCAAsC;AAAA,EACtC,6CAA6C;AAAA,EAC7C,6CAA6C;AAAA,EAC7C,6CAA6C;AAAA,EAC7C,6CAA6C;AAAA,EAC7C,qCAAqC;AAAA,EACrC,qCAAqC;AAAA,EACrC,qCAAqC;AAAA,EACrC,8CAA8C;AAAA,EAC9C,8CAA8C;AAAA,EAC9C,8CAA8C;AAAA,EAC9C,wCAAwC;AAAA,EACxC,wCAAwC;AAAA,EACxC,wCAAwC;AAAA,EACxC,uCAAuC;AAAA,EACvC,yCAAyC;AAAA,EACzC,yCAAyC;AAAA,EACzC,iDAAiD;AAAA,EACjD,mDAAmD;AAAA,EACnD,qDAAqD;AACvD;",
4
+ "sourcesContent": ["/**\n * Payload contracts for the `staff.timesheets.*` and `staff.support_ticket.*` event families.\n *\n * **Why this file exists.** Outbound webhooks in this platform are not registered\n * per event: `packages/webhooks` subscribes once with `event: '*'`\n * (`subscribers/outbound-dispatch.ts`) and matches each emitted id against the\n * patterns a webhook endpoint subscribed to, so declaring an event in `events.ts`\n * IS its registration \u2014 it appears in `GET /api/webhooks/events` and is deliverable\n * from that moment (`packages/webhooks/AGENTS.md` \u2192 \"When You Need Outbound\n * Webhooks\", step 1). Two properties decide whether a declared event actually\n * reaches an endpoint, and neither is checked anywhere else:\n *\n * 1. the dispatcher drops any payload without a `tenantId` \u2014 it cannot resolve a\n * webhook without one, so an event emitted without tenant scope is silently\n * undeliverable;\n * 2. the delivered body IS the event payload, verbatim, so the payload is the\n * integration contract an external billing or PM system codes against.\n *\n * The webhooks package has no payload-schema registry to register with, so these\n * schemas are that contract, published here and pinned by\n * `__tests__/timeTrackingEventPayloads.test.ts`: every declared `staff.timesheets.*`\n * id must appear below, and every schema must require `tenantId`.\n *\n * Each schema is `passthrough()`: the listed keys are what a subscriber may rely on,\n * additional keys are allowed so a later emitter can add one without breaking a\n * consumer that validates against this schema.\n *\n * Money note: `time_report.closed` carries minute totals but no amount, and\n * `time_project.budget_threshold_reached` carries an `amount` budget's value only\n * when the budget is measured in hours. Both events are `clientBroadcast: true` and\n * the DOM Event Bridge has no feature gate, so the amounts are withheld from the\n * payload itself rather than from one of its two audiences.\n *\n * Money is not the only thing that audience decides. A `clientBroadcast: true`\n * payload must also carry no operator free text and no customer identity: SSE\n * reaches every signed-in user of the organization, so `time_report.unlocked` omits\n * its mandatory `reason` and `time_report.closed` omits `customerId`.\n * `__tests__/timeTrackingEventPayloads.test.ts` fails if either reappears.\n */\n\nimport { z } from 'zod'\n\nconst scope = z.object({\n tenantId: z.string(),\n organizationId: z.string().nullable().optional(),\n})\n\n/** The `{ id, tenantId, organizationId }` shape every CRUD lifecycle event carries. */\nconst crudPayload = scope.extend({ id: z.string() }).passthrough()\n\nconst timerStarted = scope\n .extend({\n id: z.string(),\n staffMemberId: z.string().nullable(),\n startedAt: z.string(),\n })\n .passthrough()\n\nconst timerStopped = scope\n .extend({\n id: z.string(),\n staffMemberId: z.string().nullable(),\n stoppedAt: z.string(),\n durationMinutes: z.number(),\n })\n .passthrough()\n\nconst entryBulkUpdated = scope\n .extend({\n staffMemberId: z.string(),\n created: z.number(),\n updated: z.number(),\n deleted: z.number(),\n entryIds: z.array(z.string()),\n })\n .passthrough()\n\n/** `sourceId` is the entry the copy was made from; `date` only on the copy-day path. */\nconst entryCopied = scope\n .extend({\n id: z.string(),\n sourceId: z.string(),\n staffMemberId: z.string().optional(),\n date: z.string().optional(),\n })\n .passthrough()\n\n/** Batch-level: a report freeze/unfreeze names the report, never one entry. */\nconst entryLockToggled = scope\n .extend({\n reportId: z.string(),\n })\n .passthrough()\n\nconst segmentPayload = scope\n .extend({\n id: z.string(),\n timeEntryId: z.string(),\n })\n .passthrough()\n\nconst taskStatusChanged = scope\n .extend({\n id: z.string(),\n taskId: z.string().optional(),\n timeProjectId: z.string().optional(),\n previousTaskStatusId: z.string().nullable().optional(),\n taskStatusId: z.string().optional(),\n })\n .passthrough()\n\n/** Ids only: the event is `clientBroadcast: true`, so no names, no customer and no text. */\nconst taskAssigneeChanged = scope\n .extend({\n id: z.string(),\n timeProjectId: z.string(),\n previousAssigneeStaffMemberId: z.string().nullable(),\n assigneeStaffMemberId: z.string().nullable(),\n changeKind: z.enum(['default', 'claim', 'release', 'manual']),\n actorUserId: z.string().nullable().optional(),\n })\n .passthrough()\n\n/**\n * No `customerId`: the event is `clientBroadcast: true` and the DOM Event Bridge\n * applies no feature check, so the one field linking a report to a named client is\n * withheld from the payload rather than from one of its two audiences \u2014 the same\n * trade the amount already makes. The emitter documents the field-by-field call.\n */\nconst reportClosed = scope\n .extend({\n id: z.string(),\n reportId: z.string(),\n reference: z.string(),\n lockedEntryCount: z.number(),\n totalBillableMinutes: z.number(),\n totalNonbillableMinutes: z.number(),\n })\n .passthrough()\n\n/**\n * No `reason`: unlocking demands a written justification of up to 2000 characters,\n * and this event reaches every browser in the organization with no feature check.\n * The prose lives on the `StaffTimeReportEvent` audit row, behind the ACL.\n */\nconst reportUnlocked = scope\n .extend({\n id: z.string(),\n reference: z.string(),\n actorUserId: z.string().nullable(),\n unlockedEntryCount: z.number(),\n })\n .passthrough()\n\nconst reportExported = scope\n .extend({\n id: z.string(),\n reference: z.string(),\n format: z.string(),\n grouping: z.string(),\n rowCount: z.number(),\n })\n .passthrough()\n\nconst reportPortalPublished = scope\n .extend({\n id: z.string(),\n reference: z.string(),\n periodFrom: z.string(),\n periodTo: z.string(),\n /**\n * The portal SSE stream narrows a broadcast to these customer-user ids. The\n * emitter never publishes this event with an empty list, so a report can only\n * ever reach the portal users of its own customer.\n */\n recipientUserIds: z.array(z.string()).min(1),\n })\n .passthrough()\n\nconst projectCurrencyChanged = scope\n .extend({\n id: z.string(),\n currencyCode: z.string(),\n previousCurrencyCode: z.string().nullable(),\n converted: z.boolean(),\n })\n .passthrough()\n\nconst budgetThresholdReached = scope\n .extend({\n id: z.string(),\n timeProjectId: z.string(),\n thresholdPercent: z.number(),\n percent: z.number().nullable(),\n budgetKind: z.string(),\n /** Present only for an `hours` budget \u2014 an `amount` budget states money. */\n budgetValue: z.number().nullable().optional(),\n /** Present only for an `hours` budget \u2014 see `budgetValue`. */\n usedValue: z.number().nullable().optional(),\n })\n .passthrough()\n\nconst projectAccessRequested = scope\n .extend({\n requesterUserId: z.string(),\n requesterName: z.string(),\n timeProjectId: z.string().nullable(),\n timeProjectName: z.string().nullable(),\n requestedAt: z.string(),\n })\n .passthrough()\n\nconst projectAccessDecision = scope.extend({ id: z.string() }).passthrough()\n\nconst settingsUpdated = scope.extend({ settings: z.record(z.string(), z.unknown()) }).passthrough()\n\nconst roundingReapplied = scope\n .extend({\n progressJobId: z.string(),\n candidateCount: z.number(),\n })\n .passthrough()\n\n/**\n * Every declared `staff.timesheets.*` event id and the payload a webhook endpoint\n * subscribed to it receives.\n */\nexport const staffTimeTrackingEventPayloadSchemas = {\n 'staff.timesheets.time_entry.created': crudPayload,\n 'staff.timesheets.time_entry.updated': crudPayload,\n 'staff.timesheets.time_entry.deleted': crudPayload,\n 'staff.timesheets.time_entry.timer_started': timerStarted,\n 'staff.timesheets.time_entry.timer_stopped': timerStopped,\n 'staff.timesheets.time_entry.bulk_updated': entryBulkUpdated,\n 'staff.timesheets.time_entry.copied': entryCopied,\n 'staff.timesheets.time_entry.locked': entryLockToggled,\n 'staff.timesheets.time_entry.unlocked': entryLockToggled,\n 'staff.timesheets.time_entry_segment.created': segmentPayload,\n 'staff.timesheets.time_entry_segment.updated': segmentPayload,\n 'staff.timesheets.time_entry_segment.deleted': segmentPayload,\n 'staff.timesheets.time_project.created': crudPayload,\n 'staff.timesheets.time_project.updated': crudPayload,\n 'staff.timesheets.time_project.deleted': crudPayload,\n 'staff.timesheets.time_project.currency_changed': projectCurrencyChanged,\n 'staff.timesheets.time_project.budget_threshold_reached': budgetThresholdReached,\n 'staff.timesheets.time_project_member.created': crudPayload,\n 'staff.timesheets.time_project_member.updated': crudPayload,\n 'staff.timesheets.time_project_member.deleted': crudPayload,\n 'staff.timesheets.time_project_access.granted': projectAccessDecision,\n 'staff.timesheets.time_project_access.denied': projectAccessDecision,\n 'staff.timesheets.project_access.requested': projectAccessRequested,\n 'staff.timesheets.time_task.created': crudPayload,\n 'staff.timesheets.time_task.updated': crudPayload,\n 'staff.timesheets.time_task.deleted': crudPayload,\n 'staff.timesheets.time_task.status_changed': taskStatusChanged,\n 'staff.timesheets.time_task.assignee_changed': taskAssigneeChanged,\n 'staff.timesheets.time_task_status.created': crudPayload,\n 'staff.timesheets.time_task_status.updated': crudPayload,\n 'staff.timesheets.time_task_status.deleted': crudPayload,\n 'staff.timesheets.time_tag.created': crudPayload,\n 'staff.timesheets.time_tag.updated': crudPayload,\n 'staff.timesheets.time_tag.deleted': crudPayload,\n 'staff.timesheets.time_task_comment.created': crudPayload,\n 'staff.timesheets.time_task_comment.updated': crudPayload,\n 'staff.timesheets.time_task_comment.deleted': crudPayload,\n 'staff.timesheets.time_report.created': crudPayload,\n 'staff.timesheets.time_report.updated': crudPayload,\n 'staff.timesheets.time_report.deleted': crudPayload,\n 'staff.timesheets.time_report.closed': reportClosed,\n 'staff.timesheets.time_report.unlocked': reportUnlocked,\n 'staff.timesheets.time_report.exported': reportExported,\n 'staff.timesheets.time_report.portal_published': reportPortalPublished,\n 'staff.timesheets.time_tracking.settings_updated': settingsUpdated,\n 'staff.timesheets.time_tracking.rounding_reapplied': roundingReapplied,\n} as const\n\nexport type StaffTimeTrackingEventId = keyof typeof staffTimeTrackingEventPayloadSchemas\n\nexport type StaffTimeTrackingEventPayload<TEventId extends StaffTimeTrackingEventId> = z.infer<\n typeof staffTimeTrackingEventPayloadSchemas[TEventId]\n>\n\n/**\n * Names the customer and the ticket reference, so the event stays server-side\n * (no `clientBroadcast`); webhooks and the notification subscriber read it.\n */\nconst supportTicketCreated = scope\n .extend({\n id: z.string(),\n taskId: z.string(),\n projectId: z.string(),\n customerId: z.string(),\n supportReference: z.string(),\n categoryValue: z.string(),\n })\n .passthrough()\n\nconst supportTicketCustomerReplied = scope\n .extend({\n id: z.string(),\n taskId: z.string(),\n projectId: z.string(),\n commentId: z.string(),\n supportReference: z.string(),\n })\n .passthrough()\n\n/** Ids only: the event is `clientBroadcast: true`, so no customer, no reference and no text. */\nconst supportTicketActivityRecorded = scope\n .extend({\n id: z.string(),\n taskId: z.string(),\n projectId: z.string(),\n kind: z.enum(['created', 'customer_replied', 'portal_status', 'attachment_added', 'attachment_removed']),\n /** The changed attachment for `attachment_added` / `attachment_removed`, so distinct changes stay distinct for the 500 ms duplicate filter. */\n attachmentId: z.string().optional(),\n })\n .passthrough()\n\nconst supportTicketPortalUpdated = scope\n .extend({\n id: z.string(),\n ticketId: z.string(),\n supportReference: z.string(),\n portalStatus: z.enum(['received', 'in_progress', 'resolved']),\n kind: z.enum(['status', 'reply']),\n /** The change announced: the task version for `status`, the comment id for `reply`. Keeps distinct changes distinct for the portal bridge's 500 ms duplicate filter. */\n version: z.string().optional(),\n /**\n * The portal SSE stream narrows a broadcast to these customer-user ids. The\n * emitter never publishes this event with an empty list, so a ticket update can\n * only ever reach the portal users of the ticket's own customer.\n */\n recipientUserIds: z.array(z.string()).min(1),\n })\n .passthrough()\n\n/**\n * Every declared `staff.support_ticket.*` event id and the payload a webhook endpoint\n * subscribed to it receives. Same rules as the time-tracking map above: `tenantId` is\n * required and every schema is `passthrough()`.\n */\nexport const staffSupportTicketEventPayloadSchemas = {\n 'staff.support_ticket.created': supportTicketCreated,\n 'staff.support_ticket.customer_replied': supportTicketCustomerReplied,\n 'staff.support_ticket.activity_recorded': supportTicketActivityRecorded,\n 'staff.support_ticket.portal_updated': supportTicketPortalUpdated,\n} as const\n\nexport type StaffSupportTicketEventId = keyof typeof staffSupportTicketEventPayloadSchemas\n\nexport type StaffSupportTicketEventPayload<TEventId extends StaffSupportTicketEventId> = z.infer<\n typeof staffSupportTicketEventPayloadSchemas[TEventId]\n>\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -106,6 +106,7 @@ const extensionPoints = defineModuleExtensionPoints({
106
106
  myWorkBeforeSections: pageHost("staff.my_work:before-sections", "backend/staff/time-tracking/page.tsx"),
107
107
  myWorkAfterSections: pageHost("staff.my_work:after-sections", "backend/staff/time-tracking/page.tsx"),
108
108
  timeTrackingSettingsSections: pageHost("staff.time_tracking.settings:sections", "backend/staff/time-tracking/settings/page.tsx"),
109
+ timeTrackingSettingsTabs: pageHost("staff.time_tracking.settings:tabs", "backend/staff/time-tracking/settings/page.tsx"),
109
110
  timerBarActions: pageHost("staff.timesheets.timer-bar:actions", "lib/timesheets-ui/TimerBar.tsx"),
110
111
  /**
111
112
  * EP-50. The two customer-portal spots. `scopeContract` names the third