@open-mercato/core 0.7.1-develop.7178.1.ab93fbaf4e → 0.7.1-develop.7180.1.9717fbbb43

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 (808) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/staff_time_entry/index.js +14 -0
  3. package/dist/generated/entities/staff_time_entry/index.js.map +2 -2
  4. package/dist/generated/entities/staff_time_entry_tag/index.js +15 -0
  5. package/dist/generated/entities/staff_time_entry_tag/index.js.map +7 -0
  6. package/dist/generated/entities/staff_time_project/index.js +16 -0
  7. package/dist/generated/entities/staff_time_project/index.js.map +2 -2
  8. package/dist/generated/entities/staff_time_report/index.js +57 -0
  9. package/dist/generated/entities/staff_time_report/index.js.map +7 -0
  10. package/dist/generated/entities/staff_time_report_entry/index.js +27 -0
  11. package/dist/generated/entities/staff_time_report_entry/index.js.map +7 -0
  12. package/dist/generated/entities/staff_time_report_event/index.js +21 -0
  13. package/dist/generated/entities/staff_time_report_event/index.js.map +7 -0
  14. package/dist/generated/entities/staff_time_report_project/index.js +15 -0
  15. package/dist/generated/entities/staff_time_report_project/index.js.map +7 -0
  16. package/dist/generated/entities/staff_time_tag/index.js +21 -0
  17. package/dist/generated/entities/staff_time_tag/index.js.map +7 -0
  18. package/dist/generated/entities/staff_time_task/index.js +37 -0
  19. package/dist/generated/entities/staff_time_task/index.js.map +7 -0
  20. package/dist/generated/entities/staff_time_task_comment/index.js +21 -0
  21. package/dist/generated/entities/staff_time_task_comment/index.js.map +7 -0
  22. package/dist/generated/entities/staff_time_task_status/index.js +29 -0
  23. package/dist/generated/entities/staff_time_task_status/index.js.map +7 -0
  24. package/dist/generated/entities/staff_time_task_tag/index.js +15 -0
  25. package/dist/generated/entities/staff_time_task_tag/index.js.map +7 -0
  26. package/dist/generated/entities.ids.generated.js +11 -1
  27. package/dist/generated/entities.ids.generated.js.map +2 -2
  28. package/dist/generated/entity-fields-registry.js +149 -0
  29. package/dist/generated/entity-fields-registry.js.map +2 -2
  30. package/dist/helpers/integration/timesheetFixtures.js +7 -0
  31. package/dist/helpers/integration/timesheetFixtures.js.map +2 -2
  32. package/dist/modules/auth/cli.js +16 -0
  33. package/dist/modules/auth/cli.js.map +2 -2
  34. package/dist/modules/auth/lib/backendChrome.js +1 -0
  35. package/dist/modules/auth/lib/backendChrome.js.map +2 -2
  36. package/dist/modules/customer_accounts/lib/customerRoleAcls.js +44 -0
  37. package/dist/modules/customer_accounts/lib/customerRoleAcls.js.map +7 -0
  38. package/dist/modules/customer_accounts/setup.js +1 -28
  39. package/dist/modules/customer_accounts/setup.js.map +2 -2
  40. package/dist/modules/data_sync/api/options.js +2 -0
  41. package/dist/modules/data_sync/api/options.js.map +2 -2
  42. package/dist/modules/data_sync/backend/data-sync/page.js +39 -17
  43. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  44. package/dist/modules/data_sync/lib/start-controls.js +42 -0
  45. package/dist/modules/data_sync/lib/start-controls.js.map +7 -0
  46. package/dist/modules/staff/acl.js +9 -1
  47. package/dist/modules/staff/acl.js.map +2 -2
  48. package/dist/modules/staff/ai-agents.js +142 -0
  49. package/dist/modules/staff/ai-agents.js.map +7 -0
  50. package/dist/modules/staff/ai-tools/time-tracking-pack.js +348 -0
  51. package/dist/modules/staff/ai-tools/time-tracking-pack.js.map +7 -0
  52. package/dist/modules/staff/ai-tools/types.js +54 -0
  53. package/dist/modules/staff/ai-tools/types.js.map +7 -0
  54. package/dist/modules/staff/ai-tools.js +8 -0
  55. package/dist/modules/staff/ai-tools.js.map +7 -0
  56. package/dist/modules/staff/analytics.js +84 -1
  57. package/dist/modules/staff/analytics.js.map +2 -2
  58. package/dist/modules/staff/api/guards.js +37 -3
  59. package/dist/modules/staff/api/guards.js.map +2 -2
  60. package/dist/modules/staff/api/leave-requests/accept/route.js +1 -3
  61. package/dist/modules/staff/api/leave-requests/accept/route.js.map +2 -2
  62. package/dist/modules/staff/api/leave-requests/reject/route.js +1 -3
  63. package/dist/modules/staff/api/leave-requests/reject/route.js.map +2 -2
  64. package/dist/modules/staff/api/portal/time-reports/[id]/route.js +131 -0
  65. package/dist/modules/staff/api/portal/time-reports/[id]/route.js.map +7 -0
  66. package/dist/modules/staff/api/portal/time-reports/route.js +179 -0
  67. package/dist/modules/staff/api/portal/time-reports/route.js.map +7 -0
  68. package/dist/modules/staff/api/team-members/self/route.js +1 -3
  69. package/dist/modules/staff/api/team-members/self/route.js.map +2 -2
  70. package/dist/modules/staff/api/team-members/tags/assign/route.js +1 -3
  71. package/dist/modules/staff/api/team-members/tags/assign/route.js.map +2 -2
  72. package/dist/modules/staff/api/team-members/tags/unassign/route.js +1 -3
  73. package/dist/modules/staff/api/team-members/tags/unassign/route.js.map +2 -2
  74. package/dist/modules/staff/api/timesheets/_shared/withTimesheetInterceptors.js +174 -0
  75. package/dist/modules/staff/api/timesheets/_shared/withTimesheetInterceptors.js.map +7 -0
  76. package/dist/modules/staff/api/timesheets/access-requests/route.js +226 -0
  77. package/dist/modules/staff/api/timesheets/access-requests/route.js.map +7 -0
  78. package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js +15 -8
  79. package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js.map +2 -2
  80. package/dist/modules/staff/api/timesheets/my-projects/route.js +13 -1
  81. package/dist/modules/staff/api/timesheets/my-projects/route.js.map +2 -2
  82. package/dist/modules/staff/api/timesheets/my-work/myWorkAggregate.js +42 -0
  83. package/dist/modules/staff/api/timesheets/my-work/myWorkAggregate.js.map +7 -0
  84. package/dist/modules/staff/api/timesheets/my-work/route.js +383 -0
  85. package/dist/modules/staff/api/timesheets/my-work/route.js.map +7 -0
  86. package/dist/modules/staff/api/timesheets/projects/kpis/route.js +14 -2
  87. package/dist/modules/staff/api/timesheets/projects/kpis/route.js.map +2 -2
  88. package/dist/modules/staff/api/timesheets/reports/[id]/close/route.js +168 -0
  89. package/dist/modules/staff/api/timesheets/reports/[id]/close/route.js.map +7 -0
  90. package/dist/modules/staff/api/timesheets/reports/[id]/export/route.js +246 -0
  91. package/dist/modules/staff/api/timesheets/reports/[id]/export/route.js.map +7 -0
  92. package/dist/modules/staff/api/timesheets/reports/[id]/sheet/route.js +183 -0
  93. package/dist/modules/staff/api/timesheets/reports/[id]/sheet/route.js.map +7 -0
  94. package/dist/modules/staff/api/timesheets/reports/[id]/unlock/route.js +164 -0
  95. package/dist/modules/staff/api/timesheets/reports/[id]/unlock/route.js.map +7 -0
  96. package/dist/modules/staff/api/timesheets/reports/preview/route.js +360 -0
  97. package/dist/modules/staff/api/timesheets/reports/preview/route.js.map +7 -0
  98. package/dist/modules/staff/api/timesheets/reports/route.js +316 -0
  99. package/dist/modules/staff/api/timesheets/reports/route.js.map +7 -0
  100. package/dist/modules/staff/api/timesheets/reports/shared.js +63 -0
  101. package/dist/modules/staff/api/timesheets/reports/shared.js.map +7 -0
  102. package/dist/modules/staff/api/timesheets/settings/reapply-rounding/route.js +164 -0
  103. package/dist/modules/staff/api/timesheets/settings/reapply-rounding/route.js.map +7 -0
  104. package/dist/modules/staff/api/timesheets/settings/rounding-impact/route.js +168 -0
  105. package/dist/modules/staff/api/timesheets/settings/rounding-impact/route.js.map +7 -0
  106. package/dist/modules/staff/api/timesheets/settings/route.js +199 -0
  107. package/dist/modules/staff/api/timesheets/settings/route.js.map +7 -0
  108. package/dist/modules/staff/api/timesheets/tags/access.js +76 -0
  109. package/dist/modules/staff/api/timesheets/tags/access.js.map +7 -0
  110. package/dist/modules/staff/api/timesheets/tags/entry-assignments/route.js +235 -0
  111. package/dist/modules/staff/api/timesheets/tags/entry-assignments/route.js.map +7 -0
  112. package/dist/modules/staff/api/timesheets/tags/route.js +160 -0
  113. package/dist/modules/staff/api/timesheets/tags/route.js.map +7 -0
  114. package/dist/modules/staff/api/timesheets/tags/task-assignments/route.js +233 -0
  115. package/dist/modules/staff/api/timesheets/tags/task-assignments/route.js.map +7 -0
  116. package/dist/modules/staff/api/timesheets/task-statuses/route.js +188 -0
  117. package/dist/modules/staff/api/timesheets/task-statuses/route.js.map +7 -0
  118. package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js +399 -0
  119. package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js.map +7 -0
  120. package/dist/modules/staff/api/timesheets/tasks/[id]/status/route.js +210 -0
  121. package/dist/modules/staff/api/timesheets/tasks/[id]/status/route.js.map +7 -0
  122. package/dist/modules/staff/api/timesheets/tasks/route.js +333 -0
  123. package/dist/modules/staff/api/timesheets/tasks/route.js.map +7 -0
  124. package/dist/modules/staff/api/timesheets/time-entries/[id]/duplicate/route.js +228 -0
  125. package/dist/modules/staff/api/timesheets/time-entries/[id]/duplicate/route.js.map +7 -0
  126. package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.js +29 -10
  127. package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.js.map +2 -2
  128. package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js +31 -18
  129. package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js.map +2 -2
  130. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +21 -7
  131. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +2 -2
  132. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js +27 -7
  133. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js.map +2 -2
  134. package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js +215 -32
  135. package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js.map +2 -2
  136. package/dist/modules/staff/api/timesheets/time-entries/copy-day/route.js +378 -0
  137. package/dist/modules/staff/api/timesheets/time-entries/copy-day/route.js.map +7 -0
  138. package/dist/modules/staff/api/timesheets/time-entries/overlaps/route.js +340 -0
  139. package/dist/modules/staff/api/timesheets/time-entries/overlaps/route.js.map +7 -0
  140. package/dist/modules/staff/api/timesheets/time-entries/route.js +238 -26
  141. package/dist/modules/staff/api/timesheets/time-entries/route.js.map +2 -2
  142. package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js +23 -8
  143. package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js.map +2 -2
  144. package/dist/modules/staff/api/timesheets/time-projects/[id]/change-currency/route.js +209 -0
  145. package/dist/modules/staff/api/timesheets/time-projects/[id]/change-currency/route.js.map +7 -0
  146. package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js +59 -2
  147. package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js.map +2 -2
  148. package/dist/modules/staff/api/timesheets/time-projects/route.js +264 -22
  149. package/dist/modules/staff/api/timesheets/time-projects/route.js.map +2 -2
  150. package/dist/modules/staff/backend/staff/time-tracking/board/page.js +110 -0
  151. package/dist/modules/staff/backend/staff/time-tracking/board/page.js.map +7 -0
  152. package/dist/modules/staff/backend/staff/time-tracking/board/page.meta.js +18 -0
  153. package/dist/modules/staff/backend/staff/time-tracking/board/page.meta.js.map +7 -0
  154. package/dist/modules/staff/backend/staff/time-tracking/entries/page.js +981 -0
  155. package/dist/modules/staff/backend/staff/time-tracking/entries/page.js.map +7 -0
  156. package/dist/modules/staff/backend/staff/time-tracking/entries/page.meta.js +18 -0
  157. package/dist/modules/staff/backend/staff/time-tracking/entries/page.meta.js.map +7 -0
  158. package/dist/modules/staff/backend/staff/time-tracking/page.js +583 -0
  159. package/dist/modules/staff/backend/staff/time-tracking/page.js.map +7 -0
  160. package/dist/modules/staff/backend/staff/time-tracking/page.meta.js +15 -0
  161. package/dist/modules/staff/backend/staff/time-tracking/page.meta.js.map +7 -0
  162. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.js +65 -0
  163. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.js.map +7 -0
  164. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.meta.js +16 -0
  165. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.meta.js.map +7 -0
  166. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js +229 -0
  167. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js.map +7 -0
  168. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.meta.js +16 -0
  169. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.meta.js.map +7 -0
  170. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +1014 -0
  171. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +7 -0
  172. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.meta.js +16 -0
  173. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.meta.js.map +7 -0
  174. package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.js +97 -0
  175. package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.js.map +7 -0
  176. package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.meta.js +16 -0
  177. package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.meta.js.map +7 -0
  178. package/dist/modules/staff/backend/staff/time-tracking/projects/page.js +1040 -0
  179. package/dist/modules/staff/backend/staff/time-tracking/projects/page.js.map +7 -0
  180. package/dist/modules/staff/backend/staff/time-tracking/projects/page.meta.js +19 -0
  181. package/dist/modules/staff/backend/staff/time-tracking/projects/page.meta.js.map +7 -0
  182. package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js +353 -0
  183. package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js.map +7 -0
  184. package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.js +457 -0
  185. package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.js.map +7 -0
  186. package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.meta.js +16 -0
  187. package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.meta.js.map +7 -0
  188. package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.js +697 -0
  189. package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.js.map +7 -0
  190. package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.meta.js +16 -0
  191. package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.meta.js.map +7 -0
  192. package/dist/modules/staff/backend/staff/time-tracking/reports/page.js +174 -0
  193. package/dist/modules/staff/backend/staff/time-tracking/reports/page.js.map +7 -0
  194. package/dist/modules/staff/backend/staff/time-tracking/reports/page.meta.js +18 -0
  195. package/dist/modules/staff/backend/staff/time-tracking/reports/page.meta.js.map +7 -0
  196. package/dist/modules/staff/backend/staff/time-tracking/settings/page.js +546 -0
  197. package/dist/modules/staff/backend/staff/time-tracking/settings/page.js.map +7 -0
  198. package/dist/modules/staff/backend/staff/time-tracking/settings/page.meta.js +18 -0
  199. package/dist/modules/staff/backend/staff/time-tracking/settings/page.meta.js.map +7 -0
  200. package/dist/modules/staff/backend/staff/time-tracking/timesheet/GridView.js +710 -0
  201. package/dist/modules/staff/backend/staff/time-tracking/timesheet/GridView.js.map +7 -0
  202. package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.js +646 -0
  203. package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.js.map +7 -0
  204. package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.meta.js +18 -0
  205. package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.meta.js.map +7 -0
  206. package/dist/modules/staff/backend/staff/timesheets/page.js +4 -793
  207. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  208. package/dist/modules/staff/backend/staff/timesheets/page.meta.js +2 -7
  209. package/dist/modules/staff/backend/staff/timesheets/page.meta.js.map +2 -2
  210. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js +5 -136
  211. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js.map +2 -2
  212. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.js +1 -7
  213. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.js.map +2 -2
  214. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js +5 -445
  215. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +3 -3
  216. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.js +1 -7
  217. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.js.map +2 -2
  218. package/dist/modules/staff/backend/staff/timesheets/projects/create/page.js +4 -76
  219. package/dist/modules/staff/backend/staff/timesheets/projects/create/page.js.map +2 -2
  220. package/dist/modules/staff/backend/staff/timesheets/projects/create/page.meta.js +1 -7
  221. package/dist/modules/staff/backend/staff/timesheets/projects/create/page.meta.js.map +2 -2
  222. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +4 -613
  223. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  224. package/dist/modules/staff/backend/staff/timesheets/projects/page.meta.js +2 -17
  225. package/dist/modules/staff/backend/staff/timesheets/projects/page.meta.js.map +2 -2
  226. package/dist/modules/staff/ce.js +40 -0
  227. package/dist/modules/staff/ce.js.map +2 -2
  228. package/dist/modules/staff/cli.js +166 -1
  229. package/dist/modules/staff/cli.js.map +2 -2
  230. package/dist/modules/staff/commands/index.js +5 -0
  231. package/dist/modules/staff/commands/index.js.map +2 -2
  232. package/dist/modules/staff/commands/timesheets-entries.js +569 -21
  233. package/dist/modules/staff/commands/timesheets-entries.js.map +3 -3
  234. package/dist/modules/staff/commands/timesheets-projects.js +450 -7
  235. package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
  236. package/dist/modules/staff/commands/timesheets-reports.js +1036 -0
  237. package/dist/modules/staff/commands/timesheets-reports.js.map +7 -0
  238. package/dist/modules/staff/commands/timesheets-tags.js +1015 -0
  239. package/dist/modules/staff/commands/timesheets-tags.js.map +7 -0
  240. package/dist/modules/staff/commands/timesheets-task-comments.js +438 -0
  241. package/dist/modules/staff/commands/timesheets-task-comments.js.map +7 -0
  242. package/dist/modules/staff/commands/timesheets-task-statuses.js +723 -0
  243. package/dist/modules/staff/commands/timesheets-task-statuses.js.map +7 -0
  244. package/dist/modules/staff/commands/timesheets-tasks.js +834 -0
  245. package/dist/modules/staff/commands/timesheets-tasks.js.map +7 -0
  246. package/dist/modules/staff/data/enrichers.js +426 -12
  247. package/dist/modules/staff/data/enrichers.js.map +2 -2
  248. package/dist/modules/staff/data/entities.js +552 -3
  249. package/dist/modules/staff/data/entities.js.map +2 -2
  250. package/dist/modules/staff/data/extensions.js +41 -0
  251. package/dist/modules/staff/data/extensions.js.map +7 -0
  252. package/dist/modules/staff/data/validators.js +254 -9
  253. package/dist/modules/staff/data/validators.js.map +2 -2
  254. package/dist/modules/staff/di.js +42 -1
  255. package/dist/modules/staff/di.js.map +2 -2
  256. package/dist/modules/staff/events.js +84 -6
  257. package/dist/modules/staff/events.js.map +2 -2
  258. package/dist/modules/staff/events.payloads.js +158 -0
  259. package/dist/modules/staff/events.payloads.js.map +7 -0
  260. package/dist/modules/staff/extension-points.js +261 -0
  261. package/dist/modules/staff/extension-points.js.map +7 -0
  262. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.js +138 -0
  263. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.js.map +7 -0
  264. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.meta.js +12 -0
  265. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.meta.js.map +7 -0
  266. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.js +133 -0
  267. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.js.map +7 -0
  268. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.meta.js +19 -0
  269. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.meta.js.map +7 -0
  270. package/dist/modules/staff/lib/crud.js +11 -1
  271. package/dist/modules/staff/lib/crud.js.map +2 -2
  272. package/dist/modules/staff/lib/time-tracking/access.js +92 -0
  273. package/dist/modules/staff/lib/time-tracking/access.js.map +7 -0
  274. package/dist/modules/staff/lib/time-tracking/billability.js +39 -0
  275. package/dist/modules/staff/lib/time-tracking/billability.js.map +7 -0
  276. package/dist/modules/staff/lib/time-tracking/capacity.js +68 -0
  277. package/dist/modules/staff/lib/time-tracking/capacity.js.map +7 -0
  278. package/dist/modules/staff/lib/time-tracking/componentContracts.js +15 -0
  279. package/dist/modules/staff/lib/time-tracking/componentContracts.js.map +7 -0
  280. package/dist/modules/staff/lib/time-tracking/cost.js +82 -0
  281. package/dist/modules/staff/lib/time-tracking/cost.js.map +7 -0
  282. package/dist/modules/staff/lib/time-tracking/duration.js +55 -0
  283. package/dist/modules/staff/lib/time-tracking/duration.js.map +7 -0
  284. package/dist/modules/staff/lib/time-tracking/featureAccess.js +41 -0
  285. package/dist/modules/staff/lib/time-tracking/featureAccess.js.map +7 -0
  286. package/dist/modules/staff/lib/time-tracking/interval.js +72 -0
  287. package/dist/modules/staff/lib/time-tracking/interval.js.map +7 -0
  288. package/dist/modules/staff/lib/time-tracking/migrateProjectCodes.js +88 -0
  289. package/dist/modules/staff/lib/time-tracking/migrateProjectCodes.js.map +7 -0
  290. package/dist/modules/staff/lib/time-tracking/moneyVisibility.js +10 -0
  291. package/dist/modules/staff/lib/time-tracking/moneyVisibility.js.map +7 -0
  292. package/dist/modules/staff/lib/time-tracking/overlap.js +87 -0
  293. package/dist/modules/staff/lib/time-tracking/overlap.js.map +7 -0
  294. package/dist/modules/staff/lib/time-tracking/portalRecipients.js +27 -0
  295. package/dist/modules/staff/lib/time-tracking/portalRecipients.js.map +7 -0
  296. package/dist/modules/staff/lib/time-tracking/portalReports.js +16 -0
  297. package/dist/modules/staff/lib/time-tracking/portalReports.js.map +7 -0
  298. package/dist/modules/staff/lib/time-tracking/projectCode.js +135 -0
  299. package/dist/modules/staff/lib/time-tracking/projectCode.js.map +7 -0
  300. package/dist/modules/staff/lib/time-tracking/reapplyRounding.js +187 -0
  301. package/dist/modules/staff/lib/time-tracking/reapplyRounding.js.map +7 -0
  302. package/dist/modules/staff/lib/time-tracking/recalculationRunner.js +80 -0
  303. package/dist/modules/staff/lib/time-tracking/recalculationRunner.js.map +7 -0
  304. package/dist/modules/staff/lib/time-tracking/recalculations.js +56 -0
  305. package/dist/modules/staff/lib/time-tracking/recalculations.js.map +7 -0
  306. package/dist/modules/staff/lib/time-tracking/registries/invoke.js +63 -0
  307. package/dist/modules/staff/lib/time-tracking/registries/invoke.js.map +7 -0
  308. package/dist/modules/staff/lib/time-tracking/registries/registry.js +62 -0
  309. package/dist/modules/staff/lib/time-tracking/registries/registry.js.map +7 -0
  310. package/dist/modules/staff/lib/time-tracking/registries/scope.js +21 -0
  311. package/dist/modules/staff/lib/time-tracking/registries/scope.js.map +7 -0
  312. package/dist/modules/staff/lib/time-tracking/rollup.js +34 -0
  313. package/dist/modules/staff/lib/time-tracking/rollup.js.map +7 -0
  314. package/dist/modules/staff/lib/time-tracking/rounding.js +66 -0
  315. package/dist/modules/staff/lib/time-tracking/rounding.js.map +7 -0
  316. package/dist/modules/staff/lib/time-tracking/roundingImpact.js +39 -0
  317. package/dist/modules/staff/lib/time-tracking/roundingImpact.js.map +7 -0
  318. package/dist/modules/staff/lib/time-tracking/settingKeys.js +214 -0
  319. package/dist/modules/staff/lib/time-tracking/settingKeys.js.map +7 -0
  320. package/dist/modules/staff/lib/time-tracking/settings.js +87 -0
  321. package/dist/modules/staff/lib/time-tracking/settings.js.map +7 -0
  322. package/dist/modules/staff/lib/time-tracking/sqlInClause.js +9 -0
  323. package/dist/modules/staff/lib/time-tracking/sqlInClause.js.map +7 -0
  324. package/dist/modules/staff/lib/time-tracking/timeEntrySources.js +48 -0
  325. package/dist/modules/staff/lib/time-tracking/timeEntrySources.js.map +7 -0
  326. package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js +283 -0
  327. package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js.map +7 -0
  328. package/dist/modules/staff/lib/time-tracking-ui/CustomerPicker.js +324 -0
  329. package/dist/modules/staff/lib/time-tracking-ui/CustomerPicker.js.map +7 -0
  330. package/dist/modules/staff/lib/time-tracking-ui/DurationInput.js +121 -0
  331. package/dist/modules/staff/lib/time-tracking-ui/DurationInput.js.map +7 -0
  332. package/dist/modules/staff/lib/time-tracking-ui/EntryDetailsFields.js +188 -0
  333. package/dist/modules/staff/lib/time-tracking-ui/EntryDetailsFields.js.map +7 -0
  334. package/dist/modules/staff/lib/time-tracking-ui/EntryFilterBar.js +89 -0
  335. package/dist/modules/staff/lib/time-tracking-ui/EntryFilterBar.js.map +7 -0
  336. package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js +855 -0
  337. package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js.map +7 -0
  338. package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js +360 -0
  339. package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js.map +7 -0
  340. package/dist/modules/staff/lib/time-tracking-ui/KanbanColumn.js +259 -0
  341. package/dist/modules/staff/lib/time-tracking-ui/KanbanColumn.js.map +7 -0
  342. package/dist/modules/staff/lib/time-tracking-ui/NewTaskDialog.js +238 -0
  343. package/dist/modules/staff/lib/time-tracking-ui/NewTaskDialog.js.map +7 -0
  344. package/dist/modules/staff/lib/time-tracking-ui/NoProjectAccess.js +130 -0
  345. package/dist/modules/staff/lib/time-tracking-ui/NoProjectAccess.js.map +7 -0
  346. package/dist/modules/staff/lib/time-tracking-ui/PeriodSelector.js +98 -0
  347. package/dist/modules/staff/lib/time-tracking-ui/PeriodSelector.js.map +7 -0
  348. package/dist/modules/staff/lib/time-tracking-ui/PhasePlaceholder.js +27 -0
  349. package/dist/modules/staff/lib/time-tracking-ui/PhasePlaceholder.js.map +7 -0
  350. package/dist/modules/staff/lib/time-tracking-ui/ProjectCodeField.js +166 -0
  351. package/dist/modules/staff/lib/time-tracking-ui/ProjectCodeField.js.map +7 -0
  352. package/dist/modules/staff/lib/time-tracking-ui/ProjectCurrencyField.js +295 -0
  353. package/dist/modules/staff/lib/time-tracking-ui/ProjectCurrencyField.js.map +7 -0
  354. package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js +212 -0
  355. package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js.map +7 -0
  356. package/dist/modules/staff/lib/time-tracking-ui/ProjectTeamDrawer.js +729 -0
  357. package/dist/modules/staff/lib/time-tracking-ui/ProjectTeamDrawer.js.map +7 -0
  358. package/dist/modules/staff/lib/time-tracking-ui/ReportSheet.js +217 -0
  359. package/dist/modules/staff/lib/time-tracking-ui/ReportSheet.js.map +7 -0
  360. package/dist/modules/staff/lib/time-tracking-ui/TagPicker.js +158 -0
  361. package/dist/modules/staff/lib/time-tracking-ui/TagPicker.js.map +7 -0
  362. package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js +224 -0
  363. package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js.map +7 -0
  364. package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js +93 -0
  365. package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js.map +7 -0
  366. package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js +1196 -0
  367. package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js.map +7 -0
  368. package/dist/modules/staff/lib/time-tracking-ui/TaskListView.js +176 -0
  369. package/dist/modules/staff/lib/time-tracking-ui/TaskListView.js.map +7 -0
  370. package/dist/modules/staff/lib/time-tracking-ui/TaskPicker.js +307 -0
  371. package/dist/modules/staff/lib/time-tracking-ui/TaskPicker.js.map +7 -0
  372. package/dist/modules/staff/lib/time-tracking-ui/TaskQuickLog.js +284 -0
  373. package/dist/modules/staff/lib/time-tracking-ui/TaskQuickLog.js.map +7 -0
  374. package/dist/modules/staff/lib/time-tracking-ui/TimeEntriesSummaryFooter.js +73 -0
  375. package/dist/modules/staff/lib/time-tracking-ui/TimeEntriesSummaryFooter.js.map +7 -0
  376. package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDialog.js +1499 -0
  377. package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDialog.js.map +7 -0
  378. package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDurationCell.js +95 -0
  379. package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDurationCell.js.map +7 -0
  380. package/dist/modules/staff/lib/time-tracking-ui/TimesheetCalendar.js +188 -0
  381. package/dist/modules/staff/lib/time-tracking-ui/TimesheetCalendar.js.map +7 -0
  382. package/dist/modules/staff/lib/time-tracking-ui/TimesheetPeriodFooter.js +61 -0
  383. package/dist/modules/staff/lib/time-tracking-ui/TimesheetPeriodFooter.js.map +7 -0
  384. package/dist/modules/staff/lib/time-tracking-ui/TimesheetViewSwitch.js +45 -0
  385. package/dist/modules/staff/lib/time-tracking-ui/TimesheetViewSwitch.js.map +7 -0
  386. package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js +176 -0
  387. package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js.map +7 -0
  388. package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js +82 -0
  389. package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js.map +7 -0
  390. package/dist/modules/staff/lib/time-tracking-ui/boardSummary.js +5 -0
  391. package/dist/modules/staff/lib/time-tracking-ui/boardSummary.js.map +7 -0
  392. package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js +152 -0
  393. package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js.map +7 -0
  394. package/dist/modules/staff/lib/time-tracking-ui/projectTeamAssignment.js +92 -0
  395. package/dist/modules/staff/lib/time-tracking-ui/projectTeamAssignment.js.map +7 -0
  396. package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js +111 -0
  397. package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js.map +7 -0
  398. package/dist/modules/staff/lib/time-tracking-ui/timeEntryDialogState.js +243 -0
  399. package/dist/modules/staff/lib/time-tracking-ui/timeEntryDialogState.js.map +7 -0
  400. package/dist/modules/staff/lib/time-tracking-ui/timeEntryListData.js +151 -0
  401. package/dist/modules/staff/lib/time-tracking-ui/timeEntryListData.js.map +7 -0
  402. package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js +105 -0
  403. package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js.map +7 -0
  404. package/dist/modules/staff/lib/time-tracking-ui/timesheetData.js +132 -0
  405. package/dist/modules/staff/lib/time-tracking-ui/timesheetData.js.map +7 -0
  406. package/dist/modules/staff/lib/time-tracking-ui/timesheetPeriod.js +205 -0
  407. package/dist/modules/staff/lib/time-tracking-ui/timesheetPeriod.js.map +7 -0
  408. package/dist/modules/staff/lib/time-tracking-ui/timesheetTargets.js +53 -0
  409. package/dist/modules/staff/lib/time-tracking-ui/timesheetTargets.js.map +7 -0
  410. package/dist/modules/staff/lib/time-tracking-ui/useBoardFilters.js +77 -0
  411. package/dist/modules/staff/lib/time-tracking-ui/useBoardFilters.js.map +7 -0
  412. package/dist/modules/staff/lib/time-tracking-ui/useTimesheetPreferences.js +151 -0
  413. package/dist/modules/staff/lib/time-tracking-ui/useTimesheetPreferences.js.map +7 -0
  414. package/dist/modules/staff/lib/timeTrackingSeeds.js +809 -0
  415. package/dist/modules/staff/lib/timeTrackingSeeds.js.map +7 -0
  416. package/dist/modules/staff/lib/timesheets/timeEntryCacheInvalidation.js +2 -3
  417. package/dist/modules/staff/lib/timesheets/timeEntryCacheInvalidation.js.map +2 -2
  418. package/dist/modules/staff/lib/timesheets/timeEntryDecoration.js +152 -0
  419. package/dist/modules/staff/lib/timesheets/timeEntryDecoration.js.map +7 -0
  420. package/dist/modules/staff/lib/timesheets-projects/budgetBurn.js +36 -0
  421. package/dist/modules/staff/lib/timesheets-projects/budgetBurn.js.map +7 -0
  422. package/dist/modules/staff/lib/timesheets-projects/budgetThreshold.js +66 -0
  423. package/dist/modules/staff/lib/timesheets-projects/budgetThreshold.js.map +7 -0
  424. package/dist/modules/staff/lib/timesheets-projects/budgetThresholdState.js +78 -0
  425. package/dist/modules/staff/lib/timesheets-projects/budgetThresholdState.js.map +7 -0
  426. package/dist/modules/staff/lib/timesheets-projects/computeProjectFinancials.js +81 -0
  427. package/dist/modules/staff/lib/timesheets-projects/computeProjectFinancials.js.map +7 -0
  428. package/dist/modules/staff/lib/timesheets-projects/reportSelection.js +44 -0
  429. package/dist/modules/staff/lib/timesheets-projects/reportSelection.js.map +7 -0
  430. package/dist/modules/staff/lib/timesheets-projects-ui/AssignMembersDialog.js +169 -0
  431. package/dist/modules/staff/lib/timesheets-projects-ui/AssignMembersDialog.js.map +7 -0
  432. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectBudgetCell.js +22 -0
  433. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectBudgetCell.js.map +7 -0
  434. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectCard.js +51 -1
  435. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectCard.js.map +2 -2
  436. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectsBulkActionsBar.js +70 -0
  437. package/dist/modules/staff/lib/timesheets-projects-ui/ProjectsBulkActionsBar.js.map +7 -0
  438. package/dist/modules/staff/lib/timesheets-reports/buildReportSheet.js +63 -0
  439. package/dist/modules/staff/lib/timesheets-reports/buildReportSheet.js.map +7 -0
  440. package/dist/modules/staff/lib/timesheets-reports/loadReportData.js +170 -0
  441. package/dist/modules/staff/lib/timesheets-reports/loadReportData.js.map +7 -0
  442. package/dist/modules/staff/lib/timesheets-reports/pdf.js +205 -0
  443. package/dist/modules/staff/lib/timesheets-reports/pdf.js.map +7 -0
  444. package/dist/modules/staff/lib/timesheets-reports/reportApprovalPolicies.js +68 -0
  445. package/dist/modules/staff/lib/timesheets-reports/reportApprovalPolicies.js.map +7 -0
  446. package/dist/modules/staff/lib/timesheets-reports/reportConfigData.js +135 -0
  447. package/dist/modules/staff/lib/timesheets-reports/reportConfigData.js.map +7 -0
  448. package/dist/modules/staff/lib/timesheets-reports/reportConfigState.js +48 -0
  449. package/dist/modules/staff/lib/timesheets-reports/reportConfigState.js.map +7 -0
  450. package/dist/modules/staff/lib/timesheets-reports/reportExport.js +262 -0
  451. package/dist/modules/staff/lib/timesheets-reports/reportExport.js.map +7 -0
  452. package/dist/modules/staff/lib/timesheets-reports/reportExportFormats.js +34 -0
  453. package/dist/modules/staff/lib/timesheets-reports/reportExportFormats.js.map +7 -0
  454. package/dist/modules/staff/lib/timesheets-reports/reportGroupings.js +79 -0
  455. package/dist/modules/staff/lib/timesheets-reports/reportGroupings.js.map +7 -0
  456. package/dist/modules/staff/lib/timesheets-reports/reportLabels.js +11 -0
  457. package/dist/modules/staff/lib/timesheets-reports/reportLabels.js.map +7 -0
  458. package/dist/modules/staff/lib/timesheets-reports/reportReference.js +83 -0
  459. package/dist/modules/staff/lib/timesheets-reports/reportReference.js.map +7 -0
  460. package/dist/modules/staff/lib/timesheets-reports/reportRows.js +42 -0
  461. package/dist/modules/staff/lib/timesheets-reports/reportRows.js.map +7 -0
  462. package/dist/modules/staff/lib/timesheets-reports/reportSheetData.js +107 -0
  463. package/dist/modules/staff/lib/timesheets-reports/reportSheetData.js.map +7 -0
  464. package/dist/modules/staff/lib/timesheets-reports/reportTotals.js +289 -0
  465. package/dist/modules/staff/lib/timesheets-reports/reportTotals.js.map +7 -0
  466. package/dist/modules/staff/lib/timesheets-reports/xlsx.js +145 -0
  467. package/dist/modules/staff/lib/timesheets-reports/xlsx.js.map +7 -0
  468. package/dist/modules/staff/lib/timesheets-tasks/computeTaskRollups.js +116 -0
  469. package/dist/modules/staff/lib/timesheets-tasks/computeTaskRollups.js.map +7 -0
  470. package/dist/modules/staff/lib/timesheets-tasks/defaultStatusTemplate.js +50 -0
  471. package/dist/modules/staff/lib/timesheets-tasks/defaultStatusTemplate.js.map +7 -0
  472. package/dist/modules/staff/lib/timesheets-tasks/seedProjectStatuses.js +27 -0
  473. package/dist/modules/staff/lib/timesheets-tasks/seedProjectStatuses.js.map +7 -0
  474. package/dist/modules/staff/lib/timesheets-tasks/statusPositions.js +65 -0
  475. package/dist/modules/staff/lib/timesheets-tasks/statusPositions.js.map +7 -0
  476. package/dist/modules/staff/lib/timesheets-tasks/statusSlug.js +31 -0
  477. package/dist/modules/staff/lib/timesheets-tasks/statusSlug.js.map +7 -0
  478. package/dist/modules/staff/lib/timesheets-tasks/taskHierarchy.js +31 -0
  479. package/dist/modules/staff/lib/timesheets-tasks/taskHierarchy.js.map +7 -0
  480. package/dist/modules/staff/lib/timesheets-tasks/taskHoursTotals.js +17 -0
  481. package/dist/modules/staff/lib/timesheets-tasks/taskHoursTotals.js.map +7 -0
  482. package/dist/modules/staff/lib/timesheets-tasks/taskReference.js +51 -0
  483. package/dist/modules/staff/lib/timesheets-tasks/taskReference.js.map +7 -0
  484. package/dist/modules/staff/lib/timesheets-ui/CreateProjectDialog.js +11 -4
  485. package/dist/modules/staff/lib/timesheets-ui/CreateProjectDialog.js.map +2 -2
  486. package/dist/modules/staff/lib/timesheets-ui/ListView.js +369 -111
  487. package/dist/modules/staff/lib/timesheets-ui/ListView.js.map +2 -2
  488. package/dist/modules/staff/lib/timesheets-ui/TimerBar.js +47 -2
  489. package/dist/modules/staff/lib/timesheets-ui/TimerBar.js.map +2 -2
  490. package/dist/modules/staff/migrations/Migration20260813073131_staff.js +79 -0
  491. package/dist/modules/staff/migrations/Migration20260813073131_staff.js.map +7 -0
  492. package/dist/modules/staff/migrations/Migration20260824143357_staff.js +15 -0
  493. package/dist/modules/staff/migrations/Migration20260824143357_staff.js.map +7 -0
  494. package/dist/modules/staff/notifications.client.js +16 -0
  495. package/dist/modules/staff/notifications.client.js.map +7 -0
  496. package/dist/modules/staff/notifications.handlers.js +80 -0
  497. package/dist/modules/staff/notifications.handlers.js.map +7 -0
  498. package/dist/modules/staff/notifications.js +168 -0
  499. package/dist/modules/staff/notifications.js.map +2 -2
  500. package/dist/modules/staff/search.js +159 -1
  501. package/dist/modules/staff/search.js.map +2 -2
  502. package/dist/modules/staff/setup.js +20 -1
  503. package/dist/modules/staff/setup.js.map +2 -2
  504. package/dist/modules/staff/subscribers/time-project-access-requested-notification.js +68 -0
  505. package/dist/modules/staff/subscribers/time-project-access-requested-notification.js.map +7 -0
  506. package/dist/modules/staff/subscribers/time-project-budget-threshold-notification.js +149 -0
  507. package/dist/modules/staff/subscribers/time-project-budget-threshold-notification.js.map +7 -0
  508. package/dist/modules/staff/subscribers/time-report-approved-notification.js +78 -0
  509. package/dist/modules/staff/subscribers/time-report-approved-notification.js.map +7 -0
  510. package/dist/modules/staff/subscribers/time-report-portal-broadcast.js +78 -0
  511. package/dist/modules/staff/subscribers/time-report-portal-broadcast.js.map +7 -0
  512. package/dist/modules/staff/translations.js +4 -1
  513. package/dist/modules/staff/translations.js.map +2 -2
  514. package/dist/modules/staff/widgets/components.js +7 -0
  515. package/dist/modules/staff/widgets/components.js.map +7 -0
  516. package/dist/modules/staff/widgets/injection/timer-sidebar-indicator/widget.js +5 -4
  517. package/dist/modules/staff/widgets/injection/timer-sidebar-indicator/widget.js.map +2 -2
  518. package/dist/modules/staff/widgets/notifications/TimeProjectAccessRequestedRenderer.js +135 -0
  519. package/dist/modules/staff/widgets/notifications/TimeProjectAccessRequestedRenderer.js.map +7 -0
  520. package/dist/modules/staff/widgets/notifications/index.js +5 -0
  521. package/dist/modules/staff/widgets/notifications/index.js.map +7 -0
  522. package/dist/modules/staff/workers/timesheets-reapply-rounding.js +43 -0
  523. package/dist/modules/staff/workers/timesheets-reapply-rounding.js.map +7 -0
  524. package/generated/entities/staff_time_entry/index.ts +7 -0
  525. package/generated/entities/staff_time_entry_tag/index.ts +6 -0
  526. package/generated/entities/staff_time_project/index.ts +8 -0
  527. package/generated/entities/staff_time_report/index.ts +27 -0
  528. package/generated/entities/staff_time_report_entry/index.ts +12 -0
  529. package/generated/entities/staff_time_report_event/index.ts +9 -0
  530. package/generated/entities/staff_time_report_project/index.ts +6 -0
  531. package/generated/entities/staff_time_tag/index.ts +9 -0
  532. package/generated/entities/staff_time_task/index.ts +17 -0
  533. package/generated/entities/staff_time_task_comment/index.ts +9 -0
  534. package/generated/entities/staff_time_task_status/index.ts +13 -0
  535. package/generated/entities/staff_time_task_tag/index.ts +6 -0
  536. package/generated/entities.ids.generated.ts +11 -1
  537. package/generated/entity-fields-registry.ts +149 -0
  538. package/package.json +7 -7
  539. package/src/helpers/integration/timesheetFixtures.ts +31 -1
  540. package/src/modules/auth/README.md +1 -1
  541. package/src/modules/auth/cli.ts +35 -1
  542. package/src/modules/auth/i18n/de.json +7 -0
  543. package/src/modules/auth/i18n/en.json +7 -0
  544. package/src/modules/auth/i18n/es.json +7 -0
  545. package/src/modules/auth/i18n/ko.json +7 -0
  546. package/src/modules/auth/i18n/pl.json +7 -0
  547. package/src/modules/auth/lib/backendChrome.tsx +1 -0
  548. package/src/modules/customer_accounts/lib/customerRoleAcls.ts +79 -0
  549. package/src/modules/customer_accounts/setup.ts +1 -45
  550. package/src/modules/data_sync/AGENTS.md +34 -0
  551. package/src/modules/data_sync/api/options.ts +2 -0
  552. package/src/modules/data_sync/backend/data-sync/page.tsx +82 -33
  553. package/src/modules/data_sync/i18n/de.json +1 -0
  554. package/src/modules/data_sync/i18n/en.json +1 -0
  555. package/src/modules/data_sync/i18n/es.json +1 -0
  556. package/src/modules/data_sync/i18n/ko.json +1 -0
  557. package/src/modules/data_sync/i18n/pl.json +1 -0
  558. package/src/modules/data_sync/lib/adapter.ts +45 -0
  559. package/src/modules/data_sync/lib/start-controls.ts +89 -0
  560. package/src/modules/staff/AGENTS.md +769 -1
  561. package/src/modules/staff/acl.ts +9 -0
  562. package/src/modules/staff/ai-agents.ts +189 -0
  563. package/src/modules/staff/ai-tools/time-tracking-pack.ts +494 -0
  564. package/src/modules/staff/ai-tools/types.ts +82 -0
  565. package/src/modules/staff/ai-tools.ts +13 -0
  566. package/src/modules/staff/analytics.ts +113 -0
  567. package/src/modules/staff/api/guards.ts +85 -3
  568. package/src/modules/staff/api/leave-requests/accept/route.ts +0 -2
  569. package/src/modules/staff/api/leave-requests/reject/route.ts +0 -2
  570. package/src/modules/staff/api/portal/time-reports/[id]/route.ts +182 -0
  571. package/src/modules/staff/api/portal/time-reports/route.ts +270 -0
  572. package/src/modules/staff/api/team-members/self/route.ts +0 -2
  573. package/src/modules/staff/api/team-members/tags/assign/route.ts +0 -2
  574. package/src/modules/staff/api/team-members/tags/unassign/route.ts +0 -2
  575. package/src/modules/staff/api/timesheets/_shared/withTimesheetInterceptors.ts +292 -0
  576. package/src/modules/staff/api/timesheets/access-requests/route.ts +299 -0
  577. package/src/modules/staff/api/timesheets/my-projects/[projectId]/route.ts +15 -7
  578. package/src/modules/staff/api/timesheets/my-projects/route.ts +14 -1
  579. package/src/modules/staff/api/timesheets/my-work/myWorkAggregate.ts +90 -0
  580. package/src/modules/staff/api/timesheets/my-work/route.ts +475 -0
  581. package/src/modules/staff/api/timesheets/projects/kpis/route.ts +15 -2
  582. package/src/modules/staff/api/timesheets/reports/[id]/close/route.ts +203 -0
  583. package/src/modules/staff/api/timesheets/reports/[id]/export/route.ts +315 -0
  584. package/src/modules/staff/api/timesheets/reports/[id]/sheet/route.ts +220 -0
  585. package/src/modules/staff/api/timesheets/reports/[id]/unlock/route.ts +208 -0
  586. package/src/modules/staff/api/timesheets/reports/preview/route.ts +449 -0
  587. package/src/modules/staff/api/timesheets/reports/route.ts +386 -0
  588. package/src/modules/staff/api/timesheets/reports/shared.ts +121 -0
  589. package/src/modules/staff/api/timesheets/settings/reapply-rounding/route.ts +205 -0
  590. package/src/modules/staff/api/timesheets/settings/rounding-impact/route.ts +226 -0
  591. package/src/modules/staff/api/timesheets/settings/route.ts +242 -0
  592. package/src/modules/staff/api/timesheets/tags/access.ts +134 -0
  593. package/src/modules/staff/api/timesheets/tags/entry-assignments/route.ts +290 -0
  594. package/src/modules/staff/api/timesheets/tags/route.ts +177 -0
  595. package/src/modules/staff/api/timesheets/tags/task-assignments/route.ts +294 -0
  596. package/src/modules/staff/api/timesheets/task-statuses/route.ts +232 -0
  597. package/src/modules/staff/api/timesheets/tasks/[id]/comments/route.ts +532 -0
  598. package/src/modules/staff/api/timesheets/tasks/[id]/status/route.ts +271 -0
  599. package/src/modules/staff/api/timesheets/tasks/route.ts +443 -0
  600. package/src/modules/staff/api/timesheets/time-entries/[id]/duplicate/route.ts +306 -0
  601. package/src/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.ts +32 -10
  602. package/src/modules/staff/api/timesheets/time-entries/[id]/segments/route.ts +32 -17
  603. package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +27 -6
  604. package/src/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.ts +36 -6
  605. package/src/modules/staff/api/timesheets/time-entries/bulk/route.ts +331 -34
  606. package/src/modules/staff/api/timesheets/time-entries/copy-day/route.ts +533 -0
  607. package/src/modules/staff/api/timesheets/time-entries/overlaps/route.ts +457 -0
  608. package/src/modules/staff/api/timesheets/time-entries/route.ts +378 -24
  609. package/src/modules/staff/api/timesheets/time-entries/start-timer/route.ts +31 -9
  610. package/src/modules/staff/api/timesheets/time-projects/[id]/change-currency/route.ts +246 -0
  611. package/src/modules/staff/api/timesheets/time-projects/[id]/employees/route.ts +62 -2
  612. package/src/modules/staff/api/timesheets/time-projects/route.ts +397 -22
  613. package/src/modules/staff/backend/staff/time-tracking/board/page.meta.ts +14 -0
  614. package/src/modules/staff/backend/staff/time-tracking/board/page.tsx +151 -0
  615. package/src/modules/staff/backend/staff/time-tracking/entries/page.meta.ts +14 -0
  616. package/src/modules/staff/backend/staff/time-tracking/entries/page.tsx +1229 -0
  617. package/src/modules/staff/backend/staff/time-tracking/page.meta.ts +11 -0
  618. package/src/modules/staff/backend/staff/time-tracking/page.tsx +823 -0
  619. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.meta.ts +12 -0
  620. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.tsx +81 -0
  621. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.meta.ts +12 -0
  622. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.tsx +275 -0
  623. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.meta.ts +12 -0
  624. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +1420 -0
  625. package/src/modules/staff/backend/staff/time-tracking/projects/create/page.meta.ts +12 -0
  626. package/src/modules/staff/backend/staff/time-tracking/projects/create/page.tsx +109 -0
  627. package/src/modules/staff/backend/staff/time-tracking/projects/page.meta.ts +15 -0
  628. package/src/modules/staff/backend/staff/time-tracking/projects/page.tsx +1254 -0
  629. package/src/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.ts +466 -0
  630. package/src/modules/staff/backend/staff/time-tracking/reports/[id]/page.meta.ts +12 -0
  631. package/src/modules/staff/backend/staff/time-tracking/reports/[id]/page.tsx +632 -0
  632. package/src/modules/staff/backend/staff/time-tracking/reports/create/page.meta.ts +12 -0
  633. package/src/modules/staff/backend/staff/time-tracking/reports/create/page.tsx +867 -0
  634. package/src/modules/staff/backend/staff/time-tracking/reports/page.meta.ts +14 -0
  635. package/src/modules/staff/backend/staff/time-tracking/reports/page.tsx +246 -0
  636. package/src/modules/staff/backend/staff/time-tracking/settings/page.meta.ts +14 -0
  637. package/src/modules/staff/backend/staff/time-tracking/settings/page.tsx +701 -0
  638. package/src/modules/staff/backend/staff/time-tracking/timesheet/GridView.tsx +953 -0
  639. package/src/modules/staff/backend/staff/time-tracking/timesheet/page.meta.ts +14 -0
  640. package/src/modules/staff/backend/staff/time-tracking/timesheet/page.tsx +800 -0
  641. package/src/modules/staff/backend/staff/timesheets/page.meta.ts +6 -6
  642. package/src/modules/staff/backend/staff/timesheets/page.tsx +12 -1010
  643. package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.ts +0 -6
  644. package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.tsx +4 -158
  645. package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.ts +0 -6
  646. package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +4 -609
  647. package/src/modules/staff/backend/staff/timesheets/projects/create/page.meta.ts +0 -6
  648. package/src/modules/staff/backend/staff/timesheets/projects/create/page.tsx +3 -89
  649. package/src/modules/staff/backend/staff/timesheets/projects/page.meta.ts +2 -19
  650. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +3 -778
  651. package/src/modules/staff/ce.ts +63 -0
  652. package/src/modules/staff/cli.ts +207 -1
  653. package/src/modules/staff/commands/index.ts +5 -0
  654. package/src/modules/staff/commands/timesheets-entries.ts +1006 -28
  655. package/src/modules/staff/commands/timesheets-projects.ts +593 -7
  656. package/src/modules/staff/commands/timesheets-reports.ts +1329 -0
  657. package/src/modules/staff/commands/timesheets-tags.ts +1315 -0
  658. package/src/modules/staff/commands/timesheets-task-comments.ts +583 -0
  659. package/src/modules/staff/commands/timesheets-task-statuses.ts +889 -0
  660. package/src/modules/staff/commands/timesheets-tasks.ts +1121 -0
  661. package/src/modules/staff/data/enrichers.ts +675 -10
  662. package/src/modules/staff/data/entities.ts +494 -2
  663. package/src/modules/staff/data/extensions.ts +68 -0
  664. package/src/modules/staff/data/validators.ts +348 -3
  665. package/src/modules/staff/di.ts +96 -0
  666. package/src/modules/staff/events.payloads.ts +268 -0
  667. package/src/modules/staff/events.ts +87 -5
  668. package/src/modules/staff/extension-points.ts +308 -0
  669. package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.meta.ts +10 -0
  670. package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.tsx +225 -0
  671. package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/page.meta.ts +17 -0
  672. package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/page.tsx +182 -0
  673. package/src/modules/staff/i18n/de.json +899 -0
  674. package/src/modules/staff/i18n/en.json +899 -0
  675. package/src/modules/staff/i18n/es.json +899 -0
  676. package/src/modules/staff/i18n/ko.json +899 -0
  677. package/src/modules/staff/i18n/pl.json +899 -0
  678. package/src/modules/staff/lib/crud.ts +14 -3
  679. package/src/modules/staff/lib/time-tracking/access.ts +155 -0
  680. package/src/modules/staff/lib/time-tracking/billability.ts +68 -0
  681. package/src/modules/staff/lib/time-tracking/capacity.ts +124 -0
  682. package/src/modules/staff/lib/time-tracking/componentContracts.ts +26 -0
  683. package/src/modules/staff/lib/time-tracking/cost.ts +144 -0
  684. package/src/modules/staff/lib/time-tracking/duration.ts +68 -0
  685. package/src/modules/staff/lib/time-tracking/featureAccess.ts +115 -0
  686. package/src/modules/staff/lib/time-tracking/interval.ts +90 -0
  687. package/src/modules/staff/lib/time-tracking/migrateProjectCodes.ts +161 -0
  688. package/src/modules/staff/lib/time-tracking/moneyVisibility.ts +37 -0
  689. package/src/modules/staff/lib/time-tracking/overlap.ts +159 -0
  690. package/src/modules/staff/lib/time-tracking/portalRecipients.ts +76 -0
  691. package/src/modules/staff/lib/time-tracking/portalReports.ts +31 -0
  692. package/src/modules/staff/lib/time-tracking/projectCode.ts +221 -0
  693. package/src/modules/staff/lib/time-tracking/reapplyRounding.ts +313 -0
  694. package/src/modules/staff/lib/time-tracking/recalculationRunner.ts +118 -0
  695. package/src/modules/staff/lib/time-tracking/recalculations.ts +135 -0
  696. package/src/modules/staff/lib/time-tracking/registries/invoke.ts +122 -0
  697. package/src/modules/staff/lib/time-tracking/registries/registry.ts +124 -0
  698. package/src/modules/staff/lib/time-tracking/registries/scope.ts +56 -0
  699. package/src/modules/staff/lib/time-tracking/rollup.ts +59 -0
  700. package/src/modules/staff/lib/time-tracking/rounding.ts +126 -0
  701. package/src/modules/staff/lib/time-tracking/roundingImpact.ts +75 -0
  702. package/src/modules/staff/lib/time-tracking/settingKeys.ts +274 -0
  703. package/src/modules/staff/lib/time-tracking/settings.ts +168 -0
  704. package/src/modules/staff/lib/time-tracking/sqlInClause.ts +22 -0
  705. package/src/modules/staff/lib/time-tracking/timeEntrySources.ts +85 -0
  706. package/src/modules/staff/lib/time-tracking-ui/BoardFilterChips.tsx +360 -0
  707. package/src/modules/staff/lib/time-tracking-ui/CustomerPicker.tsx +427 -0
  708. package/src/modules/staff/lib/time-tracking-ui/DurationInput.tsx +192 -0
  709. package/src/modules/staff/lib/time-tracking-ui/EntryDetailsFields.tsx +224 -0
  710. package/src/modules/staff/lib/time-tracking-ui/EntryFilterBar.tsx +144 -0
  711. package/src/modules/staff/lib/time-tracking-ui/KanbanBoard.tsx +1065 -0
  712. package/src/modules/staff/lib/time-tracking-ui/KanbanCard.tsx +435 -0
  713. package/src/modules/staff/lib/time-tracking-ui/KanbanColumn.tsx +316 -0
  714. package/src/modules/staff/lib/time-tracking-ui/NewTaskDialog.tsx +291 -0
  715. package/src/modules/staff/lib/time-tracking-ui/NoProjectAccess.tsx +162 -0
  716. package/src/modules/staff/lib/time-tracking-ui/PeriodSelector.tsx +149 -0
  717. package/src/modules/staff/lib/time-tracking-ui/PhasePlaceholder.tsx +31 -0
  718. package/src/modules/staff/lib/time-tracking-ui/ProjectCodeField.tsx +230 -0
  719. package/src/modules/staff/lib/time-tracking-ui/ProjectCurrencyField.tsx +432 -0
  720. package/src/modules/staff/lib/time-tracking-ui/ProjectFormSections.tsx +323 -0
  721. package/src/modules/staff/lib/time-tracking-ui/ProjectTeamDrawer.tsx +930 -0
  722. package/src/modules/staff/lib/time-tracking-ui/ReportSheet.tsx +357 -0
  723. package/src/modules/staff/lib/time-tracking-ui/TagPicker.tsx +195 -0
  724. package/src/modules/staff/lib/time-tracking-ui/TaskBoardScreen.tsx +243 -0
  725. package/src/modules/staff/lib/time-tracking-ui/TaskCommentThread.tsx +137 -0
  726. package/src/modules/staff/lib/time-tracking-ui/TaskDrawer.tsx +1405 -0
  727. package/src/modules/staff/lib/time-tracking-ui/TaskListView.tsx +260 -0
  728. package/src/modules/staff/lib/time-tracking-ui/TaskPicker.tsx +435 -0
  729. package/src/modules/staff/lib/time-tracking-ui/TaskQuickLog.tsx +296 -0
  730. package/src/modules/staff/lib/time-tracking-ui/TimeEntriesSummaryFooter.tsx +97 -0
  731. package/src/modules/staff/lib/time-tracking-ui/TimeEntryDialog.tsx +1929 -0
  732. package/src/modules/staff/lib/time-tracking-ui/TimeEntryDurationCell.tsx +126 -0
  733. package/src/modules/staff/lib/time-tracking-ui/TimesheetCalendar.tsx +265 -0
  734. package/src/modules/staff/lib/time-tracking-ui/TimesheetPeriodFooter.tsx +78 -0
  735. package/src/modules/staff/lib/time-tracking-ui/TimesheetViewSwitch.tsx +70 -0
  736. package/src/modules/staff/lib/time-tracking-ui/boardDirectory.ts +231 -0
  737. package/src/modules/staff/lib/time-tracking-ui/boardFilters.ts +128 -0
  738. package/src/modules/staff/lib/time-tracking-ui/boardSummary.ts +20 -0
  739. package/src/modules/staff/lib/time-tracking-ui/kanbanBoardData.ts +228 -0
  740. package/src/modules/staff/lib/time-tracking-ui/projectTeamAssignment.ts +143 -0
  741. package/src/modules/staff/lib/time-tracking-ui/taskDrawerData.ts +194 -0
  742. package/src/modules/staff/lib/time-tracking-ui/timeEntryDialogState.ts +400 -0
  743. package/src/modules/staff/lib/time-tracking-ui/timeEntryListData.ts +271 -0
  744. package/src/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.ts +168 -0
  745. package/src/modules/staff/lib/time-tracking-ui/timesheetData.ts +225 -0
  746. package/src/modules/staff/lib/time-tracking-ui/timesheetPeriod.ts +278 -0
  747. package/src/modules/staff/lib/time-tracking-ui/timesheetTargets.ts +93 -0
  748. package/src/modules/staff/lib/time-tracking-ui/useBoardFilters.ts +107 -0
  749. package/src/modules/staff/lib/time-tracking-ui/useTimesheetPreferences.ts +245 -0
  750. package/src/modules/staff/lib/timeTrackingSeeds.ts +1037 -0
  751. package/src/modules/staff/lib/timesheets/timeEntryCacheInvalidation.ts +11 -10
  752. package/src/modules/staff/lib/timesheets/timeEntryDecoration.ts +256 -0
  753. package/src/modules/staff/lib/timesheets-projects/budgetBurn.ts +60 -0
  754. package/src/modules/staff/lib/timesheets-projects/budgetThreshold.ts +135 -0
  755. package/src/modules/staff/lib/timesheets-projects/budgetThresholdState.ts +137 -0
  756. package/src/modules/staff/lib/timesheets-projects/computeProjectFinancials.ts +142 -0
  757. package/src/modules/staff/lib/timesheets-projects/reportSelection.ts +82 -0
  758. package/src/modules/staff/lib/timesheets-projects-ui/AssignMembersDialog.tsx +237 -0
  759. package/src/modules/staff/lib/timesheets-projects-ui/ProjectBudgetCell.tsx +33 -0
  760. package/src/modules/staff/lib/timesheets-projects-ui/ProjectCard.tsx +56 -1
  761. package/src/modules/staff/lib/timesheets-projects-ui/ProjectsBulkActionsBar.tsx +90 -0
  762. package/src/modules/staff/lib/timesheets-reports/buildReportSheet.ts +125 -0
  763. package/src/modules/staff/lib/timesheets-reports/loadReportData.ts +251 -0
  764. package/src/modules/staff/lib/timesheets-reports/pdf.ts +263 -0
  765. package/src/modules/staff/lib/timesheets-reports/reportApprovalPolicies.ts +137 -0
  766. package/src/modules/staff/lib/timesheets-reports/reportConfigData.ts +247 -0
  767. package/src/modules/staff/lib/timesheets-reports/reportConfigState.ts +89 -0
  768. package/src/modules/staff/lib/timesheets-reports/reportExport.ts +373 -0
  769. package/src/modules/staff/lib/timesheets-reports/reportExportFormats.ts +71 -0
  770. package/src/modules/staff/lib/timesheets-reports/reportGroupings.ts +153 -0
  771. package/src/modules/staff/lib/timesheets-reports/reportLabels.ts +23 -0
  772. package/src/modules/staff/lib/timesheets-reports/reportReference.ts +146 -0
  773. package/src/modules/staff/lib/timesheets-reports/reportRows.ts +89 -0
  774. package/src/modules/staff/lib/timesheets-reports/reportSheetData.ts +196 -0
  775. package/src/modules/staff/lib/timesheets-reports/reportTotals.ts +544 -0
  776. package/src/modules/staff/lib/timesheets-reports/xlsx.ts +207 -0
  777. package/src/modules/staff/lib/timesheets-tasks/computeTaskRollups.ts +238 -0
  778. package/src/modules/staff/lib/timesheets-tasks/defaultStatusTemplate.ts +90 -0
  779. package/src/modules/staff/lib/timesheets-tasks/seedProjectStatuses.ts +43 -0
  780. package/src/modules/staff/lib/timesheets-tasks/statusPositions.ts +132 -0
  781. package/src/modules/staff/lib/timesheets-tasks/statusSlug.ts +43 -0
  782. package/src/modules/staff/lib/timesheets-tasks/taskHierarchy.ts +99 -0
  783. package/src/modules/staff/lib/timesheets-tasks/taskHoursTotals.ts +42 -0
  784. package/src/modules/staff/lib/timesheets-tasks/taskReference.ts +108 -0
  785. package/src/modules/staff/lib/timesheets-ui/CreateProjectDialog.tsx +18 -4
  786. package/src/modules/staff/lib/timesheets-ui/ListView.tsx +504 -149
  787. package/src/modules/staff/lib/timesheets-ui/TimerBar.tsx +50 -2
  788. package/src/modules/staff/migrations/.snapshot-open-mercato.json +3244 -228
  789. package/src/modules/staff/migrations/Migration20260813073131_staff.ts +94 -0
  790. package/src/modules/staff/migrations/Migration20260824143357_staff.ts +17 -0
  791. package/src/modules/staff/notifications.client.ts +16 -0
  792. package/src/modules/staff/notifications.handlers.ts +88 -0
  793. package/src/modules/staff/notifications.ts +163 -0
  794. package/src/modules/staff/search.ts +191 -1
  795. package/src/modules/staff/setup.ts +22 -0
  796. package/src/modules/staff/subscribers/time-project-access-requested-notification.ts +95 -0
  797. package/src/modules/staff/subscribers/time-project-budget-threshold-notification.ts +226 -0
  798. package/src/modules/staff/subscribers/time-report-approved-notification.ts +116 -0
  799. package/src/modules/staff/subscribers/time-report-portal-broadcast.ts +120 -0
  800. package/src/modules/staff/translations.ts +17 -0
  801. package/src/modules/staff/widgets/components.ts +34 -0
  802. package/src/modules/staff/widgets/injection/timer-sidebar-indicator/widget.tsx +6 -5
  803. package/src/modules/staff/widgets/notifications/TimeProjectAccessRequestedRenderer.tsx +138 -0
  804. package/src/modules/staff/widgets/notifications/index.ts +1 -0
  805. package/src/modules/staff/workers/timesheets-reapply-rounding.ts +59 -0
  806. package/dist/modules/staff/backend/staff/timesheets/projects/projectFormConfig.js +0 -123
  807. package/dist/modules/staff/backend/staff/timesheets/projects/projectFormConfig.js.map +0 -7
  808. package/src/modules/staff/backend/staff/timesheets/projects/projectFormConfig.ts +0 -138
@@ -0,0 +1,94 @@
1
+ import { Migration } from '@mikro-orm/migrations';
2
+
3
+ export class Migration20260813073131_staff extends Migration {
4
+
5
+ override up(): void | Promise<void> {
6
+ this.addSql(`create table "staff_time_entry_tags" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "tag_id" uuid not null, "time_entry_id" uuid not null, "created_at" timestamptz not null, primary key ("id"));`);
7
+ this.addSql(`create unique index "staff_time_entry_tags_unique_idx" on "staff_time_entry_tags" ("tag_id", "time_entry_id");`);
8
+ this.addSql(`create index "staff_time_entry_tags_entry_idx" on "staff_time_entry_tags" ("organization_id", "time_entry_id");`);
9
+ this.addSql(`create index "staff_time_entry_tags_tenant_org_idx" on "staff_time_entry_tags" ("tenant_id", "organization_id");`);
10
+
11
+ this.addSql(`create table "staff_time_reports" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "customer_id" uuid not null, "customer_snapshot" jsonb null, "reference" text not null, "title" text not null, "period_kind" text not null default 'month', "period_from" date not null, "period_to" date not null, "currency_code" text not null, "grouping" text not null default 'project_task', "nonbillable_mode" text not null default 'separate', "include_already_reported" boolean not null default false, "show_rates" boolean not null default true, "rounding_unit_minutes" int not null default 0, "rounding_direction" text not null default 'up', "status" text not null default 'draft', "total_billable_minutes" int null, "total_nonbillable_minutes" int null, "total_amount" numeric(14,2) null, "closed_at" timestamptz null, "closed_by_user_id" uuid null, "created_by_user_id" uuid null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
12
+ this.addSql(`create unique index "staff_time_reports_reference_unique_idx" on "staff_time_reports" ("organization_id", "tenant_id", "reference") where "deleted_at" is null;`);
13
+ this.addSql(`create index "staff_time_reports_status_idx" on "staff_time_reports" ("organization_id", "status", "period_from");`);
14
+ this.addSql(`create index "staff_time_reports_customer_idx" on "staff_time_reports" ("organization_id", "customer_id");`);
15
+ this.addSql(`create index "staff_time_reports_tenant_org_idx" on "staff_time_reports" ("tenant_id", "organization_id");`);
16
+
17
+ this.addSql(`create table "staff_time_report_entries" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "report_id" uuid not null, "time_entry_id" uuid not null, "frozen_raw_minutes" int not null default 0, "frozen_rounded_minutes" int not null default 0, "frozen_rate_amount" numeric(14,4) null, "frozen_currency_code" text not null, "frozen_amount" numeric(14,2) null, "frozen_is_billable" boolean not null default true, "created_at" timestamptz not null, primary key ("id"));`);
18
+ this.addSql(`create unique index "staff_time_report_entries_unique_idx" on "staff_time_report_entries" ("report_id", "time_entry_id");`);
19
+ this.addSql(`create index "staff_time_report_entries_entry_idx" on "staff_time_report_entries" ("organization_id", "time_entry_id");`);
20
+ this.addSql(`create index "staff_time_report_entries_tenant_org_idx" on "staff_time_report_entries" ("tenant_id", "organization_id");`);
21
+
22
+ this.addSql(`create table "staff_time_report_events" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "report_id" uuid not null, "event_type" text not null, "reason" text null, "actor_user_id" uuid null, "metadata" jsonb null, "created_at" timestamptz not null, primary key ("id"));`);
23
+ this.addSql(`create index "staff_time_report_events_report_idx" on "staff_time_report_events" ("organization_id", "report_id", "created_at");`);
24
+ this.addSql(`create index "staff_time_report_events_tenant_org_idx" on "staff_time_report_events" ("tenant_id", "organization_id");`);
25
+
26
+ this.addSql(`create table "staff_time_report_projects" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "report_id" uuid not null, "time_project_id" uuid not null, "created_at" timestamptz not null, primary key ("id"));`);
27
+ this.addSql(`create unique index "staff_time_report_projects_unique_idx" on "staff_time_report_projects" ("report_id", "time_project_id");`);
28
+ this.addSql(`create index "staff_time_report_projects_project_idx" on "staff_time_report_projects" ("organization_id", "time_project_id");`);
29
+ this.addSql(`create index "staff_time_report_projects_tenant_org_idx" on "staff_time_report_projects" ("tenant_id", "organization_id");`);
30
+
31
+ this.addSql(`create table "staff_time_tags" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "slug" text not null, "label" text not null, "color" text null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
32
+ this.addSql(`create unique index "staff_time_tags_slug_unique_idx" on "staff_time_tags" ("organization_id", "tenant_id", "slug") where "deleted_at" is null;`);
33
+ this.addSql(`create index "staff_time_tags_tenant_org_idx" on "staff_time_tags" ("tenant_id", "organization_id");`);
34
+
35
+ this.addSql(`create table "staff_time_tasks" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "time_project_id" uuid not null, "parent_task_id" uuid null, "task_status_id" uuid not null, "sequence_number" int not null default 0, "reference" text not null, "title" text not null, "description" text null, "assignee_staff_member_id" uuid null, "position" int not null default 0, "created_by_user_id" uuid null, "closed_at" timestamptz null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
36
+ this.addSql(`create unique index "staff_time_tasks_reference_unique_idx" on "staff_time_tasks" ("organization_id", "tenant_id", "reference") where "deleted_at" is null;`);
37
+ this.addSql(`create unique index "staff_time_tasks_sequence_unique_idx" on "staff_time_tasks" ("organization_id", "tenant_id", "time_project_id", "sequence_number") where "deleted_at" is null;`);
38
+ this.addSql(`create index "staff_time_tasks_assignee_idx" on "staff_time_tasks" ("organization_id", "assignee_staff_member_id");`);
39
+ this.addSql(`create index "staff_time_tasks_parent_idx" on "staff_time_tasks" ("organization_id", "parent_task_id");`);
40
+ this.addSql(`create index "staff_time_tasks_board_idx" on "staff_time_tasks" ("organization_id", "time_project_id", "task_status_id", "position");`);
41
+ this.addSql(`create index "staff_time_tasks_tenant_org_idx" on "staff_time_tasks" ("tenant_id", "organization_id");`);
42
+
43
+ this.addSql(`create table "staff_time_task_comments" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "task_id" uuid not null, "body" text not null, "author_user_id" uuid null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
44
+ this.addSql(`create index "staff_time_task_comments_task_idx" on "staff_time_task_comments" ("organization_id", "task_id", "created_at");`);
45
+ this.addSql(`create index "staff_time_task_comments_tenant_org_idx" on "staff_time_task_comments" ("tenant_id", "organization_id");`);
46
+
47
+ this.addSql(`create table "staff_time_task_statuses" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "time_project_id" uuid not null, "name" text not null, "slug" text not null, "color" text null, "position" int not null default 0, "is_default" boolean not null default false, "is_done" boolean not null default false, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
48
+ this.addSql(`create unique index "staff_time_task_statuses_slug_unique_idx" on "staff_time_task_statuses" ("organization_id", "tenant_id", "time_project_id", "slug") where "deleted_at" is null;`);
49
+ this.addSql(`create index "staff_time_task_statuses_project_idx" on "staff_time_task_statuses" ("organization_id", "time_project_id", "position");`);
50
+ this.addSql(`create index "staff_time_task_statuses_tenant_org_idx" on "staff_time_task_statuses" ("tenant_id", "organization_id");`);
51
+
52
+ this.addSql(`create table "staff_time_task_tags" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "tag_id" uuid not null, "task_id" uuid not null, "created_at" timestamptz not null, primary key ("id"));`);
53
+ this.addSql(`create unique index "staff_time_task_tags_unique_idx" on "staff_time_task_tags" ("tag_id", "task_id");`);
54
+ this.addSql(`create index "staff_time_task_tags_task_idx" on "staff_time_task_tags" ("organization_id", "task_id");`);
55
+ this.addSql(`create index "staff_time_task_tags_tenant_org_idx" on "staff_time_task_tags" ("tenant_id", "organization_id");`);
56
+
57
+ this.addSql(`alter table "staff_time_reports" add constraint "staff_time_reports_period_kind_check" check ("period_kind" in ('week', 'month', 'year', 'custom'));`);
58
+ this.addSql(`alter table "staff_time_reports" add constraint "staff_time_reports_grouping_check" check ("grouping" in ('project_task', 'project_person', 'project_day'));`);
59
+ this.addSql(`alter table "staff_time_reports" add constraint "staff_time_reports_nonbillable_mode_check" check ("nonbillable_mode" in ('separate', 'exclude'));`);
60
+ this.addSql(`alter table "staff_time_reports" add constraint "staff_time_reports_status_check" check ("status" in ('draft', 'closed'));`);
61
+
62
+ this.addSql(`alter table "staff_time_report_events" add constraint "staff_time_report_events_event_type_check" check ("event_type" in ('closed', 'unlocked', 'exported'));`);
63
+
64
+ this.addSql(`alter table "staff_time_entries" add "task_id" uuid null, add "is_billable" boolean not null default true, add "rounded_minutes" int null, add "rate_override_amount" numeric(14,4) null, add "rate_currency_code" text null, add "locked_report_id" uuid null, add "locked_at" timestamptz null;`);
65
+ this.addSql(`create index "staff_time_entries_locked_report_idx" on "staff_time_entries" ("organization_id", "locked_report_id");`);
66
+ this.addSql(`create index "staff_time_entries_member_overlap_idx" on "staff_time_entries" ("organization_id", "staff_member_id", "date", "started_at");`);
67
+ this.addSql(`create index "staff_time_entries_task_idx" on "staff_time_entries" ("organization_id", "task_id");`);
68
+
69
+ this.addSql(`alter table "staff_time_projects" add "customer_snapshot" jsonb null, add "hourly_rate" numeric(14,4) null, add "currency_code" text null, add "billable_by_default" boolean not null default true, add "budget_kind" text not null default 'none', add "budget_value" numeric(14,4) null, add "budget_warn_at_percent" int not null default 80, add "budget_alerted_at_percent" int null;`);
70
+ this.addSql(`alter table "staff_time_projects" add constraint "staff_time_projects_budget_kind_check" check ("budget_kind" in ('none', 'hours', 'amount'));`);
71
+ }
72
+
73
+ override down(): void | Promise<void> {
74
+ this.addSql(`drop table if exists "staff_time_entry_tags" cascade;`);
75
+ this.addSql(`drop table if exists "staff_time_report_entries" cascade;`);
76
+ this.addSql(`drop table if exists "staff_time_report_events" cascade;`);
77
+ this.addSql(`drop table if exists "staff_time_report_projects" cascade;`);
78
+ this.addSql(`drop table if exists "staff_time_reports" cascade;`);
79
+ this.addSql(`drop table if exists "staff_time_task_tags" cascade;`);
80
+ this.addSql(`drop table if exists "staff_time_tags" cascade;`);
81
+ this.addSql(`drop table if exists "staff_time_task_comments" cascade;`);
82
+ this.addSql(`drop table if exists "staff_time_tasks" cascade;`);
83
+ this.addSql(`drop table if exists "staff_time_task_statuses" cascade;`);
84
+
85
+ this.addSql(`drop index "staff_time_entries_locked_report_idx";`);
86
+ this.addSql(`drop index "staff_time_entries_member_overlap_idx";`);
87
+ this.addSql(`drop index "staff_time_entries_task_idx";`);
88
+ this.addSql(`alter table "staff_time_entries" drop column "task_id", drop column "is_billable", drop column "rounded_minutes", drop column "rate_override_amount", drop column "rate_currency_code", drop column "locked_report_id", drop column "locked_at";`);
89
+
90
+ this.addSql(`alter table "staff_time_projects" drop constraint if exists "staff_time_projects_budget_kind_check";`);
91
+ this.addSql(`alter table "staff_time_projects" drop column "customer_snapshot", drop column "hourly_rate", drop column "currency_code", drop column "billable_by_default", drop column "budget_kind", drop column "budget_value", drop column "budget_warn_at_percent", drop column "budget_alerted_at_percent";`);
92
+ }
93
+
94
+ }
@@ -0,0 +1,17 @@
1
+ import { Migration } from '@mikro-orm/migrations';
2
+
3
+ export class Migration20260824143357_staff extends Migration {
4
+
5
+ override up(): void | Promise<void> {
6
+ this.addSql(`alter table "staff_time_entries" drop constraint if exists "staff_time_entries_source_check";`);
7
+
8
+ this.addSql(`alter table "staff_time_reports" drop constraint if exists "staff_time_reports_grouping_check";`);
9
+ }
10
+
11
+ override down(): void | Promise<void> {
12
+ this.addSql(`alter table "staff_time_entries" add constraint "staff_time_entries_source_check" check ("source" in ('manual', 'timer', 'kiosk', 'mobile'));`);
13
+
14
+ this.addSql(`alter table "staff_time_reports" add constraint "staff_time_reports_grouping_check" check ("grouping" in ('project_task', 'project_person', 'project_day'));`);
15
+ }
16
+
17
+ }
@@ -0,0 +1,16 @@
1
+ 'use client'
2
+
3
+ import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
4
+ import { notificationTypes } from './notifications'
5
+ import { TimeProjectAccessRequestedRenderer } from './widgets/notifications/TimeProjectAccessRequestedRenderer'
6
+
7
+ const rendererMap: Record<string, NotificationTypeDefinition['Renderer']> = {
8
+ 'staff.timesheets.project_access.requested': TimeProjectAccessRequestedRenderer,
9
+ }
10
+
11
+ export const staffNotificationTypes: NotificationTypeDefinition[] = notificationTypes.map((type) => ({
12
+ ...type,
13
+ Renderer: rendererMap[type.type],
14
+ }))
15
+
16
+ export default staffNotificationTypes
@@ -0,0 +1,88 @@
1
+ import type { NotificationHandler } from '@open-mercato/shared/modules/notifications/handler'
2
+
3
+ /**
4
+ * EP-48. Reactive browser handlers for the time-tracking notification types.
5
+ *
6
+ * A handler is the module's own reaction to one of its notifications arriving in
7
+ * the browser: it re-broadcasts on the DOM Event Bridge so an open screen can
8
+ * refetch, and toasts the ones a person needs to see even when the bell is
9
+ * collapsed. Each `id` is the override key — `notifications.handlers.<id>` — so
10
+ * an app can disable or replace one without patching this file.
11
+ *
12
+ * `features` is checked with the wildcard-aware policy before `handle` runs, so
13
+ * a handler never fires for a caller who could not open the screen it points at.
14
+ */
15
+
16
+ export const TIME_REPORT_APPROVED_EVENT = 'om:staff:time-report-approved'
17
+ export const TIME_REPORT_READY_FOR_APPROVAL_EVENT = 'om:staff:time-report-ready-for-approval'
18
+ export const TIMER_RUNNING_LONG_EVENT = 'om:staff:timer-running-long'
19
+ export const TIMESHEET_PERIOD_INCOMPLETE_EVENT = 'om:staff:timesheet-period-incomplete'
20
+
21
+ export const notificationHandlers: NotificationHandler[] = [
22
+ {
23
+ id: 'staff.time-report-approved-event',
24
+ notificationType: 'staff.timesheets.time_report.approved',
25
+ features: ['staff.timesheets.reports.view'],
26
+ priority: 100,
27
+ handle(notification, context) {
28
+ context.emitEvent(TIME_REPORT_APPROVED_EVENT, {
29
+ notificationId: notification.id,
30
+ reportId: notification.sourceEntityId ?? null,
31
+ reference: notification.bodyVariables?.reference ?? null,
32
+ })
33
+ context.refreshNotifications()
34
+ },
35
+ },
36
+ {
37
+ id: 'staff.time-report-ready-for-approval-event',
38
+ notificationType: 'staff.timesheets.time_report.ready_for_approval',
39
+ features: ['staff.timesheets.reports.view'],
40
+ priority: 100,
41
+ handle(notification, context) {
42
+ context.emitEvent(TIME_REPORT_READY_FOR_APPROVAL_EVENT, {
43
+ notificationId: notification.id,
44
+ reportId: notification.sourceEntityId ?? null,
45
+ reference: notification.bodyVariables?.reference ?? null,
46
+ })
47
+ },
48
+ },
49
+ {
50
+ /**
51
+ * A running timer keeps billing until somebody stops it, so this one toasts
52
+ * as well as broadcasting — the bell alone is too quiet for a notification
53
+ * whose whole point is that the person has forgotten something.
54
+ */
55
+ id: 'staff.timer-running-long-toast',
56
+ notificationType: 'staff.timesheets.time_entry.timer_running_long',
57
+ features: ['staff.timesheets.view'],
58
+ priority: 110,
59
+ debounceMs: 60_000,
60
+ handle(notification, context) {
61
+ context.toast({
62
+ title: notification.title,
63
+ body: notification.body ?? undefined,
64
+ severity: 'warning',
65
+ })
66
+ context.emitEvent(TIMER_RUNNING_LONG_EVENT, {
67
+ notificationId: notification.id,
68
+ timeEntryId: notification.sourceEntityId ?? null,
69
+ })
70
+ },
71
+ },
72
+ {
73
+ id: 'staff.timesheet-period-incomplete-event',
74
+ notificationType: 'staff.timesheets.timesheet.period_incomplete',
75
+ features: ['staff.timesheets.view'],
76
+ priority: 90,
77
+ handle(notification, context) {
78
+ context.emitEvent(TIMESHEET_PERIOD_INCOMPLETE_EVENT, {
79
+ notificationId: notification.id,
80
+ staffMemberId: notification.sourceEntityId ?? null,
81
+ periodFrom: notification.bodyVariables?.periodFrom ?? null,
82
+ periodTo: notification.bodyVariables?.periodTo ?? null,
83
+ })
84
+ },
85
+ },
86
+ ]
87
+
88
+ export default notificationHandlers
@@ -72,6 +72,169 @@ export const notificationTypes: NotificationTypeDefinition[] = [
72
72
  linkHref: '/backend/staff/leave-requests/{sourceEntityId}',
73
73
  expiresAfterHours: 168, // 7 days
74
74
  },
75
+ {
76
+ // Spec D-6: the "Request access" button on screens 2 and 17 raises a real
77
+ // notification for every `staff.timesheets.projects.manage` holder. The
78
+ // subscriber overrides `linkHref` with the requester-specific deep link so
79
+ // the project team drawer opens with the requester pre-selected.
80
+ type: 'staff.timesheets.project_access.requested',
81
+ channels: ['in_app', 'email'],
82
+ module: 'staff',
83
+ titleKey: 'staff.notifications.timeProjectAccess.requested.title',
84
+ bodyKey: 'staff.notifications.timeProjectAccess.requested.body',
85
+ icon: 'user-plus',
86
+ severity: 'info',
87
+ actions: [
88
+ {
89
+ id: 'open-team',
90
+ labelKey: 'staff.notifications.timeProjectAccess.actions.openTeam',
91
+ variant: 'default',
92
+ icon: 'users',
93
+ href: '/backend/staff/time-tracking/projects/{sourceEntityId}?panel=team',
94
+ },
95
+ ],
96
+ primaryActionId: 'open-team',
97
+ linkHref: '/backend/staff/time-tracking/projects',
98
+ expiresAfterHours: 168, // 7 days
99
+ },
100
+ {
101
+ // Screen 4 budget card: "Ostrzezenie przy 80% i 100% wykorzystania". One type
102
+ // covers both thresholds — the subscriber raises the severity to `error` for the
103
+ // 100% crossing and carries the numbers in `bodyVariables`, so the two alerts
104
+ // read differently without splitting the notification id.
105
+ type: 'staff.timesheets.time_project.budget_threshold_reached',
106
+ channels: ['in_app', 'email'],
107
+ module: 'staff',
108
+ titleKey: 'staff.notifications.timeProjectBudget.thresholdReached.title',
109
+ bodyKey: 'staff.notifications.timeProjectBudget.thresholdReached.body',
110
+ icon: 'gauge',
111
+ severity: 'warning',
112
+ actions: [
113
+ {
114
+ id: 'open-project',
115
+ labelKey: 'staff.notifications.timeProjectBudget.actions.openProject',
116
+ variant: 'default',
117
+ icon: 'external-link',
118
+ href: '/backend/staff/time-tracking/projects/{sourceEntityId}',
119
+ },
120
+ ],
121
+ primaryActionId: 'open-project',
122
+ linkHref: '/backend/staff/time-tracking/projects/{sourceEntityId}',
123
+ expiresAfterHours: 168, // 7 days
124
+ },
125
+ {
126
+ /**
127
+ * EP-48. Raised by `subscribers/time-report-approved-notification.ts` when a
128
+ * report is closed — closing IS the approval in this module: it freezes every
129
+ * per-entry value and locks the entries, and `staff.timesheets.lock` is the
130
+ * feature that gates it. The recipient is the person who drafted the report,
131
+ * who otherwise learns about it only by reopening the screen.
132
+ */
133
+ type: 'staff.timesheets.time_report.approved',
134
+ channels: ['in_app', 'email'],
135
+ module: 'staff',
136
+ titleKey: 'staff.notifications.timeReport.approved.title',
137
+ bodyKey: 'staff.notifications.timeReport.approved.body',
138
+ icon: 'file-check',
139
+ severity: 'success',
140
+ actions: [
141
+ {
142
+ id: 'open-report',
143
+ labelKey: 'staff.notifications.timeReport.actions.openReport',
144
+ variant: 'default',
145
+ icon: 'external-link',
146
+ href: '/backend/staff/time-tracking/reports/{sourceEntityId}',
147
+ },
148
+ ],
149
+ primaryActionId: 'open-report',
150
+ linkHref: '/backend/staff/time-tracking/reports/{sourceEntityId}',
151
+ expiresAfterHours: 168, // 7 days
152
+ },
153
+ {
154
+ /**
155
+ * EP-48, contributable-only by design. The module has exactly one report
156
+ * transition — draft → closed — so there is no "submitted, awaiting a second
157
+ * pair of eyes" state for core to announce. This id exists so the multi-step
158
+ * approval a `registerReportApprovalPolicy` contribution (EP-41) implements
159
+ * has a published notification to raise instead of inventing its own, and so
160
+ * the renderer and delivery preferences are already in place when it does.
161
+ */
162
+ type: 'staff.timesheets.time_report.ready_for_approval',
163
+ channels: ['in_app', 'email'],
164
+ module: 'staff',
165
+ titleKey: 'staff.notifications.timeReport.readyForApproval.title',
166
+ bodyKey: 'staff.notifications.timeReport.readyForApproval.body',
167
+ icon: 'file-clock',
168
+ severity: 'info',
169
+ actions: [
170
+ {
171
+ id: 'review-report',
172
+ labelKey: 'staff.notifications.timeReport.actions.reviewReport',
173
+ variant: 'default',
174
+ icon: 'external-link',
175
+ href: '/backend/staff/time-tracking/reports/{sourceEntityId}',
176
+ },
177
+ ],
178
+ primaryActionId: 'review-report',
179
+ linkHref: '/backend/staff/time-tracking/reports/{sourceEntityId}',
180
+ expiresAfterHours: 168, // 7 days
181
+ },
182
+ {
183
+ /**
184
+ * EP-48, contributable-only by design. "This timer has been running for six
185
+ * hours" needs something that wakes up on a schedule and looks at open
186
+ * timers; the module ships no periodic job and inventing one to justify an id
187
+ * would be the tail wagging the dog. The id is the contract for a module that
188
+ * does ship one.
189
+ */
190
+ type: 'staff.timesheets.time_entry.timer_running_long',
191
+ channels: ['in_app'],
192
+ module: 'staff',
193
+ titleKey: 'staff.notifications.timeEntryTimer.runningLong.title',
194
+ bodyKey: 'staff.notifications.timeEntryTimer.runningLong.body',
195
+ icon: 'timer',
196
+ severity: 'warning',
197
+ actions: [
198
+ {
199
+ id: 'open-timesheet',
200
+ labelKey: 'staff.notifications.timesheet.actions.openTimesheet',
201
+ variant: 'default',
202
+ icon: 'external-link',
203
+ href: '/backend/staff/time-tracking/timesheet',
204
+ },
205
+ ],
206
+ primaryActionId: 'open-timesheet',
207
+ linkHref: '/backend/staff/time-tracking/timesheet',
208
+ expiresAfterHours: 24,
209
+ },
210
+ {
211
+ /**
212
+ * EP-48, contributable-only by design. Whether a period is "incomplete" is
213
+ * the capacity provider's question (EP-40), and the built-in provider spreads
214
+ * one flat daily number over the caller's working days on demand — it has no
215
+ * schedule and no opinion about when to complain. A contributed provider that
216
+ * knows contract hours and leave is the thing that can raise this honestly.
217
+ */
218
+ type: 'staff.timesheets.timesheet.period_incomplete',
219
+ channels: ['in_app', 'email'],
220
+ module: 'staff',
221
+ titleKey: 'staff.notifications.timesheet.periodIncomplete.title',
222
+ bodyKey: 'staff.notifications.timesheet.periodIncomplete.body',
223
+ icon: 'calendar-clock',
224
+ severity: 'warning',
225
+ actions: [
226
+ {
227
+ id: 'open-timesheet',
228
+ labelKey: 'staff.notifications.timesheet.actions.openTimesheet',
229
+ variant: 'default',
230
+ icon: 'external-link',
231
+ href: '/backend/staff/time-tracking/timesheet',
232
+ },
233
+ ],
234
+ primaryActionId: 'open-timesheet',
235
+ linkHref: '/backend/staff/time-tracking/timesheet',
236
+ expiresAfterHours: 168, // 7 days
237
+ },
75
238
  ]
76
239
 
77
240
  export default notificationTypes
@@ -118,6 +118,74 @@ function buildIndexSource(
118
118
  }
119
119
  }
120
120
 
121
+ /**
122
+ * EP-46. The four time-tracking entities below join `staff:staff_time_project`
123
+ * in the index, and every one of them carries a gate that is deliberately
124
+ * stricter than the feature its REST route declares.
125
+ *
126
+ * The reason is a property of the search layer, not of this module: an entity's
127
+ * `aclFeatures` is the ONLY authorization the search pipeline applies. It is
128
+ * enforced twice per query — `resolveReadableEntityTypes` narrows the entity
129
+ * list before the query and `filterSearchResultsByEntityAccess` filters the
130
+ * results after it — but both decide **per entity type**, never per record.
131
+ * `SearchEntityConfig` has no row-level hook and `SearchOptions` has no record-id
132
+ * allowlist, so a search gate cannot reproduce the per-project membership
133
+ * intersection that `resolveProjectAccess` applies on every time-tracking route.
134
+ *
135
+ * So each gate below names the feature set whose holder already sees **every**
136
+ * record of that entity through the API. `staff.timesheets.projects.manage` is
137
+ * that feature for entries, tasks and reports: it is what makes
138
+ * `resolveProjectAccess` answer `canManageAll: true`, which is the only state in
139
+ * which those routes stop intersecting with the caller's project membership.
140
+ * A project member without it gets no hits at all rather than hits for projects
141
+ * they cannot open — the failure mode that costs a support ticket, not the one
142
+ * that discloses a client's work.
143
+ */
144
+ const UNRESTRICTED_PROJECT_ACCESS_FEATURE = 'staff.timesheets.projects.manage'
145
+
146
+ function buildTimeTaskPresenter(t: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
147
+ const title =
148
+ pickString(record.title, record.reference) ?? (record.id as string | undefined) ?? t('staff.search.badge.timeTask', 'Task')
149
+ return {
150
+ title: String(title),
151
+ subtitle: formatSubtitle(record.reference, snippet(record.description, 80)),
152
+ icon: 'list-checks',
153
+ badge: t('staff.search.badge.timeTask', 'Task'),
154
+ }
155
+ }
156
+
157
+ function buildTimeReportPresenter(t: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
158
+ const title =
159
+ pickString(record.title, record.reference) ?? (record.id as string | undefined) ?? t('staff.search.badge.timeReport', 'Report')
160
+ return {
161
+ title: String(title),
162
+ subtitle: formatSubtitle(record.reference, record.period_from ?? record.periodFrom, record.period_to ?? record.periodTo),
163
+ icon: 'file-text',
164
+ badge: t('staff.search.badge.timeReport', 'Report'),
165
+ }
166
+ }
167
+
168
+ function buildTimeTagPresenter(t: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
169
+ const title =
170
+ pickString(record.label, record.slug) ?? (record.id as string | undefined) ?? t('staff.search.badge.timeTag', 'Tag')
171
+ return {
172
+ title: String(title),
173
+ subtitle: formatSubtitle(record.slug),
174
+ icon: 'tag',
175
+ badge: t('staff.search.badge.timeTag', 'Tag'),
176
+ }
177
+ }
178
+
179
+ function buildTimeEntryPresenter(t: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
180
+ const title = snippet(record.notes, 80) ?? t('staff.search.badge.timeEntry', 'Time entry')
181
+ return {
182
+ title,
183
+ subtitle: formatSubtitle(record.date, record.duration_minutes ?? record.durationMinutes),
184
+ icon: 'timer',
185
+ badge: t('staff.search.badge.timeEntry', 'Time entry'),
186
+ }
187
+ }
188
+
121
189
  export const searchConfig: SearchModuleConfig = {
122
190
  entities: [
123
191
  {
@@ -222,11 +290,133 @@ export const searchConfig: SearchModuleConfig = {
222
290
  badge: t('staff.search.badge.timeProject', 'Project'),
223
291
  }
224
292
  },
225
- resolveUrl: async (ctx) => `/backend/staff/timesheets/projects/${encodeURIComponent(String(ctx.record.id))}`,
293
+ resolveUrl: async (ctx) => `/backend/staff/time-tracking/projects/${encodeURIComponent(String(ctx.record.id))}`,
226
294
  fieldPolicy: {
227
295
  searchable: ['name', 'code', 'description', 'project_type', 'cost_center'],
228
296
  },
229
297
  },
298
+ {
299
+ entityId: 'staff:staff_time_task',
300
+ aclFeatures: ['staff.timesheets.tasks.view', UNRESTRICTED_PROJECT_ACCESS_FEATURE],
301
+ enabled: true,
302
+ priority: 7,
303
+ buildSource: async (ctx) => {
304
+ const { t } = await resolveTranslations()
305
+ const record = ctx.record
306
+ const lines: string[] = []
307
+ appendLine(lines, 'Reference', record.reference)
308
+ appendLine(lines, 'Title', record.title)
309
+ appendLine(lines, 'Description', record.description)
310
+ return buildIndexSource(ctx, buildTimeTaskPresenter(t, record), lines)
311
+ },
312
+ formatResult: async (ctx) => {
313
+ const { t } = await resolveTranslations()
314
+ return buildTimeTaskPresenter(t, ctx.record)
315
+ },
316
+ resolveUrl: async (ctx) => {
317
+ const projectId = pickString(ctx.record.time_project_id, ctx.record.timeProjectId)
318
+ if (!projectId) return null
319
+ return `/backend/staff/time-tracking/board?projectId=${encodeURIComponent(projectId)}&task=${encodeURIComponent(String(ctx.record.id))}`
320
+ },
321
+ fieldPolicy: {
322
+ searchable: ['title', 'description', 'reference'],
323
+ },
324
+ },
325
+ {
326
+ entityId: 'staff:staff_time_report',
327
+ aclFeatures: ['staff.timesheets.reports.view', UNRESTRICTED_PROJECT_ACCESS_FEATURE],
328
+ enabled: true,
329
+ priority: 7,
330
+ buildSource: async (ctx) => {
331
+ const { t } = await resolveTranslations()
332
+ const record = ctx.record
333
+ const lines: string[] = []
334
+ appendLine(lines, 'Reference', record.reference)
335
+ appendLine(lines, 'Title', record.title)
336
+ appendLine(lines, 'Status', record.status)
337
+ return buildIndexSource(ctx, buildTimeReportPresenter(t, record), lines)
338
+ },
339
+ formatResult: async (ctx) => {
340
+ const { t } = await resolveTranslations()
341
+ return buildTimeReportPresenter(t, ctx.record)
342
+ },
343
+ resolveUrl: async (ctx) => `/backend/staff/time-tracking/reports/${encodeURIComponent(String(ctx.record.id))}`,
344
+ /**
345
+ * `total_amount` and the denormalised `customer_snapshot` are excluded, not
346
+ * merely left out of `searchable`: money in a time-tracking response is
347
+ * gated on `staff.timesheets.rates.view`, and the search pipeline has no way
348
+ * to apply a second feature to a subset of an indexed record's fields.
349
+ */
350
+ fieldPolicy: {
351
+ searchable: ['reference', 'title'],
352
+ excluded: ['total_amount', 'customer_snapshot'],
353
+ },
354
+ },
355
+ {
356
+ entityId: 'staff:staff_time_tag',
357
+ aclFeatures: ['staff.timesheets.view'],
358
+ enabled: true,
359
+ priority: 5,
360
+ buildSource: async (ctx) => {
361
+ const { t } = await resolveTranslations()
362
+ const record = ctx.record
363
+ const lines: string[] = []
364
+ appendLine(lines, 'Label', record.label)
365
+ appendLine(lines, 'Slug', record.slug)
366
+ return buildIndexSource(ctx, buildTimeTagPresenter(t, record), lines)
367
+ },
368
+ formatResult: async (ctx) => {
369
+ const { t } = await resolveTranslations()
370
+ return buildTimeTagPresenter(t, ctx.record)
371
+ },
372
+ /**
373
+ * A tag has no detail screen and the entries list deep-links only `taskId`
374
+ * and `ids`, so there is no honest destination to send the caller to. The
375
+ * presenter still answers the question a tag search asks — "does this label
376
+ * exist, and what is it spelled" — and `url` is optional in the result
377
+ * contract, so an unlinked hit renders rather than pointing somewhere wrong.
378
+ */
379
+ resolveUrl: async () => null,
380
+ fieldPolicy: {
381
+ searchable: ['label', 'slug'],
382
+ },
383
+ },
384
+ {
385
+ /**
386
+ * Entry notes are the most sensitive text time tracking holds — they are
387
+ * where a consultant writes what they did for a named client. The gate is
388
+ * therefore the strictest one the module has for entries: `staff.timesheets.view`
389
+ * AND `staff.timesheets.projects.manage`, the pair that makes
390
+ * `resolveProjectAccess` return `canManageAll`, which is the only state in
391
+ * which `/api/staff/timesheets/time-entries` stops narrowing to the caller's
392
+ * own entries plus their project memberships. A consultant with
393
+ * `staff.timesheets.manage_own` gets no entry hits at all — including their
394
+ * own — because the gate cannot express "own" and half a gate is worse than
395
+ * none.
396
+ */
397
+ entityId: 'staff:staff_time_entry',
398
+ aclFeatures: ['staff.timesheets.view', UNRESTRICTED_PROJECT_ACCESS_FEATURE],
399
+ enabled: true,
400
+ priority: 4,
401
+ buildSource: async (ctx) => {
402
+ const { t } = await resolveTranslations()
403
+ const record = ctx.record
404
+ const lines: string[] = []
405
+ appendLine(lines, 'Notes', record.notes)
406
+ appendLine(lines, 'Date', record.date)
407
+ return buildIndexSource(ctx, buildTimeEntryPresenter(t, record), lines)
408
+ },
409
+ formatResult: async (ctx) => {
410
+ const { t } = await resolveTranslations()
411
+ return buildTimeEntryPresenter(t, ctx.record)
412
+ },
413
+ resolveUrl: async (ctx) =>
414
+ `/backend/staff/time-tracking/entries?ids=${encodeURIComponent(String(ctx.record.id))}`,
415
+ fieldPolicy: {
416
+ searchable: ['notes'],
417
+ excluded: ['rate_override_amount', 'rate_currency_code'],
418
+ },
419
+ },
230
420
  ],
231
421
  }
232
422
 
@@ -1,6 +1,7 @@
1
1
  import type { ModuleSetupConfig } from '@open-mercato/shared/modules/setup'
2
2
  import { appendWidgetsToRoles } from '@open-mercato/core/modules/dashboards/lib/role-widgets'
3
3
  import { seedStaffAddressTypes, seedStaffTeamExamples } from './lib/seeds'
4
+ import { seedStaffTimeTrackingExamples } from './lib/timeTrackingSeeds'
4
5
 
5
6
  const TIMESHEETS_DASHBOARD_WIDGET_IDS = [
6
7
  'staff.timesheets.timeReporting',
@@ -22,6 +23,9 @@ export const setup: ModuleSetupConfig = {
22
23
  seedExamples: async (ctx) => {
23
24
  const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId }
24
25
  await seedStaffTeamExamples(ctx.em, scope)
26
+ // Runs after the team examples because every project it staffs, every task it
27
+ // assigns and every hour it logs points at a staff member those seeds create.
28
+ await seedStaffTimeTrackingExamples(ctx.em, scope)
25
29
  },
26
30
 
27
31
  defaultRoleFeatures: {
@@ -35,8 +39,26 @@ export const setup: ModuleSetupConfig = {
35
39
  'staff.timesheets.view',
36
40
  'staff.timesheets.manage_own',
37
41
  'staff.timesheets.projects.view',
42
+ 'staff.timesheets.tasks.view',
43
+ 'staff.timesheets.tasks.manage',
44
+ 'staff.timesheets.rates.view',
38
45
  ],
39
46
  },
47
+
48
+ /**
49
+ * EP-50. `portal.time_reports.view` is a **customer** feature, granted through
50
+ * `CustomerRoleAcl`, and it is deliberately absent from `acl.ts` — that file is
51
+ * the staff feature catalog and the two namespaces are graded by different RBAC
52
+ * services.
53
+ *
54
+ * `viewer` gets it as well as `buyer`: reading the hours already delivered is a
55
+ * read, and a client who may see their invoices may see what they paid for.
56
+ * `portal_admin` holds `portal.*` and needs no entry.
57
+ */
58
+ defaultCustomerRoleFeatures: {
59
+ buyer: ['portal.time_reports.view'],
60
+ viewer: ['portal.time_reports.view'],
61
+ },
40
62
  }
41
63
 
42
64
  export default setup