@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,399 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
+ import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
5
+ import { resolveOrganizationScopeForRequest } from "@open-mercato/core/modules/directory/utils/organizationScope";
6
+ import { serializeOperationMetadata } from "@open-mercato/shared/lib/commands/operationMetadata";
7
+ import { getCommandInterceptorHttpRejection } from "@open-mercato/shared/lib/commands/errors";
8
+ import { CrudHttpError, isCrudHttpError } from "@open-mercato/shared/lib/crud/errors";
9
+ import { runRouteMutationGuards } from "@open-mercato/shared/lib/crud/route-mutation-guard";
10
+ import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
11
+ import { parseScopedCommandInput } from "@open-mercato/shared/lib/api/scoped";
12
+ import { readJsonSafe } from "@open-mercato/shared/lib/http/readJsonSafe";
13
+ import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
14
+ import { createLogger } from "@open-mercato/shared/lib/logger";
15
+ import { User } from "@open-mercato/core/modules/auth/data/entities";
16
+ import { StaffTimeTaskComment } from "../../../../../data/entities.js";
17
+ import {
18
+ staffTimeTaskCommentCreateSchema,
19
+ staffTimeTaskCommentUpdateSchema
20
+ } from "../../../../../data/validators.js";
21
+ import { staffTimeTaskCommentCommandIds } from "../../../../../commands/timesheets-task-comments.js";
22
+ import { STAFF_TIME_TRACKING_RESOURCE_KINDS } from "../../../../guards.js";
23
+ import {
24
+ loadTagProjectAccess as loadTaskProjectAccess,
25
+ requireAccessibleTask
26
+ } from "../../../tags/access.js";
27
+ const logger = createLogger("staff").child({ component: "api/timesheets/tasks/comments" });
28
+ const RESOURCE_KIND = STAFF_TIME_TRACKING_RESOURCE_KINDS.timeTaskComment;
29
+ const VIEW_FEATURE = "staff.timesheets.tasks.view";
30
+ const MANAGE_FEATURE = "staff.timesheets.tasks.manage";
31
+ const metadata = {
32
+ GET: { requireAuth: true, requireFeatures: [VIEW_FEATURE] },
33
+ POST: { requireAuth: true, requireFeatures: [MANAGE_FEATURE] },
34
+ PUT: { requireAuth: true, requireFeatures: [MANAGE_FEATURE] },
35
+ DELETE: { requireAuth: true, requireFeatures: [MANAGE_FEATURE] }
36
+ };
37
+ const listQuerySchema = z.object({
38
+ page: z.coerce.number().min(1).default(1),
39
+ pageSize: z.coerce.number().min(1).max(100).default(50)
40
+ });
41
+ const commentItemSchema = z.object({
42
+ id: z.string().uuid(),
43
+ taskId: z.string().uuid(),
44
+ body: z.string(),
45
+ authorUserId: z.string().uuid().nullable(),
46
+ authorName: z.string().nullable(),
47
+ authorEmail: z.string().nullable(),
48
+ createdAt: z.string().nullable(),
49
+ updatedAt: z.string().nullable()
50
+ });
51
+ const listResponseSchema = z.object({
52
+ items: z.array(commentItemSchema),
53
+ total: z.number().int(),
54
+ page: z.number().int(),
55
+ pageSize: z.number().int(),
56
+ totalPages: z.number().int()
57
+ });
58
+ const createResponseSchema = z.object({
59
+ id: z.string().uuid().nullable(),
60
+ taskId: z.string().uuid(),
61
+ authorUserId: z.string().uuid().nullable()
62
+ });
63
+ const okResponseSchema = z.object({ ok: z.boolean() });
64
+ const createBodySchema = z.object({ body: z.string().trim().min(1).max(5e3) });
65
+ const updateBodySchema = z.object({ id: z.string().uuid(), body: z.string().trim().min(1).max(5e3) });
66
+ function extractTaskId(req) {
67
+ try {
68
+ const match = new URL(req.url).pathname.match(/\/tasks\/([^/]+)\/comments/);
69
+ const id = match?.[1] ? decodeURIComponent(match[1]) : null;
70
+ return id && id.length > 0 ? id : null;
71
+ } catch {
72
+ return null;
73
+ }
74
+ }
75
+ async function buildRouteContext(req) {
76
+ const container = await createRequestContainer();
77
+ const auth = await getAuthFromRequest(req);
78
+ const { translate } = await resolveTranslations();
79
+ if (!auth) throw new CrudHttpError(401, { error: translate("staff.errors.unauthorized", "Unauthorized") });
80
+ const organizationScope = await resolveOrganizationScopeForRequest({ container, auth, request: req });
81
+ const ctx = {
82
+ container,
83
+ auth,
84
+ organizationScope,
85
+ selectedOrganizationId: organizationScope?.selectedId ?? auth.orgId ?? null,
86
+ organizationIds: organizationScope?.filterIds ?? (auth.orgId ? [auth.orgId] : null),
87
+ request: req
88
+ };
89
+ const tenantId = auth.tenantId ?? null;
90
+ const organizationId = ctx.selectedOrganizationId ?? auth.orgId ?? null;
91
+ const userId = auth.sub ?? null;
92
+ if (!tenantId || !organizationId || !userId) {
93
+ throw new CrudHttpError(400, {
94
+ error: translate("staff.errors.missingScope", "Missing tenant or organization scope.")
95
+ });
96
+ }
97
+ const taskId = extractTaskId(req);
98
+ if (!taskId) {
99
+ throw new CrudHttpError(400, {
100
+ error: translate("staff.time_tracking.taskComments.errors.taskIdRequired", "Task id is required.")
101
+ });
102
+ }
103
+ return { ctx, scope: { tenantId, organizationId, userId }, translate, taskId };
104
+ }
105
+ async function requireTaskAccess(route) {
106
+ const access = await loadTaskProjectAccess(route.ctx.container, route.scope);
107
+ const em = route.ctx.container.resolve("em").fork();
108
+ await requireAccessibleTask(em, route.taskId, route.scope, access, route.translate);
109
+ }
110
+ function commentNotFoundError(translate) {
111
+ return new CrudHttpError(404, {
112
+ error: translate("staff.time_tracking.taskComments.errors.notFound", "Comment not found or not accessible.")
113
+ });
114
+ }
115
+ async function requireCommentOnTask(route, commentId) {
116
+ const em = route.ctx.container.resolve("em").fork();
117
+ const comment = await em.findOne(StaffTimeTaskComment, {
118
+ id: commentId,
119
+ taskId: route.taskId,
120
+ tenantId: route.scope.tenantId,
121
+ organizationId: route.scope.organizationId,
122
+ deletedAt: null
123
+ });
124
+ if (!comment) throw commentNotFoundError(route.translate);
125
+ return comment;
126
+ }
127
+ async function resolveAuthorMeta(route, authorUserIds) {
128
+ const map = /* @__PURE__ */ new Map();
129
+ const unique = Array.from(new Set(authorUserIds));
130
+ if (unique.length === 0) return map;
131
+ try {
132
+ const em = route.ctx.container.resolve("em").fork();
133
+ const users = await findWithDecryption(
134
+ em,
135
+ User,
136
+ { id: { $in: unique } },
137
+ void 0,
138
+ { tenantId: route.scope.tenantId, organizationId: route.scope.organizationId }
139
+ );
140
+ for (const user of users) {
141
+ const name = typeof user.name === "string" && user.name.trim().length > 0 ? user.name.trim() : null;
142
+ map.set(user.id, { name, email: user.email ?? null });
143
+ }
144
+ } catch (err) {
145
+ logger.warn("staff.timesheets.task comments failed to resolve author metadata", { err });
146
+ }
147
+ return map;
148
+ }
149
+ function serializeComment(comment, authors) {
150
+ const authorUserId = comment.authorUserId ?? null;
151
+ const meta = authorUserId ? authors.get(authorUserId) ?? null : null;
152
+ return {
153
+ id: comment.id,
154
+ taskId: comment.taskId,
155
+ body: comment.body,
156
+ authorUserId,
157
+ authorName: meta?.name ?? null,
158
+ authorEmail: meta?.email ?? null,
159
+ createdAt: comment.createdAt ? comment.createdAt.toISOString() : null,
160
+ updatedAt: comment.updatedAt ? comment.updatedAt.toISOString() : null
161
+ };
162
+ }
163
+ async function runGuards(route, operation, resourceId, mutationPayload) {
164
+ return runRouteMutationGuards({
165
+ container: route.ctx.container,
166
+ req: route.ctx.request,
167
+ auth: {
168
+ userId: route.scope.userId,
169
+ tenantId: route.scope.tenantId,
170
+ organizationId: route.scope.organizationId
171
+ },
172
+ input: {
173
+ resourceKind: RESOURCE_KIND,
174
+ resourceId,
175
+ operation,
176
+ mutationPayload
177
+ }
178
+ });
179
+ }
180
+ function withOperationHeader(response, logEntry, fallbackResourceId) {
181
+ if (!logEntry?.undoToken || !logEntry.id || !logEntry.commandId) return response;
182
+ response.headers.set(
183
+ "x-om-operation",
184
+ serializeOperationMetadata({
185
+ id: logEntry.id,
186
+ undoToken: logEntry.undoToken,
187
+ commandId: logEntry.commandId,
188
+ actionLabel: logEntry.actionLabel ?? null,
189
+ resourceKind: logEntry.resourceKind ?? RESOURCE_KIND,
190
+ resourceId: logEntry.resourceId ?? fallbackResourceId,
191
+ executedAt: logEntry.createdAt instanceof Date ? logEntry.createdAt.toISOString() : typeof logEntry.createdAt === "string" ? logEntry.createdAt : (/* @__PURE__ */ new Date()).toISOString()
192
+ })
193
+ );
194
+ return response;
195
+ }
196
+ async function errorResponse(err, message) {
197
+ if (isCrudHttpError(err)) {
198
+ return NextResponse.json(err.body, { status: err.status });
199
+ }
200
+ const { translate } = await resolveTranslations();
201
+ if (err instanceof z.ZodError) {
202
+ return NextResponse.json(
203
+ { error: translate("staff.errors.invalid_request", "Invalid request"), details: err.issues },
204
+ { status: 400 }
205
+ );
206
+ }
207
+ logger.error(message, { err });
208
+ return NextResponse.json({ error: translate("staff.errors.internal", "Internal server error") }, { status: 500 });
209
+ }
210
+ async function GET(req) {
211
+ try {
212
+ const route = await buildRouteContext(req);
213
+ await requireTaskAccess(route);
214
+ const url = new URL(req.url);
215
+ const query = listQuerySchema.parse({
216
+ page: url.searchParams.get("page") ?? void 0,
217
+ pageSize: url.searchParams.get("pageSize") ?? void 0
218
+ });
219
+ const em = route.ctx.container.resolve("em").fork();
220
+ const [comments, total] = await em.findAndCount(
221
+ StaffTimeTaskComment,
222
+ {
223
+ taskId: route.taskId,
224
+ tenantId: route.scope.tenantId,
225
+ organizationId: route.scope.organizationId,
226
+ deletedAt: null
227
+ },
228
+ {
229
+ // Oldest first — the drawer reads the thread top to bottom.
230
+ orderBy: { createdAt: "asc", id: "asc" },
231
+ limit: query.pageSize,
232
+ offset: (query.page - 1) * query.pageSize
233
+ }
234
+ );
235
+ const authors = await resolveAuthorMeta(
236
+ route,
237
+ comments.map((comment) => comment.authorUserId).filter((id) => typeof id === "string")
238
+ );
239
+ return NextResponse.json({
240
+ items: comments.map((comment) => serializeComment(comment, authors)),
241
+ total,
242
+ page: query.page,
243
+ pageSize: query.pageSize,
244
+ totalPages: query.pageSize > 0 ? Math.ceil(total / query.pageSize) : 0
245
+ });
246
+ } catch (err) {
247
+ return errorResponse(err, "staff.timesheets.tasks.comments.GET failed");
248
+ }
249
+ }
250
+ async function POST(req) {
251
+ try {
252
+ const route = await buildRouteContext(req);
253
+ await requireTaskAccess(route);
254
+ const raw = await readJsonSafe(req, {});
255
+ const parsedBody = createBodySchema.parse(raw ?? {});
256
+ const input = parseScopedCommandInput(
257
+ staffTimeTaskCommentCreateSchema,
258
+ { taskId: route.taskId, body: parsedBody.body },
259
+ route.ctx,
260
+ route.translate
261
+ );
262
+ const guardResult = await runGuards(route, "create", route.taskId, input);
263
+ if (!guardResult.ok) return guardResult.response;
264
+ const commandBus = route.ctx.container.resolve("commandBus");
265
+ const { result, logEntry } = await commandBus.execute(staffTimeTaskCommentCommandIds.create, { input, ctx: route.ctx });
266
+ await guardResult.runAfterSuccess();
267
+ const response = NextResponse.json(
268
+ {
269
+ id: result?.commentId ?? null,
270
+ taskId: route.taskId,
271
+ authorUserId: result?.authorUserId ?? null
272
+ },
273
+ { status: 201 }
274
+ );
275
+ return withOperationHeader(response, logEntry, result?.commentId ?? route.taskId);
276
+ } catch (err) {
277
+ const interceptorRejection = getCommandInterceptorHttpRejection(err);
278
+ if (interceptorRejection) {
279
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status });
280
+ }
281
+ return errorResponse(err, "staff.timesheets.tasks.comments.POST failed");
282
+ }
283
+ }
284
+ async function PUT(req) {
285
+ try {
286
+ const route = await buildRouteContext(req);
287
+ await requireTaskAccess(route);
288
+ const raw = await readJsonSafe(req, {});
289
+ const parsedBody = updateBodySchema.parse(raw ?? {});
290
+ await requireCommentOnTask(route, parsedBody.id);
291
+ const input = staffTimeTaskCommentUpdateSchema.parse({ id: parsedBody.id, body: parsedBody.body });
292
+ const guardResult = await runGuards(route, "update", input.id, input);
293
+ if (!guardResult.ok) return guardResult.response;
294
+ const commandBus = route.ctx.container.resolve("commandBus");
295
+ const { logEntry } = await commandBus.execute(
296
+ staffTimeTaskCommentCommandIds.update,
297
+ { input, ctx: route.ctx }
298
+ );
299
+ await guardResult.runAfterSuccess();
300
+ return withOperationHeader(NextResponse.json({ ok: true }), logEntry, input.id);
301
+ } catch (err) {
302
+ const interceptorRejection = getCommandInterceptorHttpRejection(err);
303
+ if (interceptorRejection) {
304
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status });
305
+ }
306
+ return errorResponse(err, "staff.timesheets.tasks.comments.PUT failed");
307
+ }
308
+ }
309
+ async function DELETE(req) {
310
+ try {
311
+ const route = await buildRouteContext(req);
312
+ await requireTaskAccess(route);
313
+ const url = new URL(req.url);
314
+ const raw = await readJsonSafe(req, {});
315
+ const rawId = url.searchParams.get("id") ?? raw?.id;
316
+ const id = z.string().uuid().parse(typeof rawId === "string" ? rawId : void 0);
317
+ await requireCommentOnTask(route, id);
318
+ const guardResult = await runGuards(route, "delete", id, { id });
319
+ if (!guardResult.ok) return guardResult.response;
320
+ const commandBus = route.ctx.container.resolve("commandBus");
321
+ const { logEntry } = await commandBus.execute(
322
+ staffTimeTaskCommentCommandIds.delete,
323
+ { input: { id }, ctx: route.ctx }
324
+ );
325
+ await guardResult.runAfterSuccess();
326
+ return withOperationHeader(NextResponse.json({ ok: true }), logEntry, id);
327
+ } catch (err) {
328
+ const interceptorRejection = getCommandInterceptorHttpRejection(err);
329
+ if (interceptorRejection) {
330
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status });
331
+ }
332
+ return errorResponse(err, "staff.timesheets.tasks.comments.DELETE failed");
333
+ }
334
+ }
335
+ const openApi = {
336
+ tag: "Staff",
337
+ summary: "Task comments",
338
+ methods: {
339
+ GET: {
340
+ summary: "List task comments",
341
+ description: "Returns the task comment thread oldest-first, with the author display name resolved for rendering. Answers 404 \u2014 identical to a task that does not exist \u2014 when the task belongs to a project the caller cannot see.",
342
+ query: listQuerySchema,
343
+ responses: [{ status: 200, description: "Comment thread", schema: listResponseSchema }],
344
+ errors: [
345
+ { status: 400, description: "Missing task id or organization scope" },
346
+ { status: 401, description: "Unauthorized" },
347
+ { status: 403, description: "Missing staff.timesheets.tasks.view" },
348
+ { status: 404, description: "Task not found or not accessible" }
349
+ ]
350
+ },
351
+ POST: {
352
+ summary: "Post a task comment",
353
+ description: "Adds a comment to the task. The author is stamped from the authenticated caller \u2014 an authorUserId supplied by the client is ignored.",
354
+ requestBody: { contentType: "application/json", schema: createBodySchema },
355
+ responses: [{ status: 201, description: "Comment created", schema: createResponseSchema }],
356
+ errors: [
357
+ { status: 400, description: "Invalid payload, missing task id or organization scope" },
358
+ { status: 401, description: "Unauthorized" },
359
+ { status: 403, description: "Missing staff.timesheets.tasks.manage" },
360
+ { status: 404, description: "Task not found or not accessible" }
361
+ ]
362
+ },
363
+ PUT: {
364
+ summary: "Edit a task comment",
365
+ description: "Updates a comment body. Only the comment author may edit, unless the caller holds staff.timesheets.manage_all. Honours the optimistic-lock header.",
366
+ requestBody: { contentType: "application/json", schema: updateBodySchema },
367
+ responses: [{ status: 200, description: "Comment updated", schema: okResponseSchema }],
368
+ errors: [
369
+ { status: 400, description: "Invalid payload, missing task id or organization scope" },
370
+ { status: 401, description: "Unauthorized" },
371
+ { status: 403, description: "Not the author and missing staff.timesheets.manage_all" },
372
+ { status: 404, description: "Task or comment not found or not accessible" },
373
+ { status: 409, description: "Optimistic lock conflict" }
374
+ ]
375
+ },
376
+ DELETE: {
377
+ summary: "Delete a task comment",
378
+ description: "Soft-deletes a comment so its audit trail survives. Only the comment author may delete, unless the caller holds staff.timesheets.manage_all.",
379
+ requestBody: { contentType: "application/json", schema: z.object({ id: z.string().uuid() }) },
380
+ responses: [{ status: 200, description: "Comment deleted", schema: okResponseSchema }],
381
+ errors: [
382
+ { status: 400, description: "Missing comment id, task id or organization scope" },
383
+ { status: 401, description: "Unauthorized" },
384
+ { status: 403, description: "Not the author and missing staff.timesheets.manage_all" },
385
+ { status: 404, description: "Task or comment not found or not accessible" },
386
+ { status: 409, description: "Optimistic lock conflict" }
387
+ ]
388
+ }
389
+ }
390
+ };
391
+ export {
392
+ DELETE,
393
+ GET,
394
+ POST,
395
+ PUT,
396
+ metadata,
397
+ openApi
398
+ };
399
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../../src/modules/staff/api/timesheets/tasks/%5Bid%5D/comments/route.ts"],
4
+ "sourcesContent": ["/**\n * Task comments (T3.4b) \u2014 the \"Komentarze (2)\" thread in the task drawer of\n * screen 7: avatar, author name, timestamp, body, and a composer that posts on\n * \u2318\u21B5.\n *\n * Hand-written rather than `makeCrudRoute`, for one reason that decides\n * everything else: **a caller who cannot see the task's project must not be able\n * to tell that the task exists.** A CRUD list would answer such a request with\n * an empty page \u2014 which is a different response from \"no such task\" and\n * therefore an existence oracle for every task id in the tenant. Here every\n * method funnels through the same `requireAccessibleTask` call before it touches\n * a comment, so \"not yours\" and \"does not exist\" produce one and the same 404\n * body, byte for byte.\n *\n * Because the route is hand-written it wires `runRouteMutationGuards` itself\n * (`packages/core/AGENTS.md` \u00A7 API Routes) \u2014 the same guard set every\n * `makeCrudRoute` write runs \u2014 and the writes go through the task-comment\n * commands so audit, undo, events and indexing stay consistent.\n *\n * Two more things the thread depends on:\n *\n * - **Oldest first.** Screen 7 reads as a conversation, so the list sorts by\n * `created_at ASC` with an id tiebreak, not the newest-first default a grid\n * would want.\n * - **The author's display name is resolved for rendering**, reusing the same\n * `User` lookup `api/comments.ts` uses for the team-member timeline rather\n * than inventing a cross-module join. A name that cannot be resolved degrades\n * to `null` and the thread still renders \u2014 the comment is the record, the\n * name is decoration.\n */\nimport { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport { serializeOperationMetadata } from '@open-mercato/shared/lib/commands/operationMetadata'\nimport type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'\nimport { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { runRouteMutationGuards } from '@open-mercato/shared/lib/crud/route-mutation-guard'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { parseScopedCommandInput } from '@open-mercato/shared/lib/api/scoped'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { User } from '@open-mercato/core/modules/auth/data/entities'\nimport { StaffTimeTaskComment } from '../../../../../data/entities'\nimport {\n staffTimeTaskCommentCreateSchema,\n staffTimeTaskCommentUpdateSchema,\n} from '../../../../../data/validators'\nimport { staffTimeTaskCommentCommandIds } from '../../../../../commands/timesheets-task-comments'\nimport { STAFF_TIME_TRACKING_RESOURCE_KINDS } from '../../../../guards'\nimport {\n loadTagProjectAccess as loadTaskProjectAccess,\n requireAccessibleTask,\n type TagAssignmentScope as TaskAccessScope,\n} from '../../../tags/access'\n\nconst logger = createLogger('staff').child({ component: 'api/timesheets/tasks/comments' })\n\nconst RESOURCE_KIND = STAFF_TIME_TRACKING_RESOURCE_KINDS.timeTaskComment\n\nconst VIEW_FEATURE = 'staff.timesheets.tasks.view'\nconst MANAGE_FEATURE = 'staff.timesheets.tasks.manage'\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: [VIEW_FEATURE] },\n POST: { requireAuth: true, requireFeatures: [MANAGE_FEATURE] },\n PUT: { requireAuth: true, requireFeatures: [MANAGE_FEATURE] },\n DELETE: { requireAuth: true, requireFeatures: [MANAGE_FEATURE] },\n}\n\nconst listQuerySchema = z.object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(100).default(50),\n})\n\nconst commentItemSchema = z.object({\n id: z.string().uuid(),\n taskId: z.string().uuid(),\n body: z.string(),\n authorUserId: z.string().uuid().nullable(),\n authorName: z.string().nullable(),\n authorEmail: z.string().nullable(),\n createdAt: z.string().nullable(),\n updatedAt: z.string().nullable(),\n})\n\nconst listResponseSchema = z.object({\n items: z.array(commentItemSchema),\n total: z.number().int(),\n page: z.number().int(),\n pageSize: z.number().int(),\n totalPages: z.number().int(),\n})\n\nconst createResponseSchema = z.object({\n id: z.string().uuid().nullable(),\n taskId: z.string().uuid(),\n authorUserId: z.string().uuid().nullable(),\n})\n\nconst okResponseSchema = z.object({ ok: z.boolean() })\n\nconst createBodySchema = z.object({ body: z.string().trim().min(1).max(5000) })\nconst updateBodySchema = z.object({ id: z.string().uuid(), body: z.string().trim().min(1).max(5000) })\n\ntype RouteContext = {\n ctx: CommandRuntimeContext\n scope: TaskAccessScope\n translate: (key: string, fallback?: string) => string\n taskId: string\n}\n\n/**\n * The task id comes from the path segment. Read from the URL rather than the\n * handler's `params` argument so the route behaves identically under the app's\n * catch-all dispatcher and under a direct call in tests.\n */\nfunction extractTaskId(req: Request): string | null {\n try {\n const match = new URL(req.url).pathname.match(/\\/tasks\\/([^/]+)\\/comments/)\n const id = match?.[1] ? decodeURIComponent(match[1]) : null\n return id && id.length > 0 ? id : null\n } catch {\n return null\n }\n}\n\nasync function buildRouteContext(req: Request): Promise<RouteContext> {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const { translate } = await resolveTranslations()\n if (!auth) throw new CrudHttpError(401, { error: translate('staff.errors.unauthorized', 'Unauthorized') })\n\n const organizationScope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const ctx: CommandRuntimeContext = {\n container,\n auth,\n organizationScope,\n selectedOrganizationId: organizationScope?.selectedId ?? auth.orgId ?? null,\n organizationIds: organizationScope?.filterIds ?? (auth.orgId ? [auth.orgId] : null),\n request: req,\n }\n\n const tenantId = auth.tenantId ?? null\n const organizationId = ctx.selectedOrganizationId ?? auth.orgId ?? null\n const userId = auth.sub ?? null\n if (!tenantId || !organizationId || !userId) {\n throw new CrudHttpError(400, {\n error: translate('staff.errors.missingScope', 'Missing tenant or organization scope.'),\n })\n }\n\n const taskId = extractTaskId(req)\n if (!taskId) {\n throw new CrudHttpError(400, {\n error: translate('staff.time_tracking.taskComments.errors.taskIdRequired', 'Task id is required.'),\n })\n }\n\n return { ctx, scope: { tenantId, organizationId, userId }, translate, taskId }\n}\n\n/**\n * The single gate every method passes through. Resolving project access before\n * the task is loaded \u2014 and answering both misses with one body \u2014 is what keeps\n * the endpoint from confirming that a task the caller may not see exists.\n */\nasync function requireTaskAccess(route: RouteContext): Promise<void> {\n const access = await loadTaskProjectAccess(route.ctx.container, route.scope)\n const em = (route.ctx.container.resolve('em') as EntityManager).fork()\n await requireAccessibleTask(em, route.taskId, route.scope, access, route.translate)\n}\n\nfunction commentNotFoundError(translate: (key: string, fallback?: string) => string): CrudHttpError {\n return new CrudHttpError(404, {\n error: translate('staff.time_tracking.taskComments.errors.notFound', 'Comment not found or not accessible.'),\n })\n}\n\n/**\n * A comment addressed through another task's URL is refused exactly like a\n * comment that does not exist, so the path segment cannot be swapped to reach a\n * thread the caller has no route to.\n */\nasync function requireCommentOnTask(route: RouteContext, commentId: string): Promise<StaffTimeTaskComment> {\n const em = (route.ctx.container.resolve('em') as EntityManager).fork()\n const comment = await em.findOne(StaffTimeTaskComment, {\n id: commentId,\n taskId: route.taskId,\n tenantId: route.scope.tenantId,\n organizationId: route.scope.organizationId,\n deletedAt: null,\n })\n if (!comment) throw commentNotFoundError(route.translate)\n return comment\n}\n\ntype AuthorMeta = { name: string | null; email: string | null }\n\nasync function resolveAuthorMeta(\n route: RouteContext,\n authorUserIds: string[],\n): Promise<Map<string, AuthorMeta>> {\n const map = new Map<string, AuthorMeta>()\n const unique = Array.from(new Set(authorUserIds))\n if (unique.length === 0) return map\n try {\n const em = (route.ctx.container.resolve('em') as EntityManager).fork()\n const users = await findWithDecryption(\n em,\n User,\n { id: { $in: unique } },\n undefined,\n { tenantId: route.scope.tenantId, organizationId: route.scope.organizationId },\n )\n for (const user of users) {\n const name = typeof user.name === 'string' && user.name.trim().length > 0 ? user.name.trim() : null\n map.set(user.id, { name, email: user.email ?? null })\n }\n } catch (err) {\n // A thread that renders without display names is still a usable thread.\n logger.warn('staff.timesheets.task comments failed to resolve author metadata', { err })\n }\n return map\n}\n\nfunction serializeComment(comment: StaffTimeTaskComment, authors: Map<string, AuthorMeta>) {\n const authorUserId = comment.authorUserId ?? null\n const meta = authorUserId ? authors.get(authorUserId) ?? null : null\n return {\n id: comment.id,\n taskId: comment.taskId,\n body: comment.body,\n authorUserId,\n authorName: meta?.name ?? null,\n authorEmail: meta?.email ?? null,\n createdAt: comment.createdAt ? comment.createdAt.toISOString() : null,\n updatedAt: comment.updatedAt ? comment.updatedAt.toISOString() : null,\n }\n}\n\nasync function runGuards(\n route: RouteContext,\n operation: 'create' | 'update' | 'delete',\n resourceId: string | null,\n mutationPayload: Record<string, unknown> | null,\n) {\n return runRouteMutationGuards({\n container: route.ctx.container,\n req: route.ctx.request as Request,\n auth: {\n userId: route.scope.userId,\n tenantId: route.scope.tenantId,\n organizationId: route.scope.organizationId,\n },\n input: {\n resourceKind: RESOURCE_KIND,\n resourceId,\n operation,\n mutationPayload,\n },\n })\n}\n\nfunction withOperationHeader(\n response: NextResponse,\n logEntry: {\n id?: string\n undoToken?: string | null\n commandId?: string\n actionLabel?: string | null\n resourceKind?: string | null\n resourceId?: string | null\n createdAt?: Date | string | null\n } | null | undefined,\n fallbackResourceId: string,\n): NextResponse {\n if (!logEntry?.undoToken || !logEntry.id || !logEntry.commandId) return response\n response.headers.set(\n 'x-om-operation',\n serializeOperationMetadata({\n id: logEntry.id,\n undoToken: logEntry.undoToken,\n commandId: logEntry.commandId,\n actionLabel: logEntry.actionLabel ?? null,\n resourceKind: logEntry.resourceKind ?? RESOURCE_KIND,\n resourceId: logEntry.resourceId ?? fallbackResourceId,\n executedAt:\n logEntry.createdAt instanceof Date\n ? logEntry.createdAt.toISOString()\n : typeof logEntry.createdAt === 'string'\n ? logEntry.createdAt\n : new Date().toISOString(),\n }),\n )\n return response\n}\n\nasync function errorResponse(err: unknown, message: string): Promise<Response> {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const { translate } = await resolveTranslations()\n if (err instanceof z.ZodError) {\n return NextResponse.json(\n { error: translate('staff.errors.invalid_request', 'Invalid request'), details: err.issues },\n { status: 400 },\n )\n }\n logger.error(message, { err })\n return NextResponse.json({ error: translate('staff.errors.internal', 'Internal server error') }, { status: 500 })\n}\n\nexport async function GET(req: Request) {\n try {\n const route = await buildRouteContext(req)\n await requireTaskAccess(route)\n\n const url = new URL(req.url)\n const query = listQuerySchema.parse({\n page: url.searchParams.get('page') ?? undefined,\n pageSize: url.searchParams.get('pageSize') ?? undefined,\n })\n\n const em = (route.ctx.container.resolve('em') as EntityManager).fork()\n const [comments, total] = await em.findAndCount(\n StaffTimeTaskComment,\n {\n taskId: route.taskId,\n tenantId: route.scope.tenantId,\n organizationId: route.scope.organizationId,\n deletedAt: null,\n },\n {\n // Oldest first \u2014 the drawer reads the thread top to bottom.\n orderBy: { createdAt: 'asc', id: 'asc' },\n limit: query.pageSize,\n offset: (query.page - 1) * query.pageSize,\n },\n )\n\n const authors = await resolveAuthorMeta(\n route,\n comments.map((comment) => comment.authorUserId).filter((id): id is string => typeof id === 'string'),\n )\n\n return NextResponse.json({\n items: comments.map((comment) => serializeComment(comment, authors)),\n total,\n page: query.page,\n pageSize: query.pageSize,\n totalPages: query.pageSize > 0 ? Math.ceil(total / query.pageSize) : 0,\n })\n } catch (err) {\n return errorResponse(err, 'staff.timesheets.tasks.comments.GET failed')\n }\n}\n\nexport async function POST(req: Request) {\n try {\n const route = await buildRouteContext(req)\n await requireTaskAccess(route)\n\n const raw = await readJsonSafe(req, {})\n const parsedBody = createBodySchema.parse(raw ?? {})\n // `authorUserId` is never forwarded: whatever the client sent is dropped\n // here and the command stamps the authenticated caller instead.\n const input = parseScopedCommandInput(\n staffTimeTaskCommentCreateSchema,\n { taskId: route.taskId, body: parsedBody.body },\n route.ctx,\n route.translate,\n )\n\n const guardResult = await runGuards(route, 'create', route.taskId, input as unknown as Record<string, unknown>)\n if (!guardResult.ok) return guardResult.response\n\n const commandBus = route.ctx.container.resolve('commandBus') as CommandBus\n const { result, logEntry } = await commandBus.execute<\n typeof input,\n { commentId: string; taskId: string; authorUserId: string | null }\n >(staffTimeTaskCommentCommandIds.create, { input, ctx: route.ctx })\n\n await guardResult.runAfterSuccess()\n\n const response = NextResponse.json(\n {\n id: result?.commentId ?? null,\n taskId: route.taskId,\n authorUserId: result?.authorUserId ?? null,\n },\n { status: 201 },\n )\n return withOperationHeader(response, logEntry, result?.commentId ?? route.taskId)\n } catch (err) {\n const interceptorRejection = getCommandInterceptorHttpRejection(err)\n if (interceptorRejection) {\n return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })\n }\n return errorResponse(err, 'staff.timesheets.tasks.comments.POST failed')\n }\n}\n\nexport async function PUT(req: Request) {\n try {\n const route = await buildRouteContext(req)\n await requireTaskAccess(route)\n\n const raw = await readJsonSafe(req, {})\n const parsedBody = updateBodySchema.parse(raw ?? {})\n await requireCommentOnTask(route, parsedBody.id)\n\n const input = staffTimeTaskCommentUpdateSchema.parse({ id: parsedBody.id, body: parsedBody.body })\n\n const guardResult = await runGuards(route, 'update', input.id, input as unknown as Record<string, unknown>)\n if (!guardResult.ok) return guardResult.response\n\n const commandBus = route.ctx.container.resolve('commandBus') as CommandBus\n const { logEntry } = await commandBus.execute<typeof input, { commentId: string; taskId: string }>(\n staffTimeTaskCommentCommandIds.update,\n { input, ctx: route.ctx },\n )\n\n await guardResult.runAfterSuccess()\n\n return withOperationHeader(NextResponse.json({ ok: true }), logEntry, input.id)\n } catch (err) {\n const interceptorRejection = getCommandInterceptorHttpRejection(err)\n if (interceptorRejection) {\n return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })\n }\n return errorResponse(err, 'staff.timesheets.tasks.comments.PUT failed')\n }\n}\n\nexport async function DELETE(req: Request) {\n try {\n const route = await buildRouteContext(req)\n await requireTaskAccess(route)\n\n const url = new URL(req.url)\n const raw = await readJsonSafe(req, {})\n const rawId = url.searchParams.get('id') ?? (raw as { id?: unknown } | null)?.id\n const id = z.string().uuid().parse(typeof rawId === 'string' ? rawId : undefined)\n await requireCommentOnTask(route, id)\n\n const guardResult = await runGuards(route, 'delete', id, { id })\n if (!guardResult.ok) return guardResult.response\n\n const commandBus = route.ctx.container.resolve('commandBus') as CommandBus\n const { logEntry } = await commandBus.execute<{ id: string }, { commentId: string; taskId: string }>(\n staffTimeTaskCommentCommandIds.delete,\n { input: { id }, ctx: route.ctx },\n )\n\n await guardResult.runAfterSuccess()\n\n return withOperationHeader(NextResponse.json({ ok: true }), logEntry, id)\n } catch (err) {\n const interceptorRejection = getCommandInterceptorHttpRejection(err)\n if (interceptorRejection) {\n return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })\n }\n return errorResponse(err, 'staff.timesheets.tasks.comments.DELETE failed')\n }\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Staff',\n summary: 'Task comments',\n methods: {\n GET: {\n summary: 'List task comments',\n description:\n 'Returns the task comment thread oldest-first, with the author display name resolved for rendering. Answers 404 \u2014 identical to a task that does not exist \u2014 when the task belongs to a project the caller cannot see.',\n query: listQuerySchema,\n responses: [{ status: 200, description: 'Comment thread', schema: listResponseSchema }],\n errors: [\n { status: 400, description: 'Missing task id or organization scope' },\n { status: 401, description: 'Unauthorized' },\n { status: 403, description: 'Missing staff.timesheets.tasks.view' },\n { status: 404, description: 'Task not found or not accessible' },\n ],\n },\n POST: {\n summary: 'Post a task comment',\n description:\n 'Adds a comment to the task. The author is stamped from the authenticated caller \u2014 an authorUserId supplied by the client is ignored.',\n requestBody: { contentType: 'application/json', schema: createBodySchema },\n responses: [{ status: 201, description: 'Comment created', schema: createResponseSchema }],\n errors: [\n { status: 400, description: 'Invalid payload, missing task id or organization scope' },\n { status: 401, description: 'Unauthorized' },\n { status: 403, description: 'Missing staff.timesheets.tasks.manage' },\n { status: 404, description: 'Task not found or not accessible' },\n ],\n },\n PUT: {\n summary: 'Edit a task comment',\n description:\n 'Updates a comment body. Only the comment author may edit, unless the caller holds staff.timesheets.manage_all. Honours the optimistic-lock header.',\n requestBody: { contentType: 'application/json', schema: updateBodySchema },\n responses: [{ status: 200, description: 'Comment updated', schema: okResponseSchema }],\n errors: [\n { status: 400, description: 'Invalid payload, missing task id or organization scope' },\n { status: 401, description: 'Unauthorized' },\n { status: 403, description: 'Not the author and missing staff.timesheets.manage_all' },\n { status: 404, description: 'Task or comment not found or not accessible' },\n { status: 409, description: 'Optimistic lock conflict' },\n ],\n },\n DELETE: {\n summary: 'Delete a task comment',\n description:\n 'Soft-deletes a comment so its audit trail survives. Only the comment author may delete, unless the caller holds staff.timesheets.manage_all.',\n requestBody: { contentType: 'application/json', schema: z.object({ id: z.string().uuid() }) },\n responses: [{ status: 200, description: 'Comment deleted', schema: okResponseSchema }],\n errors: [\n { status: 400, description: 'Missing comment id, task id or organization scope' },\n { status: 401, description: 'Unauthorized' },\n { status: 403, description: 'Not the author and missing staff.timesheets.manage_all' },\n { status: 404, description: 'Task or comment not found or not accessible' },\n { status: 409, description: 'Optimistic lock conflict' },\n ],\n },\n },\n}\n"],
5
+ "mappings": "AA8BA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,0CAA0C;AACnD,SAAS,kCAAkC;AAE3C,SAAS,0CAA0C;AACnD,SAAS,eAAe,uBAAuB;AAC/C,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AACpC,SAAS,+BAA+B;AACxC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAE7B,SAAS,YAAY;AACrB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,sCAAsC;AAC/C,SAAS,0CAA0C;AACnD;AAAA,EACE,wBAAwB;AAAA,EACxB;AAAA,OAEK;AAEP,MAAM,SAAS,aAAa,OAAO,EAAE,MAAM,EAAE,WAAW,gCAAgC,CAAC;AAEzF,MAAM,gBAAgB,mCAAmC;AAEzD,MAAM,eAAe;AACrB,MAAM,iBAAiB;AAEhB,MAAM,WAAW;AAAA,EACtB,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,YAAY,EAAE;AAAA,EAC1D,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,cAAc,EAAE;AAAA,EAC7D,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,cAAc,EAAE;AAAA,EAC5D,QAAQ,EAAE,aAAa,MAAM,iBAAiB,CAAC,cAAc,EAAE;AACjE;AAEA,MAAM,kBAAkB,EAAE,OAAO;AAAA,EAC/B,MAAM,EAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EACxC,UAAU,EAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AACxD,CAAC;AAED,MAAM,oBAAoB,EAAE,OAAO;AAAA,EACjC,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,EACpB,QAAQ,EAAE,OAAO,EAAE,KAAK;AAAA,EACxB,MAAM,EAAE,OAAO;AAAA,EACf,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACzC,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAED,MAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,OAAO,EAAE,MAAM,iBAAiB;AAAA,EAChC,OAAO,EAAE,OAAO,EAAE,IAAI;AAAA,EACtB,MAAM,EAAE,OAAO,EAAE,IAAI;AAAA,EACrB,UAAU,EAAE,OAAO,EAAE,IAAI;AAAA,EACzB,YAAY,EAAE,OAAO,EAAE,IAAI;AAC7B,CAAC;AAED,MAAM,uBAAuB,EAAE,OAAO;AAAA,EACpC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EAC/B,QAAQ,EAAE,OAAO,EAAE,KAAK;AAAA,EACxB,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAC3C,CAAC;AAED,MAAM,mBAAmB,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAErD,MAAM,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,EAAE,CAAC;AAC9E,MAAM,mBAAmB,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,EAAE,CAAC;AAcrG,SAAS,cAAc,KAA6B;AAClD,MAAI;AACF,UAAM,QAAQ,IAAI,IAAI,IAAI,GAAG,EAAE,SAAS,MAAM,4BAA4B;AAC1E,UAAM,KAAK,QAAQ,CAAC,IAAI,mBAAmB,MAAM,CAAC,CAAC,IAAI;AACvD,WAAO,MAAM,GAAG,SAAS,IAAI,KAAK;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,kBAAkB,KAAqC;AACpE,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,QAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,MAAI,CAAC,KAAM,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,6BAA6B,cAAc,EAAE,CAAC;AAEzG,QAAM,oBAAoB,MAAM,mCAAmC,EAAE,WAAW,MAAM,SAAS,IAAI,CAAC;AACpG,QAAM,MAA6B;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA,wBAAwB,mBAAmB,cAAc,KAAK,SAAS;AAAA,IACvE,iBAAiB,mBAAmB,cAAc,KAAK,QAAQ,CAAC,KAAK,KAAK,IAAI;AAAA,IAC9E,SAAS;AAAA,EACX;AAEA,QAAM,WAAW,KAAK,YAAY;AAClC,QAAM,iBAAiB,IAAI,0BAA0B,KAAK,SAAS;AACnE,QAAM,SAAS,KAAK,OAAO;AAC3B,MAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,QAAQ;AAC3C,UAAM,IAAI,cAAc,KAAK;AAAA,MAC3B,OAAO,UAAU,6BAA6B,uCAAuC;AAAA,IACvF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,cAAc,GAAG;AAChC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,cAAc,KAAK;AAAA,MAC3B,OAAO,UAAU,0DAA0D,sBAAsB;AAAA,IACnG,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,KAAK,OAAO,EAAE,UAAU,gBAAgB,OAAO,GAAG,WAAW,OAAO;AAC/E;AAOA,eAAe,kBAAkB,OAAoC;AACnE,QAAM,SAAS,MAAM,sBAAsB,MAAM,IAAI,WAAW,MAAM,KAAK;AAC3E,QAAM,KAAM,MAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AACrE,QAAM,sBAAsB,IAAI,MAAM,QAAQ,MAAM,OAAO,QAAQ,MAAM,SAAS;AACpF;AAEA,SAAS,qBAAqB,WAAsE;AAClG,SAAO,IAAI,cAAc,KAAK;AAAA,IAC5B,OAAO,UAAU,oDAAoD,sCAAsC;AAAA,EAC7G,CAAC;AACH;AAOA,eAAe,qBAAqB,OAAqB,WAAkD;AACzG,QAAM,KAAM,MAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AACrE,QAAM,UAAU,MAAM,GAAG,QAAQ,sBAAsB;AAAA,IACrD,IAAI;AAAA,IACJ,QAAQ,MAAM;AAAA,IACd,UAAU,MAAM,MAAM;AAAA,IACtB,gBAAgB,MAAM,MAAM;AAAA,IAC5B,WAAW;AAAA,EACb,CAAC;AACD,MAAI,CAAC,QAAS,OAAM,qBAAqB,MAAM,SAAS;AACxD,SAAO;AACT;AAIA,eAAe,kBACb,OACA,eACkC;AAClC,QAAM,MAAM,oBAAI,IAAwB;AACxC,QAAM,SAAS,MAAM,KAAK,IAAI,IAAI,aAAa,CAAC;AAChD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,MAAI;AACF,UAAM,KAAM,MAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AACrE,UAAM,QAAQ,MAAM;AAAA,MAClB;AAAA,MACA;AAAA,MACA,EAAE,IAAI,EAAE,KAAK,OAAO,EAAE;AAAA,MACtB;AAAA,MACA,EAAE,UAAU,MAAM,MAAM,UAAU,gBAAgB,MAAM,MAAM,eAAe;AAAA,IAC/E;AACA,eAAW,QAAQ,OAAO;AACxB,YAAM,OAAO,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,KAAK,EAAE,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI;AAC/F,UAAI,IAAI,KAAK,IAAI,EAAE,MAAM,OAAO,KAAK,SAAS,KAAK,CAAC;AAAA,IACtD;AAAA,EACF,SAAS,KAAK;AAEZ,WAAO,KAAK,oEAAoE,EAAE,IAAI,CAAC;AAAA,EACzF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAA+B,SAAkC;AACzF,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,QAAM,OAAO,eAAe,QAAQ,IAAI,YAAY,KAAK,OAAO;AAChE,SAAO;AAAA,IACL,IAAI,QAAQ;AAAA,IACZ,QAAQ,QAAQ;AAAA,IAChB,MAAM,QAAQ;AAAA,IACd;AAAA,IACA,YAAY,MAAM,QAAQ;AAAA,IAC1B,aAAa,MAAM,SAAS;AAAA,IAC5B,WAAW,QAAQ,YAAY,QAAQ,UAAU,YAAY,IAAI;AAAA,IACjE,WAAW,QAAQ,YAAY,QAAQ,UAAU,YAAY,IAAI;AAAA,EACnE;AACF;AAEA,eAAe,UACb,OACA,WACA,YACA,iBACA;AACA,SAAO,uBAAuB;AAAA,IAC5B,WAAW,MAAM,IAAI;AAAA,IACrB,KAAK,MAAM,IAAI;AAAA,IACf,MAAM;AAAA,MACJ,QAAQ,MAAM,MAAM;AAAA,MACpB,UAAU,MAAM,MAAM;AAAA,MACtB,gBAAgB,MAAM,MAAM;AAAA,IAC9B;AAAA,IACA,OAAO;AAAA,MACL,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,oBACP,UACA,UASA,oBACc;AACd,MAAI,CAAC,UAAU,aAAa,CAAC,SAAS,MAAM,CAAC,SAAS,UAAW,QAAO;AACxE,WAAS,QAAQ;AAAA,IACf;AAAA,IACA,2BAA2B;AAAA,MACzB,IAAI,SAAS;AAAA,MACb,WAAW,SAAS;AAAA,MACpB,WAAW,SAAS;AAAA,MACpB,aAAa,SAAS,eAAe;AAAA,MACrC,cAAc,SAAS,gBAAgB;AAAA,MACvC,YAAY,SAAS,cAAc;AAAA,MACnC,YACE,SAAS,qBAAqB,OAC1B,SAAS,UAAU,YAAY,IAC/B,OAAO,SAAS,cAAc,WAC5B,SAAS,aACT,oBAAI,KAAK,GAAE,YAAY;AAAA,IACjC,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,eAAe,cAAc,KAAc,SAAoC;AAC7E,MAAI,gBAAgB,GAAG,GAAG;AACxB,WAAO,aAAa,KAAK,IAAI,MAAM,EAAE,QAAQ,IAAI,OAAO,CAAC;AAAA,EAC3D;AACA,QAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,MAAI,eAAe,EAAE,UAAU;AAC7B,WAAO,aAAa;AAAA,MAClB,EAAE,OAAO,UAAU,gCAAgC,iBAAiB,GAAG,SAAS,IAAI,OAAO;AAAA,MAC3F,EAAE,QAAQ,IAAI;AAAA,IAChB;AAAA,EACF;AACA,SAAO,MAAM,SAAS,EAAE,IAAI,CAAC;AAC7B,SAAO,aAAa,KAAK,EAAE,OAAO,UAAU,yBAAyB,uBAAuB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAClH;AAEA,eAAsB,IAAI,KAAc;AACtC,MAAI;AACF,UAAM,QAAQ,MAAM,kBAAkB,GAAG;AACzC,UAAM,kBAAkB,KAAK;AAE7B,UAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,UAAM,QAAQ,gBAAgB,MAAM;AAAA,MAClC,MAAM,IAAI,aAAa,IAAI,MAAM,KAAK;AAAA,MACtC,UAAU,IAAI,aAAa,IAAI,UAAU,KAAK;AAAA,IAChD,CAAC;AAED,UAAM,KAAM,MAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AACrE,UAAM,CAAC,UAAU,KAAK,IAAI,MAAM,GAAG;AAAA,MACjC;AAAA,MACA;AAAA,QACE,QAAQ,MAAM;AAAA,QACd,UAAU,MAAM,MAAM;AAAA,QACtB,gBAAgB,MAAM,MAAM;AAAA,QAC5B,WAAW;AAAA,MACb;AAAA,MACA;AAAA;AAAA,QAEE,SAAS,EAAE,WAAW,OAAO,IAAI,MAAM;AAAA,QACvC,OAAO,MAAM;AAAA,QACb,SAAS,MAAM,OAAO,KAAK,MAAM;AAAA,MACnC;AAAA,IACF;AAEA,UAAM,UAAU,MAAM;AAAA,MACpB;AAAA,MACA,SAAS,IAAI,CAAC,YAAY,QAAQ,YAAY,EAAE,OAAO,CAAC,OAAqB,OAAO,OAAO,QAAQ;AAAA,IACrG;AAEA,WAAO,aAAa,KAAK;AAAA,MACvB,OAAO,SAAS,IAAI,CAAC,YAAY,iBAAiB,SAAS,OAAO,CAAC;AAAA,MACnE;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM;AAAA,MAChB,YAAY,MAAM,WAAW,IAAI,KAAK,KAAK,QAAQ,MAAM,QAAQ,IAAI;AAAA,IACvE,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,WAAO,cAAc,KAAK,4CAA4C;AAAA,EACxE;AACF;AAEA,eAAsB,KAAK,KAAc;AACvC,MAAI;AACF,UAAM,QAAQ,MAAM,kBAAkB,GAAG;AACzC,UAAM,kBAAkB,KAAK;AAE7B,UAAM,MAAM,MAAM,aAAa,KAAK,CAAC,CAAC;AACtC,UAAM,aAAa,iBAAiB,MAAM,OAAO,CAAC,CAAC;AAGnD,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA,EAAE,QAAQ,MAAM,QAAQ,MAAM,WAAW,KAAK;AAAA,MAC9C,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAEA,UAAM,cAAc,MAAM,UAAU,OAAO,UAAU,MAAM,QAAQ,KAA2C;AAC9G,QAAI,CAAC,YAAY,GAAI,QAAO,YAAY;AAExC,UAAM,aAAa,MAAM,IAAI,UAAU,QAAQ,YAAY;AAC3D,UAAM,EAAE,QAAQ,SAAS,IAAI,MAAM,WAAW,QAG5C,+BAA+B,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAElE,UAAM,YAAY,gBAAgB;AAElC,UAAM,WAAW,aAAa;AAAA,MAC5B;AAAA,QACE,IAAI,QAAQ,aAAa;AAAA,QACzB,QAAQ,MAAM;AAAA,QACd,cAAc,QAAQ,gBAAgB;AAAA,MACxC;AAAA,MACA,EAAE,QAAQ,IAAI;AAAA,IAChB;AACA,WAAO,oBAAoB,UAAU,UAAU,QAAQ,aAAa,MAAM,MAAM;AAAA,EAClF,SAAS,KAAK;AACZ,UAAM,uBAAuB,mCAAmC,GAAG;AACnE,QAAI,sBAAsB;AACxB,aAAO,aAAa,KAAK,qBAAqB,MAAM,EAAE,QAAQ,qBAAqB,OAAO,CAAC;AAAA,IAC7F;AACA,WAAO,cAAc,KAAK,6CAA6C;AAAA,EACzE;AACF;AAEA,eAAsB,IAAI,KAAc;AACtC,MAAI;AACF,UAAM,QAAQ,MAAM,kBAAkB,GAAG;AACzC,UAAM,kBAAkB,KAAK;AAE7B,UAAM,MAAM,MAAM,aAAa,KAAK,CAAC,CAAC;AACtC,UAAM,aAAa,iBAAiB,MAAM,OAAO,CAAC,CAAC;AACnD,UAAM,qBAAqB,OAAO,WAAW,EAAE;AAE/C,UAAM,QAAQ,iCAAiC,MAAM,EAAE,IAAI,WAAW,IAAI,MAAM,WAAW,KAAK,CAAC;AAEjG,UAAM,cAAc,MAAM,UAAU,OAAO,UAAU,MAAM,IAAI,KAA2C;AAC1G,QAAI,CAAC,YAAY,GAAI,QAAO,YAAY;AAExC,UAAM,aAAa,MAAM,IAAI,UAAU,QAAQ,YAAY;AAC3D,UAAM,EAAE,SAAS,IAAI,MAAM,WAAW;AAAA,MACpC,+BAA+B;AAAA,MAC/B,EAAE,OAAO,KAAK,MAAM,IAAI;AAAA,IAC1B;AAEA,UAAM,YAAY,gBAAgB;AAElC,WAAO,oBAAoB,aAAa,KAAK,EAAE,IAAI,KAAK,CAAC,GAAG,UAAU,MAAM,EAAE;AAAA,EAChF,SAAS,KAAK;AACZ,UAAM,uBAAuB,mCAAmC,GAAG;AACnE,QAAI,sBAAsB;AACxB,aAAO,aAAa,KAAK,qBAAqB,MAAM,EAAE,QAAQ,qBAAqB,OAAO,CAAC;AAAA,IAC7F;AACA,WAAO,cAAc,KAAK,4CAA4C;AAAA,EACxE;AACF;AAEA,eAAsB,OAAO,KAAc;AACzC,MAAI;AACF,UAAM,QAAQ,MAAM,kBAAkB,GAAG;AACzC,UAAM,kBAAkB,KAAK;AAE7B,UAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,UAAM,MAAM,MAAM,aAAa,KAAK,CAAC,CAAC;AACtC,UAAM,QAAQ,IAAI,aAAa,IAAI,IAAI,KAAM,KAAiC;AAC9E,UAAM,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,UAAU,WAAW,QAAQ,MAAS;AAChF,UAAM,qBAAqB,OAAO,EAAE;AAEpC,UAAM,cAAc,MAAM,UAAU,OAAO,UAAU,IAAI,EAAE,GAAG,CAAC;AAC/D,QAAI,CAAC,YAAY,GAAI,QAAO,YAAY;AAExC,UAAM,aAAa,MAAM,IAAI,UAAU,QAAQ,YAAY;AAC3D,UAAM,EAAE,SAAS,IAAI,MAAM,WAAW;AAAA,MACpC,+BAA+B;AAAA,MAC/B,EAAE,OAAO,EAAE,GAAG,GAAG,KAAK,MAAM,IAAI;AAAA,IAClC;AAEA,UAAM,YAAY,gBAAgB;AAElC,WAAO,oBAAoB,aAAa,KAAK,EAAE,IAAI,KAAK,CAAC,GAAG,UAAU,EAAE;AAAA,EAC1E,SAAS,KAAK;AACZ,UAAM,uBAAuB,mCAAmC,GAAG;AACnE,QAAI,sBAAsB;AACxB,aAAO,aAAa,KAAK,qBAAqB,MAAM,EAAE,QAAQ,qBAAqB,OAAO,CAAC;AAAA,IAC7F;AACA,WAAO,cAAc,KAAK,+CAA+C;AAAA,EAC3E;AACF;AAEO,MAAM,UAA2B;AAAA,EACtC,KAAK;AAAA,EACL,SAAS;AAAA,EACT,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,aACE;AAAA,MACF,OAAO;AAAA,MACP,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,kBAAkB,QAAQ,mBAAmB,CAAC;AAAA,MACtF,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,wCAAwC;AAAA,QACpE,EAAE,QAAQ,KAAK,aAAa,eAAe;AAAA,QAC3C,EAAE,QAAQ,KAAK,aAAa,sCAAsC;AAAA,QAClE,EAAE,QAAQ,KAAK,aAAa,mCAAmC;AAAA,MACjE;AAAA,IACF;AAAA,IACA,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,aACE;AAAA,MACF,aAAa,EAAE,aAAa,oBAAoB,QAAQ,iBAAiB;AAAA,MACzE,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,mBAAmB,QAAQ,qBAAqB,CAAC;AAAA,MACzF,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,yDAAyD;AAAA,QACrF,EAAE,QAAQ,KAAK,aAAa,eAAe;AAAA,QAC3C,EAAE,QAAQ,KAAK,aAAa,wCAAwC;AAAA,QACpE,EAAE,QAAQ,KAAK,aAAa,mCAAmC;AAAA,MACjE;AAAA,IACF;AAAA,IACA,KAAK;AAAA,MACH,SAAS;AAAA,MACT,aACE;AAAA,MACF,aAAa,EAAE,aAAa,oBAAoB,QAAQ,iBAAiB;AAAA,MACzE,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,mBAAmB,QAAQ,iBAAiB,CAAC;AAAA,MACrF,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,yDAAyD;AAAA,QACrF,EAAE,QAAQ,KAAK,aAAa,eAAe;AAAA,QAC3C,EAAE,QAAQ,KAAK,aAAa,yDAAyD;AAAA,QACrF,EAAE,QAAQ,KAAK,aAAa,8CAA8C;AAAA,QAC1E,EAAE,QAAQ,KAAK,aAAa,2BAA2B;AAAA,MACzD;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,aACE;AAAA,MACF,aAAa,EAAE,aAAa,oBAAoB,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE;AAAA,MAC5F,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,mBAAmB,QAAQ,iBAAiB,CAAC;AAAA,MACrF,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,oDAAoD;AAAA,QAChF,EAAE,QAAQ,KAAK,aAAa,eAAe;AAAA,QAC3C,EAAE,QAAQ,KAAK,aAAa,yDAAyD;AAAA,QACrF,EAAE,QAAQ,KAAK,aAAa,8CAA8C;AAAA,QAC1E,EAAE,QAAQ,KAAK,aAAa,2BAA2B;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }