@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.
- package/.turbo/turbo-build.log +2 -2
- package/dist/generated/entities/staff_time_entry/index.js +14 -0
- package/dist/generated/entities/staff_time_entry/index.js.map +2 -2
- package/dist/generated/entities/staff_time_entry_tag/index.js +15 -0
- package/dist/generated/entities/staff_time_entry_tag/index.js.map +7 -0
- package/dist/generated/entities/staff_time_project/index.js +16 -0
- package/dist/generated/entities/staff_time_project/index.js.map +2 -2
- package/dist/generated/entities/staff_time_report/index.js +57 -0
- package/dist/generated/entities/staff_time_report/index.js.map +7 -0
- package/dist/generated/entities/staff_time_report_entry/index.js +27 -0
- package/dist/generated/entities/staff_time_report_entry/index.js.map +7 -0
- package/dist/generated/entities/staff_time_report_event/index.js +21 -0
- package/dist/generated/entities/staff_time_report_event/index.js.map +7 -0
- package/dist/generated/entities/staff_time_report_project/index.js +15 -0
- package/dist/generated/entities/staff_time_report_project/index.js.map +7 -0
- package/dist/generated/entities/staff_time_tag/index.js +21 -0
- package/dist/generated/entities/staff_time_tag/index.js.map +7 -0
- package/dist/generated/entities/staff_time_task/index.js +37 -0
- package/dist/generated/entities/staff_time_task/index.js.map +7 -0
- package/dist/generated/entities/staff_time_task_comment/index.js +21 -0
- package/dist/generated/entities/staff_time_task_comment/index.js.map +7 -0
- package/dist/generated/entities/staff_time_task_status/index.js +29 -0
- package/dist/generated/entities/staff_time_task_status/index.js.map +7 -0
- package/dist/generated/entities/staff_time_task_tag/index.js +15 -0
- package/dist/generated/entities/staff_time_task_tag/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +11 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +149 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/timesheetFixtures.js +7 -0
- package/dist/helpers/integration/timesheetFixtures.js.map +2 -2
- package/dist/modules/auth/cli.js +16 -0
- package/dist/modules/auth/cli.js.map +2 -2
- package/dist/modules/auth/lib/backendChrome.js +1 -0
- package/dist/modules/auth/lib/backendChrome.js.map +2 -2
- package/dist/modules/customer_accounts/lib/customerRoleAcls.js +44 -0
- package/dist/modules/customer_accounts/lib/customerRoleAcls.js.map +7 -0
- package/dist/modules/customer_accounts/setup.js +1 -28
- package/dist/modules/customer_accounts/setup.js.map +2 -2
- package/dist/modules/data_sync/api/options.js +2 -0
- package/dist/modules/data_sync/api/options.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +39 -17
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/lib/start-controls.js +42 -0
- package/dist/modules/data_sync/lib/start-controls.js.map +7 -0
- package/dist/modules/staff/acl.js +9 -1
- package/dist/modules/staff/acl.js.map +2 -2
- package/dist/modules/staff/ai-agents.js +142 -0
- package/dist/modules/staff/ai-agents.js.map +7 -0
- package/dist/modules/staff/ai-tools/time-tracking-pack.js +348 -0
- package/dist/modules/staff/ai-tools/time-tracking-pack.js.map +7 -0
- package/dist/modules/staff/ai-tools/types.js +54 -0
- package/dist/modules/staff/ai-tools/types.js.map +7 -0
- package/dist/modules/staff/ai-tools.js +8 -0
- package/dist/modules/staff/ai-tools.js.map +7 -0
- package/dist/modules/staff/analytics.js +84 -1
- package/dist/modules/staff/analytics.js.map +2 -2
- package/dist/modules/staff/api/guards.js +37 -3
- package/dist/modules/staff/api/guards.js.map +2 -2
- package/dist/modules/staff/api/leave-requests/accept/route.js +1 -3
- package/dist/modules/staff/api/leave-requests/accept/route.js.map +2 -2
- package/dist/modules/staff/api/leave-requests/reject/route.js +1 -3
- package/dist/modules/staff/api/leave-requests/reject/route.js.map +2 -2
- package/dist/modules/staff/api/portal/time-reports/[id]/route.js +131 -0
- package/dist/modules/staff/api/portal/time-reports/[id]/route.js.map +7 -0
- package/dist/modules/staff/api/portal/time-reports/route.js +179 -0
- package/dist/modules/staff/api/portal/time-reports/route.js.map +7 -0
- package/dist/modules/staff/api/team-members/self/route.js +1 -3
- package/dist/modules/staff/api/team-members/self/route.js.map +2 -2
- package/dist/modules/staff/api/team-members/tags/assign/route.js +1 -3
- package/dist/modules/staff/api/team-members/tags/assign/route.js.map +2 -2
- package/dist/modules/staff/api/team-members/tags/unassign/route.js +1 -3
- package/dist/modules/staff/api/team-members/tags/unassign/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/_shared/withTimesheetInterceptors.js +174 -0
- package/dist/modules/staff/api/timesheets/_shared/withTimesheetInterceptors.js.map +7 -0
- package/dist/modules/staff/api/timesheets/access-requests/route.js +226 -0
- package/dist/modules/staff/api/timesheets/access-requests/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js +15 -8
- package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/my-projects/route.js +13 -1
- package/dist/modules/staff/api/timesheets/my-projects/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/my-work/myWorkAggregate.js +42 -0
- package/dist/modules/staff/api/timesheets/my-work/myWorkAggregate.js.map +7 -0
- package/dist/modules/staff/api/timesheets/my-work/route.js +383 -0
- package/dist/modules/staff/api/timesheets/my-work/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/projects/kpis/route.js +14 -2
- package/dist/modules/staff/api/timesheets/projects/kpis/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/reports/[id]/close/route.js +168 -0
- package/dist/modules/staff/api/timesheets/reports/[id]/close/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/reports/[id]/export/route.js +246 -0
- package/dist/modules/staff/api/timesheets/reports/[id]/export/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/reports/[id]/sheet/route.js +183 -0
- package/dist/modules/staff/api/timesheets/reports/[id]/sheet/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/reports/[id]/unlock/route.js +164 -0
- package/dist/modules/staff/api/timesheets/reports/[id]/unlock/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/reports/preview/route.js +360 -0
- package/dist/modules/staff/api/timesheets/reports/preview/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/reports/route.js +316 -0
- package/dist/modules/staff/api/timesheets/reports/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/reports/shared.js +63 -0
- package/dist/modules/staff/api/timesheets/reports/shared.js.map +7 -0
- package/dist/modules/staff/api/timesheets/settings/reapply-rounding/route.js +164 -0
- package/dist/modules/staff/api/timesheets/settings/reapply-rounding/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/settings/rounding-impact/route.js +168 -0
- package/dist/modules/staff/api/timesheets/settings/rounding-impact/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/settings/route.js +199 -0
- package/dist/modules/staff/api/timesheets/settings/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/tags/access.js +76 -0
- package/dist/modules/staff/api/timesheets/tags/access.js.map +7 -0
- package/dist/modules/staff/api/timesheets/tags/entry-assignments/route.js +235 -0
- package/dist/modules/staff/api/timesheets/tags/entry-assignments/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/tags/route.js +160 -0
- package/dist/modules/staff/api/timesheets/tags/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/tags/task-assignments/route.js +233 -0
- package/dist/modules/staff/api/timesheets/tags/task-assignments/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/task-statuses/route.js +188 -0
- package/dist/modules/staff/api/timesheets/task-statuses/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js +399 -0
- package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/tasks/[id]/status/route.js +210 -0
- package/dist/modules/staff/api/timesheets/tasks/[id]/status/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/tasks/route.js +333 -0
- package/dist/modules/staff/api/timesheets/tasks/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/duplicate/route.js +228 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/duplicate/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.js +29 -10
- package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js +31 -18
- package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +21 -7
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js +27 -7
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js +215 -32
- package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/copy-day/route.js +378 -0
- package/dist/modules/staff/api/timesheets/time-entries/copy-day/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-entries/overlaps/route.js +340 -0
- package/dist/modules/staff/api/timesheets/time-entries/overlaps/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-entries/route.js +238 -26
- package/dist/modules/staff/api/timesheets/time-entries/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js +23 -8
- package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-projects/[id]/change-currency/route.js +209 -0
- package/dist/modules/staff/api/timesheets/time-projects/[id]/change-currency/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js +59 -2
- package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-projects/route.js +264 -22
- package/dist/modules/staff/api/timesheets/time-projects/route.js.map +2 -2
- package/dist/modules/staff/backend/staff/time-tracking/board/page.js +110 -0
- package/dist/modules/staff/backend/staff/time-tracking/board/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/board/page.meta.js +18 -0
- package/dist/modules/staff/backend/staff/time-tracking/board/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/entries/page.js +981 -0
- package/dist/modules/staff/backend/staff/time-tracking/entries/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/entries/page.meta.js +18 -0
- package/dist/modules/staff/backend/staff/time-tracking/entries/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/page.js +583 -0
- package/dist/modules/staff/backend/staff/time-tracking/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/page.meta.js +15 -0
- package/dist/modules/staff/backend/staff/time-tracking/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.js +65 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.meta.js +16 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js +229 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.meta.js +16 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +1014 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.meta.js +16 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.js +97 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.meta.js +16 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/create/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/page.js +1040 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/page.meta.js +19 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js +353 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.js +457 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.meta.js +16 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.js +697 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.meta.js +16 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/create/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/page.js +174 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/page.meta.js +18 -0
- package/dist/modules/staff/backend/staff/time-tracking/reports/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/settings/page.js +546 -0
- package/dist/modules/staff/backend/staff/time-tracking/settings/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/settings/page.meta.js +18 -0
- package/dist/modules/staff/backend/staff/time-tracking/settings/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/timesheet/GridView.js +710 -0
- package/dist/modules/staff/backend/staff/time-tracking/timesheet/GridView.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.js +646 -0
- package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.meta.js +18 -0
- package/dist/modules/staff/backend/staff/time-tracking/timesheet/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/page.js +4 -793
- package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/page.meta.js +2 -7
- package/dist/modules/staff/backend/staff/timesheets/page.meta.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js +5 -136
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.js +1 -7
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js +5 -445
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +3 -3
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.js +1 -7
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/create/page.js +4 -76
- package/dist/modules/staff/backend/staff/timesheets/projects/create/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/create/page.meta.js +1 -7
- package/dist/modules/staff/backend/staff/timesheets/projects/create/page.meta.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js +4 -613
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.meta.js +2 -17
- package/dist/modules/staff/backend/staff/timesheets/projects/page.meta.js.map +2 -2
- package/dist/modules/staff/ce.js +40 -0
- package/dist/modules/staff/ce.js.map +2 -2
- package/dist/modules/staff/cli.js +166 -1
- package/dist/modules/staff/cli.js.map +2 -2
- package/dist/modules/staff/commands/index.js +5 -0
- package/dist/modules/staff/commands/index.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-entries.js +569 -21
- package/dist/modules/staff/commands/timesheets-entries.js.map +3 -3
- package/dist/modules/staff/commands/timesheets-projects.js +450 -7
- package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-reports.js +1036 -0
- package/dist/modules/staff/commands/timesheets-reports.js.map +7 -0
- package/dist/modules/staff/commands/timesheets-tags.js +1015 -0
- package/dist/modules/staff/commands/timesheets-tags.js.map +7 -0
- package/dist/modules/staff/commands/timesheets-task-comments.js +438 -0
- package/dist/modules/staff/commands/timesheets-task-comments.js.map +7 -0
- package/dist/modules/staff/commands/timesheets-task-statuses.js +723 -0
- package/dist/modules/staff/commands/timesheets-task-statuses.js.map +7 -0
- package/dist/modules/staff/commands/timesheets-tasks.js +834 -0
- package/dist/modules/staff/commands/timesheets-tasks.js.map +7 -0
- package/dist/modules/staff/data/enrichers.js +426 -12
- package/dist/modules/staff/data/enrichers.js.map +2 -2
- package/dist/modules/staff/data/entities.js +552 -3
- package/dist/modules/staff/data/entities.js.map +2 -2
- package/dist/modules/staff/data/extensions.js +41 -0
- package/dist/modules/staff/data/extensions.js.map +7 -0
- package/dist/modules/staff/data/validators.js +254 -9
- package/dist/modules/staff/data/validators.js.map +2 -2
- package/dist/modules/staff/di.js +42 -1
- package/dist/modules/staff/di.js.map +2 -2
- package/dist/modules/staff/events.js +84 -6
- package/dist/modules/staff/events.js.map +2 -2
- package/dist/modules/staff/events.payloads.js +158 -0
- package/dist/modules/staff/events.payloads.js.map +7 -0
- package/dist/modules/staff/extension-points.js +261 -0
- package/dist/modules/staff/extension-points.js.map +7 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.js +138 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.js.map +7 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.meta.js +12 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.meta.js.map +7 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.js +133 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.js.map +7 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.meta.js +19 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.meta.js.map +7 -0
- package/dist/modules/staff/lib/crud.js +11 -1
- package/dist/modules/staff/lib/crud.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking/access.js +92 -0
- package/dist/modules/staff/lib/time-tracking/access.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/billability.js +39 -0
- package/dist/modules/staff/lib/time-tracking/billability.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/capacity.js +68 -0
- package/dist/modules/staff/lib/time-tracking/capacity.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/componentContracts.js +15 -0
- package/dist/modules/staff/lib/time-tracking/componentContracts.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/cost.js +82 -0
- package/dist/modules/staff/lib/time-tracking/cost.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/duration.js +55 -0
- package/dist/modules/staff/lib/time-tracking/duration.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/featureAccess.js +41 -0
- package/dist/modules/staff/lib/time-tracking/featureAccess.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/interval.js +72 -0
- package/dist/modules/staff/lib/time-tracking/interval.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/migrateProjectCodes.js +88 -0
- package/dist/modules/staff/lib/time-tracking/migrateProjectCodes.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/moneyVisibility.js +10 -0
- package/dist/modules/staff/lib/time-tracking/moneyVisibility.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/overlap.js +87 -0
- package/dist/modules/staff/lib/time-tracking/overlap.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/portalRecipients.js +27 -0
- package/dist/modules/staff/lib/time-tracking/portalRecipients.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/portalReports.js +16 -0
- package/dist/modules/staff/lib/time-tracking/portalReports.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/projectCode.js +135 -0
- package/dist/modules/staff/lib/time-tracking/projectCode.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/reapplyRounding.js +187 -0
- package/dist/modules/staff/lib/time-tracking/reapplyRounding.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/recalculationRunner.js +80 -0
- package/dist/modules/staff/lib/time-tracking/recalculationRunner.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/recalculations.js +56 -0
- package/dist/modules/staff/lib/time-tracking/recalculations.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/registries/invoke.js +63 -0
- package/dist/modules/staff/lib/time-tracking/registries/invoke.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/registries/registry.js +62 -0
- package/dist/modules/staff/lib/time-tracking/registries/registry.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/registries/scope.js +21 -0
- package/dist/modules/staff/lib/time-tracking/registries/scope.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/rollup.js +34 -0
- package/dist/modules/staff/lib/time-tracking/rollup.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/rounding.js +66 -0
- package/dist/modules/staff/lib/time-tracking/rounding.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/roundingImpact.js +39 -0
- package/dist/modules/staff/lib/time-tracking/roundingImpact.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/settingKeys.js +214 -0
- package/dist/modules/staff/lib/time-tracking/settingKeys.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/settings.js +87 -0
- package/dist/modules/staff/lib/time-tracking/settings.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/sqlInClause.js +9 -0
- package/dist/modules/staff/lib/time-tracking/sqlInClause.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/timeEntrySources.js +48 -0
- package/dist/modules/staff/lib/time-tracking/timeEntrySources.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js +283 -0
- package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/CustomerPicker.js +324 -0
- package/dist/modules/staff/lib/time-tracking-ui/CustomerPicker.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/DurationInput.js +121 -0
- package/dist/modules/staff/lib/time-tracking-ui/DurationInput.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/EntryDetailsFields.js +188 -0
- package/dist/modules/staff/lib/time-tracking-ui/EntryDetailsFields.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/EntryFilterBar.js +89 -0
- package/dist/modules/staff/lib/time-tracking-ui/EntryFilterBar.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js +855 -0
- package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js +360 -0
- package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/KanbanColumn.js +259 -0
- package/dist/modules/staff/lib/time-tracking-ui/KanbanColumn.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/NewTaskDialog.js +238 -0
- package/dist/modules/staff/lib/time-tracking-ui/NewTaskDialog.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/NoProjectAccess.js +130 -0
- package/dist/modules/staff/lib/time-tracking-ui/NoProjectAccess.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/PeriodSelector.js +98 -0
- package/dist/modules/staff/lib/time-tracking-ui/PeriodSelector.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/PhasePlaceholder.js +27 -0
- package/dist/modules/staff/lib/time-tracking-ui/PhasePlaceholder.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/ProjectCodeField.js +166 -0
- package/dist/modules/staff/lib/time-tracking-ui/ProjectCodeField.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/ProjectCurrencyField.js +295 -0
- package/dist/modules/staff/lib/time-tracking-ui/ProjectCurrencyField.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js +212 -0
- package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/ProjectTeamDrawer.js +729 -0
- package/dist/modules/staff/lib/time-tracking-ui/ProjectTeamDrawer.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/ReportSheet.js +217 -0
- package/dist/modules/staff/lib/time-tracking-ui/ReportSheet.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TagPicker.js +158 -0
- package/dist/modules/staff/lib/time-tracking-ui/TagPicker.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js +224 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js +93 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js +1196 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskListView.js +176 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskListView.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskPicker.js +307 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskPicker.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskQuickLog.js +284 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskQuickLog.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimeEntriesSummaryFooter.js +73 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimeEntriesSummaryFooter.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDialog.js +1499 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDialog.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDurationCell.js +95 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimeEntryDurationCell.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimesheetCalendar.js +188 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimesheetCalendar.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimesheetPeriodFooter.js +61 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimesheetPeriodFooter.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimesheetViewSwitch.js +45 -0
- package/dist/modules/staff/lib/time-tracking-ui/TimesheetViewSwitch.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js +176 -0
- package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js +82 -0
- package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/boardSummary.js +5 -0
- package/dist/modules/staff/lib/time-tracking-ui/boardSummary.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js +152 -0
- package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/projectTeamAssignment.js +92 -0
- package/dist/modules/staff/lib/time-tracking-ui/projectTeamAssignment.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js +111 -0
- package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/timeEntryDialogState.js +243 -0
- package/dist/modules/staff/lib/time-tracking-ui/timeEntryDialogState.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/timeEntryListData.js +151 -0
- package/dist/modules/staff/lib/time-tracking-ui/timeEntryListData.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js +105 -0
- package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/timesheetData.js +132 -0
- package/dist/modules/staff/lib/time-tracking-ui/timesheetData.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/timesheetPeriod.js +205 -0
- package/dist/modules/staff/lib/time-tracking-ui/timesheetPeriod.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/timesheetTargets.js +53 -0
- package/dist/modules/staff/lib/time-tracking-ui/timesheetTargets.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/useBoardFilters.js +77 -0
- package/dist/modules/staff/lib/time-tracking-ui/useBoardFilters.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/useTimesheetPreferences.js +151 -0
- package/dist/modules/staff/lib/time-tracking-ui/useTimesheetPreferences.js.map +7 -0
- package/dist/modules/staff/lib/timeTrackingSeeds.js +809 -0
- package/dist/modules/staff/lib/timeTrackingSeeds.js.map +7 -0
- package/dist/modules/staff/lib/timesheets/timeEntryCacheInvalidation.js +2 -3
- package/dist/modules/staff/lib/timesheets/timeEntryCacheInvalidation.js.map +2 -2
- package/dist/modules/staff/lib/timesheets/timeEntryDecoration.js +152 -0
- package/dist/modules/staff/lib/timesheets/timeEntryDecoration.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/budgetBurn.js +36 -0
- package/dist/modules/staff/lib/timesheets-projects/budgetBurn.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/budgetThreshold.js +66 -0
- package/dist/modules/staff/lib/timesheets-projects/budgetThreshold.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/budgetThresholdState.js +78 -0
- package/dist/modules/staff/lib/timesheets-projects/budgetThresholdState.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/computeProjectFinancials.js +81 -0
- package/dist/modules/staff/lib/timesheets-projects/computeProjectFinancials.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/reportSelection.js +44 -0
- package/dist/modules/staff/lib/timesheets-projects/reportSelection.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/AssignMembersDialog.js +169 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/AssignMembersDialog.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectBudgetCell.js +22 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectBudgetCell.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectCard.js +51 -1
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectCard.js.map +2 -2
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectsBulkActionsBar.js +70 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectsBulkActionsBar.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/buildReportSheet.js +63 -0
- package/dist/modules/staff/lib/timesheets-reports/buildReportSheet.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/loadReportData.js +170 -0
- package/dist/modules/staff/lib/timesheets-reports/loadReportData.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/pdf.js +205 -0
- package/dist/modules/staff/lib/timesheets-reports/pdf.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportApprovalPolicies.js +68 -0
- package/dist/modules/staff/lib/timesheets-reports/reportApprovalPolicies.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportConfigData.js +135 -0
- package/dist/modules/staff/lib/timesheets-reports/reportConfigData.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportConfigState.js +48 -0
- package/dist/modules/staff/lib/timesheets-reports/reportConfigState.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportExport.js +262 -0
- package/dist/modules/staff/lib/timesheets-reports/reportExport.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportExportFormats.js +34 -0
- package/dist/modules/staff/lib/timesheets-reports/reportExportFormats.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportGroupings.js +79 -0
- package/dist/modules/staff/lib/timesheets-reports/reportGroupings.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportLabels.js +11 -0
- package/dist/modules/staff/lib/timesheets-reports/reportLabels.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportReference.js +83 -0
- package/dist/modules/staff/lib/timesheets-reports/reportReference.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportRows.js +42 -0
- package/dist/modules/staff/lib/timesheets-reports/reportRows.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportSheetData.js +107 -0
- package/dist/modules/staff/lib/timesheets-reports/reportSheetData.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/reportTotals.js +289 -0
- package/dist/modules/staff/lib/timesheets-reports/reportTotals.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-reports/xlsx.js +145 -0
- package/dist/modules/staff/lib/timesheets-reports/xlsx.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-tasks/computeTaskRollups.js +116 -0
- package/dist/modules/staff/lib/timesheets-tasks/computeTaskRollups.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-tasks/defaultStatusTemplate.js +50 -0
- package/dist/modules/staff/lib/timesheets-tasks/defaultStatusTemplate.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-tasks/seedProjectStatuses.js +27 -0
- package/dist/modules/staff/lib/timesheets-tasks/seedProjectStatuses.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-tasks/statusPositions.js +65 -0
- package/dist/modules/staff/lib/timesheets-tasks/statusPositions.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-tasks/statusSlug.js +31 -0
- package/dist/modules/staff/lib/timesheets-tasks/statusSlug.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-tasks/taskHierarchy.js +31 -0
- package/dist/modules/staff/lib/timesheets-tasks/taskHierarchy.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-tasks/taskHoursTotals.js +17 -0
- package/dist/modules/staff/lib/timesheets-tasks/taskHoursTotals.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-tasks/taskReference.js +51 -0
- package/dist/modules/staff/lib/timesheets-tasks/taskReference.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/CreateProjectDialog.js +11 -4
- package/dist/modules/staff/lib/timesheets-ui/CreateProjectDialog.js.map +2 -2
- package/dist/modules/staff/lib/timesheets-ui/ListView.js +369 -111
- package/dist/modules/staff/lib/timesheets-ui/ListView.js.map +2 -2
- package/dist/modules/staff/lib/timesheets-ui/TimerBar.js +47 -2
- package/dist/modules/staff/lib/timesheets-ui/TimerBar.js.map +2 -2
- package/dist/modules/staff/migrations/Migration20260813073131_staff.js +79 -0
- package/dist/modules/staff/migrations/Migration20260813073131_staff.js.map +7 -0
- package/dist/modules/staff/migrations/Migration20260824143357_staff.js +15 -0
- package/dist/modules/staff/migrations/Migration20260824143357_staff.js.map +7 -0
- package/dist/modules/staff/notifications.client.js +16 -0
- package/dist/modules/staff/notifications.client.js.map +7 -0
- package/dist/modules/staff/notifications.handlers.js +80 -0
- package/dist/modules/staff/notifications.handlers.js.map +7 -0
- package/dist/modules/staff/notifications.js +168 -0
- package/dist/modules/staff/notifications.js.map +2 -2
- package/dist/modules/staff/search.js +159 -1
- package/dist/modules/staff/search.js.map +2 -2
- package/dist/modules/staff/setup.js +20 -1
- package/dist/modules/staff/setup.js.map +2 -2
- package/dist/modules/staff/subscribers/time-project-access-requested-notification.js +68 -0
- package/dist/modules/staff/subscribers/time-project-access-requested-notification.js.map +7 -0
- package/dist/modules/staff/subscribers/time-project-budget-threshold-notification.js +149 -0
- package/dist/modules/staff/subscribers/time-project-budget-threshold-notification.js.map +7 -0
- package/dist/modules/staff/subscribers/time-report-approved-notification.js +78 -0
- package/dist/modules/staff/subscribers/time-report-approved-notification.js.map +7 -0
- package/dist/modules/staff/subscribers/time-report-portal-broadcast.js +78 -0
- package/dist/modules/staff/subscribers/time-report-portal-broadcast.js.map +7 -0
- package/dist/modules/staff/translations.js +4 -1
- package/dist/modules/staff/translations.js.map +2 -2
- package/dist/modules/staff/widgets/components.js +7 -0
- package/dist/modules/staff/widgets/components.js.map +7 -0
- package/dist/modules/staff/widgets/injection/timer-sidebar-indicator/widget.js +5 -4
- package/dist/modules/staff/widgets/injection/timer-sidebar-indicator/widget.js.map +2 -2
- package/dist/modules/staff/widgets/notifications/TimeProjectAccessRequestedRenderer.js +135 -0
- package/dist/modules/staff/widgets/notifications/TimeProjectAccessRequestedRenderer.js.map +7 -0
- package/dist/modules/staff/widgets/notifications/index.js +5 -0
- package/dist/modules/staff/widgets/notifications/index.js.map +7 -0
- package/dist/modules/staff/workers/timesheets-reapply-rounding.js +43 -0
- package/dist/modules/staff/workers/timesheets-reapply-rounding.js.map +7 -0
- package/generated/entities/staff_time_entry/index.ts +7 -0
- package/generated/entities/staff_time_entry_tag/index.ts +6 -0
- package/generated/entities/staff_time_project/index.ts +8 -0
- package/generated/entities/staff_time_report/index.ts +27 -0
- package/generated/entities/staff_time_report_entry/index.ts +12 -0
- package/generated/entities/staff_time_report_event/index.ts +9 -0
- package/generated/entities/staff_time_report_project/index.ts +6 -0
- package/generated/entities/staff_time_tag/index.ts +9 -0
- package/generated/entities/staff_time_task/index.ts +17 -0
- package/generated/entities/staff_time_task_comment/index.ts +9 -0
- package/generated/entities/staff_time_task_status/index.ts +13 -0
- package/generated/entities/staff_time_task_tag/index.ts +6 -0
- package/generated/entities.ids.generated.ts +11 -1
- package/generated/entity-fields-registry.ts +149 -0
- package/package.json +7 -7
- package/src/helpers/integration/timesheetFixtures.ts +31 -1
- package/src/modules/auth/README.md +1 -1
- package/src/modules/auth/cli.ts +35 -1
- package/src/modules/auth/i18n/de.json +7 -0
- package/src/modules/auth/i18n/en.json +7 -0
- package/src/modules/auth/i18n/es.json +7 -0
- package/src/modules/auth/i18n/ko.json +7 -0
- package/src/modules/auth/i18n/pl.json +7 -0
- package/src/modules/auth/lib/backendChrome.tsx +1 -0
- package/src/modules/customer_accounts/lib/customerRoleAcls.ts +79 -0
- package/src/modules/customer_accounts/setup.ts +1 -45
- package/src/modules/data_sync/AGENTS.md +34 -0
- package/src/modules/data_sync/api/options.ts +2 -0
- package/src/modules/data_sync/backend/data-sync/page.tsx +82 -33
- package/src/modules/data_sync/i18n/de.json +1 -0
- package/src/modules/data_sync/i18n/en.json +1 -0
- package/src/modules/data_sync/i18n/es.json +1 -0
- package/src/modules/data_sync/i18n/ko.json +1 -0
- package/src/modules/data_sync/i18n/pl.json +1 -0
- package/src/modules/data_sync/lib/adapter.ts +45 -0
- package/src/modules/data_sync/lib/start-controls.ts +89 -0
- package/src/modules/staff/AGENTS.md +769 -1
- package/src/modules/staff/acl.ts +9 -0
- package/src/modules/staff/ai-agents.ts +189 -0
- package/src/modules/staff/ai-tools/time-tracking-pack.ts +494 -0
- package/src/modules/staff/ai-tools/types.ts +82 -0
- package/src/modules/staff/ai-tools.ts +13 -0
- package/src/modules/staff/analytics.ts +113 -0
- package/src/modules/staff/api/guards.ts +85 -3
- package/src/modules/staff/api/leave-requests/accept/route.ts +0 -2
- package/src/modules/staff/api/leave-requests/reject/route.ts +0 -2
- package/src/modules/staff/api/portal/time-reports/[id]/route.ts +182 -0
- package/src/modules/staff/api/portal/time-reports/route.ts +270 -0
- package/src/modules/staff/api/team-members/self/route.ts +0 -2
- package/src/modules/staff/api/team-members/tags/assign/route.ts +0 -2
- package/src/modules/staff/api/team-members/tags/unassign/route.ts +0 -2
- package/src/modules/staff/api/timesheets/_shared/withTimesheetInterceptors.ts +292 -0
- package/src/modules/staff/api/timesheets/access-requests/route.ts +299 -0
- package/src/modules/staff/api/timesheets/my-projects/[projectId]/route.ts +15 -7
- package/src/modules/staff/api/timesheets/my-projects/route.ts +14 -1
- package/src/modules/staff/api/timesheets/my-work/myWorkAggregate.ts +90 -0
- package/src/modules/staff/api/timesheets/my-work/route.ts +475 -0
- package/src/modules/staff/api/timesheets/projects/kpis/route.ts +15 -2
- package/src/modules/staff/api/timesheets/reports/[id]/close/route.ts +203 -0
- package/src/modules/staff/api/timesheets/reports/[id]/export/route.ts +315 -0
- package/src/modules/staff/api/timesheets/reports/[id]/sheet/route.ts +220 -0
- package/src/modules/staff/api/timesheets/reports/[id]/unlock/route.ts +208 -0
- package/src/modules/staff/api/timesheets/reports/preview/route.ts +449 -0
- package/src/modules/staff/api/timesheets/reports/route.ts +386 -0
- package/src/modules/staff/api/timesheets/reports/shared.ts +121 -0
- package/src/modules/staff/api/timesheets/settings/reapply-rounding/route.ts +205 -0
- package/src/modules/staff/api/timesheets/settings/rounding-impact/route.ts +226 -0
- package/src/modules/staff/api/timesheets/settings/route.ts +242 -0
- package/src/modules/staff/api/timesheets/tags/access.ts +134 -0
- package/src/modules/staff/api/timesheets/tags/entry-assignments/route.ts +290 -0
- package/src/modules/staff/api/timesheets/tags/route.ts +177 -0
- package/src/modules/staff/api/timesheets/tags/task-assignments/route.ts +294 -0
- package/src/modules/staff/api/timesheets/task-statuses/route.ts +232 -0
- package/src/modules/staff/api/timesheets/tasks/[id]/comments/route.ts +532 -0
- package/src/modules/staff/api/timesheets/tasks/[id]/status/route.ts +271 -0
- package/src/modules/staff/api/timesheets/tasks/route.ts +443 -0
- package/src/modules/staff/api/timesheets/time-entries/[id]/duplicate/route.ts +306 -0
- package/src/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.ts +32 -10
- package/src/modules/staff/api/timesheets/time-entries/[id]/segments/route.ts +32 -17
- package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +27 -6
- package/src/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.ts +36 -6
- package/src/modules/staff/api/timesheets/time-entries/bulk/route.ts +331 -34
- package/src/modules/staff/api/timesheets/time-entries/copy-day/route.ts +533 -0
- package/src/modules/staff/api/timesheets/time-entries/overlaps/route.ts +457 -0
- package/src/modules/staff/api/timesheets/time-entries/route.ts +378 -24
- package/src/modules/staff/api/timesheets/time-entries/start-timer/route.ts +31 -9
- package/src/modules/staff/api/timesheets/time-projects/[id]/change-currency/route.ts +246 -0
- package/src/modules/staff/api/timesheets/time-projects/[id]/employees/route.ts +62 -2
- package/src/modules/staff/api/timesheets/time-projects/route.ts +397 -22
- package/src/modules/staff/backend/staff/time-tracking/board/page.meta.ts +14 -0
- package/src/modules/staff/backend/staff/time-tracking/board/page.tsx +151 -0
- package/src/modules/staff/backend/staff/time-tracking/entries/page.meta.ts +14 -0
- package/src/modules/staff/backend/staff/time-tracking/entries/page.tsx +1229 -0
- package/src/modules/staff/backend/staff/time-tracking/page.meta.ts +11 -0
- package/src/modules/staff/backend/staff/time-tracking/page.tsx +823 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.meta.ts +12 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/board/page.tsx +81 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.meta.ts +12 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.tsx +275 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.meta.ts +12 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +1420 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/create/page.meta.ts +12 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/create/page.tsx +109 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/page.meta.ts +15 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/page.tsx +1254 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.ts +466 -0
- package/src/modules/staff/backend/staff/time-tracking/reports/[id]/page.meta.ts +12 -0
- package/src/modules/staff/backend/staff/time-tracking/reports/[id]/page.tsx +632 -0
- package/src/modules/staff/backend/staff/time-tracking/reports/create/page.meta.ts +12 -0
- package/src/modules/staff/backend/staff/time-tracking/reports/create/page.tsx +867 -0
- package/src/modules/staff/backend/staff/time-tracking/reports/page.meta.ts +14 -0
- package/src/modules/staff/backend/staff/time-tracking/reports/page.tsx +246 -0
- package/src/modules/staff/backend/staff/time-tracking/settings/page.meta.ts +14 -0
- package/src/modules/staff/backend/staff/time-tracking/settings/page.tsx +701 -0
- package/src/modules/staff/backend/staff/time-tracking/timesheet/GridView.tsx +953 -0
- package/src/modules/staff/backend/staff/time-tracking/timesheet/page.meta.ts +14 -0
- package/src/modules/staff/backend/staff/time-tracking/timesheet/page.tsx +800 -0
- package/src/modules/staff/backend/staff/timesheets/page.meta.ts +6 -6
- package/src/modules/staff/backend/staff/timesheets/page.tsx +12 -1010
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.ts +0 -6
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.tsx +4 -158
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.ts +0 -6
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +4 -609
- package/src/modules/staff/backend/staff/timesheets/projects/create/page.meta.ts +0 -6
- package/src/modules/staff/backend/staff/timesheets/projects/create/page.tsx +3 -89
- package/src/modules/staff/backend/staff/timesheets/projects/page.meta.ts +2 -19
- package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +3 -778
- package/src/modules/staff/ce.ts +63 -0
- package/src/modules/staff/cli.ts +207 -1
- package/src/modules/staff/commands/index.ts +5 -0
- package/src/modules/staff/commands/timesheets-entries.ts +1006 -28
- package/src/modules/staff/commands/timesheets-projects.ts +593 -7
- package/src/modules/staff/commands/timesheets-reports.ts +1329 -0
- package/src/modules/staff/commands/timesheets-tags.ts +1315 -0
- package/src/modules/staff/commands/timesheets-task-comments.ts +583 -0
- package/src/modules/staff/commands/timesheets-task-statuses.ts +889 -0
- package/src/modules/staff/commands/timesheets-tasks.ts +1121 -0
- package/src/modules/staff/data/enrichers.ts +675 -10
- package/src/modules/staff/data/entities.ts +494 -2
- package/src/modules/staff/data/extensions.ts +68 -0
- package/src/modules/staff/data/validators.ts +348 -3
- package/src/modules/staff/di.ts +96 -0
- package/src/modules/staff/events.payloads.ts +268 -0
- package/src/modules/staff/events.ts +87 -5
- package/src/modules/staff/extension-points.ts +308 -0
- package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.meta.ts +10 -0
- package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.tsx +225 -0
- package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/page.meta.ts +17 -0
- package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/page.tsx +182 -0
- package/src/modules/staff/i18n/de.json +899 -0
- package/src/modules/staff/i18n/en.json +899 -0
- package/src/modules/staff/i18n/es.json +899 -0
- package/src/modules/staff/i18n/ko.json +899 -0
- package/src/modules/staff/i18n/pl.json +899 -0
- package/src/modules/staff/lib/crud.ts +14 -3
- package/src/modules/staff/lib/time-tracking/access.ts +155 -0
- package/src/modules/staff/lib/time-tracking/billability.ts +68 -0
- package/src/modules/staff/lib/time-tracking/capacity.ts +124 -0
- package/src/modules/staff/lib/time-tracking/componentContracts.ts +26 -0
- package/src/modules/staff/lib/time-tracking/cost.ts +144 -0
- package/src/modules/staff/lib/time-tracking/duration.ts +68 -0
- package/src/modules/staff/lib/time-tracking/featureAccess.ts +115 -0
- package/src/modules/staff/lib/time-tracking/interval.ts +90 -0
- package/src/modules/staff/lib/time-tracking/migrateProjectCodes.ts +161 -0
- package/src/modules/staff/lib/time-tracking/moneyVisibility.ts +37 -0
- package/src/modules/staff/lib/time-tracking/overlap.ts +159 -0
- package/src/modules/staff/lib/time-tracking/portalRecipients.ts +76 -0
- package/src/modules/staff/lib/time-tracking/portalReports.ts +31 -0
- package/src/modules/staff/lib/time-tracking/projectCode.ts +221 -0
- package/src/modules/staff/lib/time-tracking/reapplyRounding.ts +313 -0
- package/src/modules/staff/lib/time-tracking/recalculationRunner.ts +118 -0
- package/src/modules/staff/lib/time-tracking/recalculations.ts +135 -0
- package/src/modules/staff/lib/time-tracking/registries/invoke.ts +122 -0
- package/src/modules/staff/lib/time-tracking/registries/registry.ts +124 -0
- package/src/modules/staff/lib/time-tracking/registries/scope.ts +56 -0
- package/src/modules/staff/lib/time-tracking/rollup.ts +59 -0
- package/src/modules/staff/lib/time-tracking/rounding.ts +126 -0
- package/src/modules/staff/lib/time-tracking/roundingImpact.ts +75 -0
- package/src/modules/staff/lib/time-tracking/settingKeys.ts +274 -0
- package/src/modules/staff/lib/time-tracking/settings.ts +168 -0
- package/src/modules/staff/lib/time-tracking/sqlInClause.ts +22 -0
- package/src/modules/staff/lib/time-tracking/timeEntrySources.ts +85 -0
- package/src/modules/staff/lib/time-tracking-ui/BoardFilterChips.tsx +360 -0
- package/src/modules/staff/lib/time-tracking-ui/CustomerPicker.tsx +427 -0
- package/src/modules/staff/lib/time-tracking-ui/DurationInput.tsx +192 -0
- package/src/modules/staff/lib/time-tracking-ui/EntryDetailsFields.tsx +224 -0
- package/src/modules/staff/lib/time-tracking-ui/EntryFilterBar.tsx +144 -0
- package/src/modules/staff/lib/time-tracking-ui/KanbanBoard.tsx +1065 -0
- package/src/modules/staff/lib/time-tracking-ui/KanbanCard.tsx +435 -0
- package/src/modules/staff/lib/time-tracking-ui/KanbanColumn.tsx +316 -0
- package/src/modules/staff/lib/time-tracking-ui/NewTaskDialog.tsx +291 -0
- package/src/modules/staff/lib/time-tracking-ui/NoProjectAccess.tsx +162 -0
- package/src/modules/staff/lib/time-tracking-ui/PeriodSelector.tsx +149 -0
- package/src/modules/staff/lib/time-tracking-ui/PhasePlaceholder.tsx +31 -0
- package/src/modules/staff/lib/time-tracking-ui/ProjectCodeField.tsx +230 -0
- package/src/modules/staff/lib/time-tracking-ui/ProjectCurrencyField.tsx +432 -0
- package/src/modules/staff/lib/time-tracking-ui/ProjectFormSections.tsx +323 -0
- package/src/modules/staff/lib/time-tracking-ui/ProjectTeamDrawer.tsx +930 -0
- package/src/modules/staff/lib/time-tracking-ui/ReportSheet.tsx +357 -0
- package/src/modules/staff/lib/time-tracking-ui/TagPicker.tsx +195 -0
- package/src/modules/staff/lib/time-tracking-ui/TaskBoardScreen.tsx +243 -0
- package/src/modules/staff/lib/time-tracking-ui/TaskCommentThread.tsx +137 -0
- package/src/modules/staff/lib/time-tracking-ui/TaskDrawer.tsx +1405 -0
- package/src/modules/staff/lib/time-tracking-ui/TaskListView.tsx +260 -0
- package/src/modules/staff/lib/time-tracking-ui/TaskPicker.tsx +435 -0
- package/src/modules/staff/lib/time-tracking-ui/TaskQuickLog.tsx +296 -0
- package/src/modules/staff/lib/time-tracking-ui/TimeEntriesSummaryFooter.tsx +97 -0
- package/src/modules/staff/lib/time-tracking-ui/TimeEntryDialog.tsx +1929 -0
- package/src/modules/staff/lib/time-tracking-ui/TimeEntryDurationCell.tsx +126 -0
- package/src/modules/staff/lib/time-tracking-ui/TimesheetCalendar.tsx +265 -0
- package/src/modules/staff/lib/time-tracking-ui/TimesheetPeriodFooter.tsx +78 -0
- package/src/modules/staff/lib/time-tracking-ui/TimesheetViewSwitch.tsx +70 -0
- package/src/modules/staff/lib/time-tracking-ui/boardDirectory.ts +231 -0
- package/src/modules/staff/lib/time-tracking-ui/boardFilters.ts +128 -0
- package/src/modules/staff/lib/time-tracking-ui/boardSummary.ts +20 -0
- package/src/modules/staff/lib/time-tracking-ui/kanbanBoardData.ts +228 -0
- package/src/modules/staff/lib/time-tracking-ui/projectTeamAssignment.ts +143 -0
- package/src/modules/staff/lib/time-tracking-ui/taskDrawerData.ts +194 -0
- package/src/modules/staff/lib/time-tracking-ui/timeEntryDialogState.ts +400 -0
- package/src/modules/staff/lib/time-tracking-ui/timeEntryListData.ts +271 -0
- package/src/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.ts +168 -0
- package/src/modules/staff/lib/time-tracking-ui/timesheetData.ts +225 -0
- package/src/modules/staff/lib/time-tracking-ui/timesheetPeriod.ts +278 -0
- package/src/modules/staff/lib/time-tracking-ui/timesheetTargets.ts +93 -0
- package/src/modules/staff/lib/time-tracking-ui/useBoardFilters.ts +107 -0
- package/src/modules/staff/lib/time-tracking-ui/useTimesheetPreferences.ts +245 -0
- package/src/modules/staff/lib/timeTrackingSeeds.ts +1037 -0
- package/src/modules/staff/lib/timesheets/timeEntryCacheInvalidation.ts +11 -10
- package/src/modules/staff/lib/timesheets/timeEntryDecoration.ts +256 -0
- package/src/modules/staff/lib/timesheets-projects/budgetBurn.ts +60 -0
- package/src/modules/staff/lib/timesheets-projects/budgetThreshold.ts +135 -0
- package/src/modules/staff/lib/timesheets-projects/budgetThresholdState.ts +137 -0
- package/src/modules/staff/lib/timesheets-projects/computeProjectFinancials.ts +142 -0
- package/src/modules/staff/lib/timesheets-projects/reportSelection.ts +82 -0
- package/src/modules/staff/lib/timesheets-projects-ui/AssignMembersDialog.tsx +237 -0
- package/src/modules/staff/lib/timesheets-projects-ui/ProjectBudgetCell.tsx +33 -0
- package/src/modules/staff/lib/timesheets-projects-ui/ProjectCard.tsx +56 -1
- package/src/modules/staff/lib/timesheets-projects-ui/ProjectsBulkActionsBar.tsx +90 -0
- package/src/modules/staff/lib/timesheets-reports/buildReportSheet.ts +125 -0
- package/src/modules/staff/lib/timesheets-reports/loadReportData.ts +251 -0
- package/src/modules/staff/lib/timesheets-reports/pdf.ts +263 -0
- package/src/modules/staff/lib/timesheets-reports/reportApprovalPolicies.ts +137 -0
- package/src/modules/staff/lib/timesheets-reports/reportConfigData.ts +247 -0
- package/src/modules/staff/lib/timesheets-reports/reportConfigState.ts +89 -0
- package/src/modules/staff/lib/timesheets-reports/reportExport.ts +373 -0
- package/src/modules/staff/lib/timesheets-reports/reportExportFormats.ts +71 -0
- package/src/modules/staff/lib/timesheets-reports/reportGroupings.ts +153 -0
- package/src/modules/staff/lib/timesheets-reports/reportLabels.ts +23 -0
- package/src/modules/staff/lib/timesheets-reports/reportReference.ts +146 -0
- package/src/modules/staff/lib/timesheets-reports/reportRows.ts +89 -0
- package/src/modules/staff/lib/timesheets-reports/reportSheetData.ts +196 -0
- package/src/modules/staff/lib/timesheets-reports/reportTotals.ts +544 -0
- package/src/modules/staff/lib/timesheets-reports/xlsx.ts +207 -0
- package/src/modules/staff/lib/timesheets-tasks/computeTaskRollups.ts +238 -0
- package/src/modules/staff/lib/timesheets-tasks/defaultStatusTemplate.ts +90 -0
- package/src/modules/staff/lib/timesheets-tasks/seedProjectStatuses.ts +43 -0
- package/src/modules/staff/lib/timesheets-tasks/statusPositions.ts +132 -0
- package/src/modules/staff/lib/timesheets-tasks/statusSlug.ts +43 -0
- package/src/modules/staff/lib/timesheets-tasks/taskHierarchy.ts +99 -0
- package/src/modules/staff/lib/timesheets-tasks/taskHoursTotals.ts +42 -0
- package/src/modules/staff/lib/timesheets-tasks/taskReference.ts +108 -0
- package/src/modules/staff/lib/timesheets-ui/CreateProjectDialog.tsx +18 -4
- package/src/modules/staff/lib/timesheets-ui/ListView.tsx +504 -149
- package/src/modules/staff/lib/timesheets-ui/TimerBar.tsx +50 -2
- package/src/modules/staff/migrations/.snapshot-open-mercato.json +3244 -228
- package/src/modules/staff/migrations/Migration20260813073131_staff.ts +94 -0
- package/src/modules/staff/migrations/Migration20260824143357_staff.ts +17 -0
- package/src/modules/staff/notifications.client.ts +16 -0
- package/src/modules/staff/notifications.handlers.ts +88 -0
- package/src/modules/staff/notifications.ts +163 -0
- package/src/modules/staff/search.ts +191 -1
- package/src/modules/staff/setup.ts +22 -0
- package/src/modules/staff/subscribers/time-project-access-requested-notification.ts +95 -0
- package/src/modules/staff/subscribers/time-project-budget-threshold-notification.ts +226 -0
- package/src/modules/staff/subscribers/time-report-approved-notification.ts +116 -0
- package/src/modules/staff/subscribers/time-report-portal-broadcast.ts +120 -0
- package/src/modules/staff/translations.ts +17 -0
- package/src/modules/staff/widgets/components.ts +34 -0
- package/src/modules/staff/widgets/injection/timer-sidebar-indicator/widget.tsx +6 -5
- package/src/modules/staff/widgets/notifications/TimeProjectAccessRequestedRenderer.tsx +138 -0
- package/src/modules/staff/widgets/notifications/index.ts +1 -0
- package/src/modules/staff/workers/timesheets-reapply-rounding.ts +59 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/projectFormConfig.js +0 -123
- package/dist/modules/staff/backend/staff/timesheets/projects/projectFormConfig.js.map +0 -7
- package/src/modules/staff/backend/staff/timesheets/projects/projectFormConfig.ts +0 -138
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/staff/commands/timesheets-reports.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Customer report commands \u2014 screens 13, 14 and 15.\n *\n * A report is the one artefact in this module a client can dispute, so the rules\n * it enforces are financial rather than cosmetic:\n *\n * 1. **One customer, one currency (risk R2).** Every selected project must carry\n * the report's `customerId` and they must all agree on a currency code. A\n * mismatch is refused with the offending project names rather than silently\n * averaging two currencies into one number.\n * 2. **The reference is allocated once and never reused** \u2014 see\n * `lib/timesheets-reports/reportReference.ts`. It is printed on a PDF the\n * client keeps.\n * 3. **A closed report is immutable.** Editing or deleting one is refused with\n * `409 report_closed`; the way back is the unlock command, which is gated on\n * its own feature (`staff.timesheets.reports.unlock`) precisely so \"who may\n * restate billed time\" is answerable without inventing an admin role.\n *\n * Money is never computed here. `lib/timesheets-reports/reportTotals.ts` owns\n * D-7 (round at the entry, then sum upward) and the close command below feeds\n * its per-entry results straight into the freeze records.\n */\n\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { CommandHandler, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { buildChanges, emitCrudSideEffects, emitCrudUndoSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport type { CrudEventsConfig, CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport type { ModuleConfigService } from '@open-mercato/core/modules/configs/lib/module-config-service'\nimport {\n StaffTimeEntry,\n StaffTimeProject,\n StaffTimeReport,\n StaffTimeReportEntry,\n StaffTimeReportEvent,\n StaffTimeReportProject,\n} from '../data/entities'\nimport {\n staffTimeReportCloseSchema,\n staffTimeReportCreateSchema,\n staffTimeReportUnlockSchema,\n staffTimeReportUpdateSchema,\n type StaffTimeReportCloseInput,\n type StaffTimeReportCreateInput,\n type StaffTimeReportUnlockInput,\n type StaffTimeReportUpdateInput,\n} from '../data/validators'\nimport { readTimeTrackingSettings } from '../lib/time-tracking/settings'\nimport {\n allocateReportReference,\n highestReportSequenceNumber,\n isReportReferenceConflict,\n reportReferencePrefix,\n reportReferenceYear,\n withReportReferenceRetry,\n} from '../lib/timesheets-reports/reportReference'\nimport { loadReportData } from '../lib/timesheets-reports/loadReportData'\nimport { reportSheetLabels } from '../lib/timesheets-reports/reportLabels'\nimport {\n computeReportTotals,\n resolveEntryValues,\n resolveReportCurrency,\n selectIncludedEntries,\n} from '../lib/timesheets-reports/reportTotals'\nimport { emitStaffEvent } from '../events'\nimport {\n applyScopeToWhere,\n commandActorScope,\n commandInputScope,\n ensureOrganizationScope,\n ensureTenantScope,\n extractUndoPayload,\n scopedStaffSnapshotWhere,\n staffSnapshotScopeFromContext,\n staffSnapshotScopeFromSnapshot,\n type StaffCommandScope,\n type StaffSnapshotScope,\n} from './shared'\n\nexport const staffTimeReportCommandIds = {\n create: 'staff.timesheets.reports.create',\n update: 'staff.timesheets.reports.update',\n delete: 'staff.timesheets.reports.delete',\n close: 'staff.timesheets.reports.close',\n unlock: 'staff.timesheets.reports.unlock',\n} as const\n\nexport const STAFF_TIME_REPORT_RESOURCE_KIND = 'staff.timesheets.time_report'\n\nexport const REPORT_CURRENCY_CONFLICT_CODE = 'report_currency_conflict'\nexport const REPORT_PROJECT_CUSTOMER_MISMATCH_CODE = 'report_project_customer_mismatch'\nexport const REPORT_PROJECT_NOT_FOUND_CODE = 'report_project_not_found'\nexport const REPORT_CLOSED_CODE = 'report_closed'\nexport const REPORT_NOT_CLOSED_CODE = 'report_not_closed'\nexport const REPORT_REFERENCE_CONFLICT_CODE = 'report_reference_conflict'\nexport const REPORT_EMPTY_CODE = 'report_empty'\n\nconst logger = createLogger('staff').child({ component: 'commands/timesheets-reports' })\n\nconst reportCrudIndexer: CrudIndexerConfig<StaffTimeReport> = {\n entityType: 'staff:staff_time_report',\n}\n\nconst reportCrudEvents: CrudEventsConfig<StaffTimeReport> = {\n module: 'staff',\n entity: 'timesheets.time_report',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\ntype Translate = (key: string, fallback: string) => string\n\nexport type ReportSnapshot = {\n id: string\n tenantId: string\n organizationId: string\n customerId: string\n customerSnapshot: Record<string, unknown> | null\n reference: string\n title: string\n periodKind: string\n periodFrom: string | null\n periodTo: string | null\n currencyCode: string\n grouping: string\n nonbillableMode: string\n includeAlreadyReported: boolean\n showRates: boolean\n roundingUnitMinutes: number\n roundingDirection: string\n status: string\n totalBillableMinutes: number | null\n totalNonbillableMinutes: number | null\n totalAmount: string | null\n closedAt: string | null\n closedByUserId: string | null\n timeProjectIds: string[]\n deletedAt: string | null\n}\n\ntype ReportUndoPayload = {\n before?: ReportSnapshot | null\n after?: ReportSnapshot | null\n}\n\nconst DIFFED_FIELDS = [\n 'title',\n 'periodKind',\n 'periodFrom',\n 'periodTo',\n 'currencyCode',\n 'grouping',\n 'nonbillableMode',\n 'includeAlreadyReported',\n 'showRates',\n 'status',\n 'totalBillableMinutes',\n 'totalNonbillableMinutes',\n 'totalAmount',\n] as const\n\nfunction toIsoDate(value: Date | string | null | undefined): string | null {\n if (!value) return null\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) return null\n const year = value.getFullYear()\n const month = String(value.getMonth() + 1).padStart(2, '0')\n const day = String(value.getDate()).padStart(2, '0')\n return `${year}-${month}-${day}`\n }\n const text = String(value)\n return text.length >= 10 ? text.slice(0, 10) : text\n}\n\nfunction snapshotScopeWhere(scope?: StaffSnapshotScope | null): { tenantId?: string; organizationId?: string } {\n const where: { tenantId?: string; organizationId?: string } = {}\n if (scope?.tenantId) where.tenantId = scope.tenantId\n if (scope?.organizationId) where.organizationId = scope.organizationId\n return where\n}\n\nexport async function loadReportProjectIds(\n em: EntityManager,\n reportId: string,\n scope?: StaffSnapshotScope | null,\n): Promise<string[]> {\n const rows = await em.find(StaffTimeReportProject, { reportId, ...snapshotScopeWhere(scope) })\n return rows.map((row) => row.timeProjectId)\n}\n\nfunction toSnapshot(report: StaffTimeReport, timeProjectIds: string[]): ReportSnapshot {\n return {\n id: report.id,\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n customerId: report.customerId,\n customerSnapshot: report.customerSnapshot ?? null,\n reference: report.reference,\n title: report.title,\n periodKind: report.periodKind,\n periodFrom: toIsoDate(report.periodFrom),\n periodTo: toIsoDate(report.periodTo),\n currencyCode: report.currencyCode,\n grouping: report.grouping,\n nonbillableMode: report.nonbillableMode,\n includeAlreadyReported: report.includeAlreadyReported ?? false,\n showRates: report.showRates ?? true,\n roundingUnitMinutes: report.roundingUnitMinutes ?? 0,\n roundingDirection: report.roundingDirection ?? 'up',\n status: report.status,\n totalBillableMinutes: report.totalBillableMinutes ?? null,\n totalNonbillableMinutes: report.totalNonbillableMinutes ?? null,\n totalAmount: report.totalAmount ?? null,\n closedAt: report.closedAt ? report.closedAt.toISOString() : null,\n closedByUserId: report.closedByUserId ?? null,\n timeProjectIds,\n deletedAt: report.deletedAt ? report.deletedAt.toISOString() : null,\n }\n}\n\nexport async function loadReportSnapshot(\n em: EntityManager,\n id: string,\n scope?: StaffSnapshotScope | null,\n): Promise<ReportSnapshot | null> {\n const report = await em.findOne(StaffTimeReport, scopedStaffSnapshotWhere(id, scope))\n if (!report) return null\n const projectIds = await loadReportProjectIds(em, report.id, scope)\n return toSnapshot(report, projectIds)\n}\n\nexport function reportNotFoundError(translate: Translate): CrudHttpError {\n return new CrudHttpError(404, {\n error: translate('staff.time_tracking.reports.errors.notFound', 'Report not found or not accessible.'),\n })\n}\n\nexport function reportClosedError(translate: Translate, reference: string | null): CrudHttpError {\n return new CrudHttpError(409, {\n code: REPORT_CLOSED_CODE,\n error: translate(\n 'staff.time_tracking.reports.errors.closed',\n 'This report is closed. Unlock it before changing anything.',\n ),\n reference: reference ?? null,\n })\n}\n\nfunction projectsRequiredError(translate: Translate): CrudHttpError {\n const message = translate(\n 'staff.time_tracking.reports.errors.projectsRequired',\n 'Pick at least one project for this report.',\n )\n return new CrudHttpError(422, { error: message, fieldErrors: { timeProjectIds: message } })\n}\n\nfunction projectNotFoundError(translate: Translate, missingIds: string[]): CrudHttpError {\n const message = translate(\n 'staff.time_tracking.reports.errors.projectNotFound',\n 'Some of the selected projects are not available.',\n )\n return new CrudHttpError(422, {\n code: REPORT_PROJECT_NOT_FOUND_CODE,\n error: message,\n fieldErrors: { timeProjectIds: message },\n missingProjectIds: missingIds,\n })\n}\n\nfunction customerMismatchError(translate: Translate, offenders: string[]): CrudHttpError {\n const message = translate(\n 'staff.time_tracking.reports.errors.customerMismatch',\n 'A report always covers one customer. These projects belong to someone else: {projects}.',\n ).replace('{projects}', offenders.join(', '))\n return new CrudHttpError(422, {\n code: REPORT_PROJECT_CUSTOMER_MISMATCH_CODE,\n error: message,\n fieldErrors: { timeProjectIds: message },\n offenders,\n })\n}\n\n/**\n * Risk R2 refused at the cheapest point. The body names both the currencies and\n * the projects carrying them, because \"pick one currency\" is unactionable\n * without knowing which project is the odd one out.\n */\nexport function currencyConflictError(\n translate: Translate,\n currencies: string[],\n offenders: Array<{ id: string; name: string; currencyCode: string | null }>,\n): CrudHttpError {\n const message = translate(\n 'staff.time_tracking.reports.errors.currencyConflict',\n 'A report always covers one currency. Selected projects use {currencies}.',\n ).replace('{currencies}', currencies.join(', '))\n return new CrudHttpError(422, {\n code: REPORT_CURRENCY_CONFLICT_CODE,\n error: message,\n fieldErrors: { timeProjectIds: message },\n currencies,\n offenders: offenders.map((project) => ({\n id: project.id,\n name: project.name,\n currencyCode: project.currencyCode ?? null,\n })),\n })\n}\n\nfunction referenceConflictError(translate: Translate): CrudHttpError {\n return new CrudHttpError(409, {\n code: REPORT_REFERENCE_CONFLICT_CODE,\n error: translate(\n 'staff.time_tracking.reports.errors.referenceConflict',\n 'Could not allocate a report number right now. Try again.',\n ),\n })\n}\n\nexport type ResolvedReportProjects = {\n projects: StaffTimeProject[]\n currencyCode: string\n}\n\n/**\n * The single validation gate every write shares: the projects exist in scope,\n * they all belong to the report's customer, and they agree on a currency.\n */\nexport async function resolveReportProjects(\n em: EntityManager,\n timeProjectIds: readonly string[],\n customerId: string,\n scope: StaffCommandScope,\n translate: Translate,\n): Promise<ResolvedReportProjects> {\n const ids = Array.from(new Set(timeProjectIds.filter((id) => typeof id === 'string' && id.length > 0)))\n if (ids.length === 0) throw projectsRequiredError(translate)\n\n const projects = await em.find(\n StaffTimeProject,\n applyScopeToWhere<StaffTimeProject>({ id: { $in: ids }, deletedAt: null }, scope),\n )\n if (projects.length !== ids.length) {\n const found = new Set(projects.map((project) => project.id))\n throw projectNotFoundError(\n translate,\n ids.filter((id) => !found.has(id)),\n )\n }\n\n const mismatched = projects.filter((project) => (project.customerId ?? null) !== customerId)\n if (mismatched.length > 0) {\n throw customerMismatchError(\n translate,\n mismatched.map((project) => project.name),\n )\n }\n\n const resolution = resolveReportCurrency(\n projects.map((project) => ({\n id: project.id,\n name: project.name,\n currencyCode: project.currencyCode ?? null,\n })),\n )\n if (!resolution.ok) {\n throw currencyConflictError(translate, resolution.currencies, resolution.offenders)\n }\n\n return { projects, currencyCode: resolution.currencyCode ?? '' }\n}\n\n/**\n * D-9: the report carries the customer as an FK id plus a denormalized snapshot,\n * so the sheet header resolves a client name without joining the customers\n * module \u2014 and keeps resolving it if that customer is later removed. The\n * snapshot is taken from the selected projects, which already carry one, rather\n * than reaching across the module boundary a second time.\n */\nexport function deriveCustomerSnapshot(projects: readonly StaffTimeProject[]): Record<string, unknown> | null {\n for (const project of projects) {\n const snapshot = project.customerSnapshot\n if (snapshot && typeof snapshot === 'object' && Object.keys(snapshot).length > 0) {\n return snapshot as Record<string, unknown>\n }\n }\n return null\n}\n\nasync function readRoundingSnapshot(\n ctx: CommandRuntimeContext,\n tenantId: string,\n): Promise<{ unitMinutes: number; direction: string }> {\n try {\n const configService = ctx.container.resolve('moduleConfigService') as ModuleConfigService\n const settings = await readTimeTrackingSettings(configService, { tenantId })\n return { unitMinutes: settings.rounding.unitMinutes, direction: settings.rounding.direction }\n } catch (err) {\n // A draft that cannot read the rule still has to exist; close re-stamps it.\n logger.warn('staff.timesheets.reports rounding snapshot unavailable', { err })\n return { unitMinutes: 0, direction: 'up' }\n }\n}\n\nasync function replaceReportProjects(\n em: EntityManager,\n report: StaffTimeReport,\n projects: readonly StaffTimeProject[],\n): Promise<void> {\n const existing = await em.find(StaffTimeReportProject, { reportId: report.id })\n for (const row of existing) em.remove(row)\n for (const project of projects) {\n em.persist(\n em.create(StaffTimeReportProject, {\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n reportId: report.id,\n timeProjectId: project.id,\n createdAt: new Date(),\n }),\n )\n }\n}\n\nfunction actorUserId(ctx: CommandRuntimeContext): string | null {\n return typeof ctx.auth?.sub === 'string' ? ctx.auth.sub : null\n}\n\n/**\n * The highest report number the organization has EVER handed out this year,\n * soft-deleted rows included. The unique index covers live rows only, so a\n * deleted `RAP-2026-0042` would otherwise be reissued behind a PDF a client\n * already holds.\n */\nasync function readHighestReportSequence(\n em: EntityManager,\n year: number,\n scope: StaffCommandScope,\n): Promise<number> {\n const rows = await em.find(\n StaffTimeReport,\n applyScopeToWhere<StaffTimeReport>({ reference: { $like: `${reportReferencePrefix(year)}%` } }, scope),\n )\n return highestReportSequenceNumber(\n rows.map((row) => row.reference),\n year,\n )\n}\n\nconst createReportCommand: CommandHandler<StaffTimeReportCreateInput, { reportId: string }> = {\n id: staffTimeReportCommandIds.create,\n async execute(rawInput, ctx) {\n const parsed = staffTimeReportCreateSchema.parse(rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n const scope = commandInputScope(ctx, parsed.tenantId, parsed.organizationId)\n const { translate } = await resolveTranslations()\n const baseEm = ctx.container.resolve('em') as EntityManager\n const createdByUserId = actorUserId(ctx)\n const rounding = await readRoundingSnapshot(ctx, parsed.tenantId)\n const issuedAt = new Date()\n const year = reportReferenceYear(issuedAt)\n\n let record: StaffTimeReport\n try {\n record = await withReportReferenceRetry(async () => {\n // A fresh fork per attempt: a lost race aborts the transaction, so the\n // retry re-reads the highest reference rather than reusing a stale max.\n const em = baseEm.fork()\n let created: StaffTimeReport | null = null\n let plan: { projects: StaffTimeProject[]; currencyCode: string; highest: number } | null = null\n\n await withAtomicFlush(\n em,\n [\n async () => {\n const resolved = await resolveReportProjects(\n em,\n parsed.timeProjectIds,\n parsed.customerId,\n scope,\n translate,\n )\n plan = {\n projects: resolved.projects,\n currencyCode: resolved.currencyCode,\n highest: await readHighestReportSequence(em, year, scope),\n }\n },\n () => {\n if (!plan) throw reportNotFoundError(translate)\n const allocation = allocateReportReference(year, plan.highest)\n const now = new Date()\n created = em.create(StaffTimeReport, {\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n customerId: parsed.customerId,\n customerSnapshot: deriveCustomerSnapshot(plan.projects),\n reference: allocation.reference,\n title: parsed.title,\n periodKind: parsed.periodKind,\n periodFrom: parsed.periodFrom,\n periodTo: parsed.periodTo,\n currencyCode: plan.currencyCode,\n grouping: parsed.grouping,\n nonbillableMode: parsed.nonbillableMode,\n includeAlreadyReported: parsed.includeAlreadyReported,\n showRates: parsed.showRates,\n roundingUnitMinutes: rounding.unitMinutes,\n roundingDirection: rounding.direction,\n status: 'draft',\n createdByUserId,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n })\n em.persist(created)\n },\n async () => {\n if (!created || !plan) return\n await replaceReportProjects(em, created, plan.projects)\n },\n ],\n { transaction: true, label: staffTimeReportCommandIds.create },\n )\n\n if (!created) throw reportNotFoundError(translate)\n return created as StaffTimeReport\n })\n } catch (err) {\n if (isReportReferenceConflict(err)) throw referenceConflictError(translate)\n throw err\n }\n\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine'),\n action: 'created',\n entity: record,\n identifiers: { id: record.id, organizationId: record.organizationId, tenantId: record.tenantId },\n events: reportCrudEvents,\n indexer: reportCrudIndexer,\n })\n\n return { reportId: record.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadReportSnapshot(em, result.reportId, staffSnapshotScopeFromContext(ctx))\n if (!snapshot) return null\n return { snapshot }\n },\n buildLog: async ({ result, ctx }) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadReportSnapshot(em, result.reportId, staffSnapshotScopeFromContext(ctx))\n if (!snapshot) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.timesheets.reports.create', 'Create report'),\n resourceKind: STAFF_TIME_REPORT_RESOURCE_KIND,\n resourceId: snapshot.id,\n tenantId: snapshot.tenantId,\n organizationId: snapshot.organizationId,\n snapshotAfter: snapshot,\n payload: { undo: { after: snapshot } satisfies ReportUndoPayload },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<ReportUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const report = await em.findOne(\n StaffTimeReport,\n scopedStaffSnapshotWhere(after.id, staffSnapshotScopeFromSnapshot(after)),\n )\n if (!report) return\n // A report that has since been closed froze entries; undoing its creation\n // would strand those locks, so the undo declines rather than half-unwinding.\n if (report.status === 'closed') return\n report.deletedAt = new Date()\n report.updatedAt = new Date()\n await em.flush()\n\n await emitCrudUndoSideEffects({\n dataEngine: ctx.container.resolve('dataEngine'),\n action: 'deleted',\n entity: report,\n identifiers: { id: report.id, organizationId: report.organizationId, tenantId: report.tenantId },\n events: reportCrudEvents,\n indexer: reportCrudIndexer,\n })\n },\n}\n\nconst updateReportCommand: CommandHandler<StaffTimeReportUpdateInput, { reportId: string }> = {\n id: staffTimeReportCommandIds.update,\n async prepare(rawInput, ctx) {\n const parsed = staffTimeReportUpdateSchema.safeParse(rawInput)\n if (!parsed.success) return {}\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const before = await loadReportSnapshot(em, parsed.data.id, staffSnapshotScopeFromContext(ctx))\n if (!before) return {}\n return { before: { snapshot: before } }\n },\n async execute(rawInput, ctx) {\n const parsed = staffTimeReportUpdateSchema.parse(rawInput)\n const { translate } = await resolveTranslations()\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = commandActorScope(ctx)\n\n const report = await em.findOne(\n StaffTimeReport,\n applyScopeToWhere<StaffTimeReport>({ id: parsed.id, deletedAt: null }, scope),\n )\n if (!report) throw reportNotFoundError(translate)\n ensureTenantScope(ctx, report.tenantId)\n ensureOrganizationScope(ctx, report.organizationId)\n if (report.status === 'closed') throw reportClosedError(translate, report.reference)\n\n const targetCustomerId = parsed.customerId ?? report.customerId\n let resolved: ResolvedReportProjects | null = null\n\n await withAtomicFlush(\n em,\n [\n async () => {\n const needsProjectCheck =\n parsed.timeProjectIds !== undefined || (parsed.customerId !== undefined && parsed.customerId !== report.customerId)\n if (!needsProjectCheck) return\n const ids = parsed.timeProjectIds ?? (await loadReportProjectIds(em, report.id, scope))\n resolved = await resolveReportProjects(em, ids, targetCustomerId, scope, translate)\n },\n () => {\n const now = new Date()\n if (parsed.title !== undefined) report.title = parsed.title\n if (parsed.periodKind !== undefined) report.periodKind = parsed.periodKind\n if (parsed.periodFrom !== undefined) report.periodFrom = parsed.periodFrom\n if (parsed.periodTo !== undefined) report.periodTo = parsed.periodTo\n if (parsed.grouping !== undefined) report.grouping = parsed.grouping\n if (parsed.nonbillableMode !== undefined) report.nonbillableMode = parsed.nonbillableMode\n if (parsed.includeAlreadyReported !== undefined) {\n report.includeAlreadyReported = parsed.includeAlreadyReported\n }\n if (parsed.showRates !== undefined) report.showRates = parsed.showRates\n if (parsed.customerId !== undefined) report.customerId = parsed.customerId\n if (resolved) {\n report.currencyCode = resolved.currencyCode\n report.customerSnapshot = deriveCustomerSnapshot(resolved.projects) ?? report.customerSnapshot ?? null\n }\n report.updatedAt = now\n },\n async () => {\n if (!resolved || parsed.timeProjectIds === undefined) return\n await replaceReportProjects(em, report, resolved.projects)\n },\n ],\n { transaction: true, label: staffTimeReportCommandIds.update },\n )\n\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine'),\n action: 'updated',\n entity: report,\n identifiers: { id: report.id, organizationId: report.organizationId, tenantId: report.tenantId },\n events: reportCrudEvents,\n indexer: reportCrudIndexer,\n })\n\n return { reportId: report.id }\n },\n buildLog: async ({ snapshots, ctx }) => {\n const before = (snapshots.before as { snapshot?: ReportSnapshot } | undefined)?.snapshot\n if (!before) return null\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const after = await loadReportSnapshot(em, before.id, staffSnapshotScopeFromSnapshot(before))\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.timesheets.reports.update', 'Update report'),\n resourceKind: STAFF_TIME_REPORT_RESOURCE_KIND,\n resourceId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: after,\n changes: buildChanges(\n before as unknown as Record<string, unknown>,\n after as unknown as Record<string, unknown>,\n [...DIFFED_FIELDS],\n ),\n payload: { undo: { before, after } satisfies ReportUndoPayload },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<ReportUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const report = await em.findOne(\n StaffTimeReport,\n scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)),\n )\n if (!report) return\n if (report.status === 'closed') return\n\n const projects = await em.find(StaffTimeProject, {\n id: { $in: before.timeProjectIds },\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n })\n\n await withAtomicFlush(\n em,\n [\n () => {\n report.customerId = before.customerId\n report.customerSnapshot = before.customerSnapshot\n report.title = before.title\n report.periodKind = before.periodKind as StaffTimeReport['periodKind']\n if (before.periodFrom) report.periodFrom = new Date(before.periodFrom)\n if (before.periodTo) report.periodTo = new Date(before.periodTo)\n report.currencyCode = before.currencyCode\n report.grouping = before.grouping as StaffTimeReport['grouping']\n report.nonbillableMode = before.nonbillableMode as StaffTimeReport['nonbillableMode']\n report.includeAlreadyReported = before.includeAlreadyReported\n report.showRates = before.showRates\n report.updatedAt = new Date()\n },\n async () => {\n if (projects.length !== before.timeProjectIds.length) return\n await replaceReportProjects(em, report, projects)\n },\n ],\n { transaction: true, label: `${staffTimeReportCommandIds.update}.undo` },\n )\n\n await emitCrudUndoSideEffects({\n dataEngine: ctx.container.resolve('dataEngine'),\n action: 'updated',\n entity: report,\n identifiers: { id: report.id, organizationId: report.organizationId, tenantId: report.tenantId },\n events: reportCrudEvents,\n indexer: reportCrudIndexer,\n })\n },\n}\n\nconst deleteReportCommand: CommandHandler<{ id?: string }, { reportId: string }> = {\n id: staffTimeReportCommandIds.delete,\n async prepare(input, ctx) {\n const id = input?.id\n if (!id) return {}\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const before = await loadReportSnapshot(em, id, staffSnapshotScopeFromContext(ctx))\n if (!before) return {}\n return { before: { snapshot: before } }\n },\n async execute(input, ctx) {\n const { translate } = await resolveTranslations()\n const id = input?.id\n if (!id) {\n throw new CrudHttpError(400, {\n error: translate('staff.time_tracking.reports.errors.idRequired', 'Report id is required.'),\n })\n }\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = commandActorScope(ctx)\n const report = await em.findOne(\n StaffTimeReport,\n applyScopeToWhere<StaffTimeReport>({ id, deletedAt: null }, scope),\n )\n if (!report) throw reportNotFoundError(translate)\n ensureTenantScope(ctx, report.tenantId)\n ensureOrganizationScope(ctx, report.organizationId)\n // Deleting a closed report would strand every entry it froze: their\n // `locked_report_id` would point at a row nothing can unlock.\n if (report.status === 'closed') throw reportClosedError(translate, report.reference)\n\n const now = new Date()\n report.deletedAt = now\n report.updatedAt = now\n await em.flush()\n\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine'),\n action: 'deleted',\n entity: report,\n identifiers: { id: report.id, organizationId: report.organizationId, tenantId: report.tenantId },\n events: reportCrudEvents,\n indexer: reportCrudIndexer,\n })\n\n return { reportId: report.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = (snapshots.before as { snapshot?: ReportSnapshot } | undefined)?.snapshot\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.timesheets.reports.delete', 'Delete report'),\n resourceKind: STAFF_TIME_REPORT_RESOURCE_KIND,\n resourceId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: { undo: { before } satisfies ReportUndoPayload },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<ReportUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const report = await em.findOne(\n StaffTimeReport,\n scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)),\n )\n if (!report) return\n report.deletedAt = null\n report.updatedAt = new Date()\n await em.flush()\n\n await emitCrudUndoSideEffects({\n dataEngine: ctx.container.resolve('dataEngine'),\n action: 'created',\n entity: report,\n identifiers: { id: report.id, organizationId: report.organizationId, tenantId: report.tenantId },\n events: reportCrudEvents,\n indexer: reportCrudIndexer,\n })\n },\n}\n\nregisterCommand(createReportCommand)\nregisterCommand(updateReportCommand)\nregisterCommand(deleteReportCommand)\n\n/**\n * US-G3 \u2014 close & lock. This is the only place a lock is created: exporting a\n * PDF freezes nothing (screen 14 note 5), because \"in a generated/sent report\"\n * (\u00A79) is ambiguous and a download that silently locks a team's timesheet is the\n * worse reading of it.\n *\n * Everything the close writes happens inside ONE `withAtomicFlush({ transaction:\n * true })`: the per-entry freeze records, the `locked_report_id` stamps, the\n * frozen report totals and the `closed` audit event. A partial close would leave\n * entries frozen against a report that never closed \u2014 unlockable by nobody,\n * because the unlock command refuses a draft.\n *\n * Two rules that are easy to get wrong:\n *\n * - **The freeze records come from the same `selectIncludedEntries` /\n * `resolveEntryValues` pair the sheet printed**, so what is frozen is by\n * construction what the client was shown. The amounts are already rounded at\n * the entry (D-7), which is what lets `total_amount` be an exact sum.\n * - **An entry already locked by another report keeps that lock.** When the\n * D-5 opt-in pulls a previously billed hour into a second report, this report\n * records what it billed, but ownership of the lock stays with the report\n * that froze it first \u2014 otherwise unlocking the earlier report would leave\n * the hour editable while a later closed report still quotes it.\n */\nexport type StaffTimeReportCloseResult = {\n reportId: string\n lockedEntryCount: number\n totalAmount: number\n totalBillableMinutes: number\n totalNonbillableMinutes: number\n}\n\nfunction reportNotClosedError(translate: Translate): CrudHttpError {\n return new CrudHttpError(409, {\n code: REPORT_NOT_CLOSED_CODE,\n error: translate(\n 'staff.time_tracking.reports.errors.notClosed',\n 'This report is not closed, so there is nothing to unlock.',\n ),\n })\n}\n\nfunction reportEmptyError(translate: Translate): CrudHttpError {\n return new CrudHttpError(422, {\n code: REPORT_EMPTY_CODE,\n error: translate(\n 'staff.time_tracking.reports.errors.empty',\n 'This report covers no time entries, so there is nothing to freeze. Adjust the period or the project selection first.',\n ),\n })\n}\n\nconst closeReportCommand: CommandHandler<StaffTimeReportCloseInput, StaffTimeReportCloseResult> = {\n id: staffTimeReportCommandIds.close,\n async prepare(rawInput, ctx) {\n const parsed = staffTimeReportCloseSchema.safeParse(rawInput)\n if (!parsed.success) return {}\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const before = await loadReportSnapshot(em, parsed.data.id, staffSnapshotScopeFromContext(ctx))\n if (!before) return {}\n return { before: { snapshot: before } }\n },\n async execute(rawInput, ctx) {\n const parsed = staffTimeReportCloseSchema.parse(rawInput)\n const { translate } = await resolveTranslations()\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = commandActorScope(ctx)\n\n const report = await em.findOne(\n StaffTimeReport,\n applyScopeToWhere<StaffTimeReport>({ id: parsed.id, deletedAt: null }, scope),\n )\n if (!report) throw reportNotFoundError(translate)\n ensureTenantScope(ctx, report.tenantId)\n ensureOrganizationScope(ctx, report.organizationId)\n if (report.status === 'closed') throw reportClosedError(translate, report.reference)\n\n const dataScope = { tenantId: report.tenantId, organizationId: report.organizationId }\n const rounding = await readRoundingSnapshot(ctx, report.tenantId)\n const actorId = actorUserId(ctx)\n const labels = reportSheetLabels(translate)\n\n type ClosePlanItem = {\n entry: ReturnType<typeof selectIncludedEntries>[number]\n row: StaffTimeEntry | null\n values: ReturnType<typeof resolveEntryValues>\n currencyCode: string\n }\n\n let lockedEntryCount = 0\n let totals: ReturnType<typeof computeReportTotals> | null = null\n let closePlan: ClosePlanItem[] = []\n\n await withAtomicFlush(\n em,\n [\n async () => {\n const timeProjectIds = await loadReportProjectIds(em, report.id, dataScope)\n const data = await loadReportData({\n em,\n scope: dataScope,\n timeProjectIds,\n periodFrom: report.periodFrom,\n periodTo: report.periodTo,\n })\n const options = {\n grouping: report.grouping,\n nonbillableMode: report.nonbillableMode,\n includeAlreadyReported: report.includeAlreadyReported ?? false,\n } as const\n const included = selectIncludedEntries(data.entries, options, report.id)\n if (included.length === 0) throw reportEmptyError(translate)\n\n totals = computeReportTotals({\n entries: data.entries,\n projects: data.projects,\n directory: data.directory,\n options,\n currentReportId: report.id,\n labels,\n })\n\n const projectById = new Map(data.projects.map((project) => [project.id, project]))\n const entryRows = await em.find(StaffTimeEntry, {\n id: { $in: included.map((entry) => entry.id) },\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n })\n const entryById = new Map(entryRows.map((row) => [row.id, row]))\n\n closePlan = included.map((entry) => ({\n entry,\n row: entryById.get(entry.id) ?? null,\n values: resolveEntryValues(entry, projectById.get(entry.timeProjectId) ?? null),\n currencyCode:\n projectById.get(entry.timeProjectId)?.currencyCode ?? report.currencyCode ?? '',\n }))\n },\n () => {\n if (!totals) throw reportEmptyError(translate)\n const now = new Date()\n for (const item of closePlan) {\n em.persist(\n em.create(StaffTimeReportEntry, {\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n reportId: report.id,\n timeEntryId: item.entry.id,\n frozenRawMinutes: item.values.rawMinutes,\n frozenRoundedMinutes: item.values.minutes,\n frozenRateAmount: item.values.rate === null ? null : String(item.values.rate),\n frozenCurrencyCode: item.currencyCode,\n frozenAmount: item.values.amount === null ? null : item.values.amount.toFixed(2),\n frozenIsBillable: item.values.isBillable,\n createdAt: now,\n }),\n )\n const row = item.row\n if (!row) continue\n // Ownership of an existing lock is never transferred \u2014 see the note\n // on this command.\n if (row.lockedReportId) continue\n row.lockedReportId = report.id\n row.lockedAt = now\n row.updatedAt = now\n lockedEntryCount += 1\n }\n\n report.status = 'closed'\n report.closedAt = now\n report.closedByUserId = actorId\n report.roundingUnitMinutes = rounding.unitMinutes\n report.roundingDirection = rounding.direction\n report.totalBillableMinutes = totals.billableMinutes\n report.totalNonbillableMinutes = totals.nonbillableMinutes\n report.totalAmount = totals.totalAmount.toFixed(2)\n report.updatedAt = now\n\n em.persist(\n em.create(StaffTimeReportEvent, {\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n reportId: report.id,\n eventType: 'closed',\n reason: null,\n actorUserId: actorId,\n metadata: {\n frozenEntryCount: closePlan.length,\n lockedEntryCount,\n totalAmount: totals.totalAmount,\n currencyCode: report.currencyCode,\n roundingUnitMinutes: rounding.unitMinutes,\n roundingDirection: rounding.direction,\n },\n createdAt: now,\n }),\n )\n },\n ],\n { transaction: true, label: staffTimeReportCommandIds.close },\n )\n\n const resolved = totals as ReturnType<typeof computeReportTotals> | null\n const result: StaffTimeReportCloseResult = {\n reportId: report.id,\n lockedEntryCount,\n totalAmount: resolved?.totalAmount ?? 0,\n totalBillableMinutes: resolved?.billableMinutes ?? 0,\n totalNonbillableMinutes: resolved?.nonbillableMinutes ?? 0,\n }\n\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine'),\n action: 'updated',\n entity: report,\n identifiers: { id: report.id, organizationId: report.organizationId, tenantId: report.tenantId },\n events: reportCrudEvents,\n indexer: reportCrudIndexer,\n })\n\n // A failed broadcast must never fail a committed close.\n //\n // The payload is spelled out rather than spreading `result` because this event is\n // `clientBroadcast: true`: the DOM Event Bridge delivers it to every user of the\n // organization with no feature check, and `result.totalAmount` is money, which is\n // gated on `staff.timesheets.rates.view`. The minute totals and the locked-entry\n // count are not money and are what a live report screen needs; the amount is read\n // back from the report itself by a caller entitled to it.\n //\n // What else that unfiltered audience decides, field by field:\n //\n // - `customerId` is DROPPED. It is the one field that links a report to a named\n // client, and one organization serves many; a tenant's whole staff learning\n // which client was billed this week is a disclosure with no consumer asking\n // for it. The schema always declared it optional, both in-repo subscribers\n // re-read the report from the database, and the portal mirror\n // (`time_report.portal_published`) resolves the customer itself.\n // - `reference` and the two minute totals STAY. They are stable identifiers and\n // non-money aggregates, they are the published webhook contract an external\n // billing system codes against, and they are what a live reports screen needs\n // to refresh a row. Narrowing them further is not expressible here: the DOM\n // bridge can only pin an audience by user or ROLE id, and this module\n // deliberately gates on immutable feature ids rather than mutable roles.\n void emitStaffEvent('staff.timesheets.time_report.closed', {\n id: report.id,\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n reference: report.reference,\n reportId: result.reportId,\n lockedEntryCount: result.lockedEntryCount,\n totalBillableMinutes: result.totalBillableMinutes,\n totalNonbillableMinutes: result.totalNonbillableMinutes,\n }).catch((err) => {\n logger.error('staff.timesheets emit time_report.closed failed', { err })\n })\n\n // The close froze `lockedEntryCount` entries. The entry-scoped subscribers key\n // off a single record id, so this batch-level notice carries none and reaches\n // only the ones that care about a period being frozen.\n if (lockedEntryCount > 0) {\n void emitStaffEvent('staff.timesheets.time_entry.locked', {\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n reportId: report.id,\n lockedEntryCount,\n }).catch((err) => {\n logger.error('staff.timesheets emit time_entry.locked failed', { err })\n })\n }\n\n return result\n },\n buildLog: async ({ snapshots, ctx }) => {\n const before = (snapshots.before as { snapshot?: ReportSnapshot } | undefined)?.snapshot\n if (!before) return null\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const after = await loadReportSnapshot(em, before.id, staffSnapshotScopeFromSnapshot(before))\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.timesheets.reports.close', 'Close and lock report'),\n resourceKind: STAFF_TIME_REPORT_RESOURCE_KIND,\n resourceId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: after,\n changes: buildChanges(\n before as unknown as Record<string, unknown>,\n after as unknown as Record<string, unknown>,\n [...DIFFED_FIELDS],\n ),\n // Deliberately no `undo` payload: unwinding a close is the unlock command,\n // which requires a reason and its own feature. A silent undo of a billing\n // freeze is exactly what US-G3 forbids.\n }\n },\n}\n\n/**\n * US-G3's other half \u2014 unlock, screen 15.\n *\n * Three things make it an \"explicit, audited action\" rather than a confirm\n * dialog: it takes a mandatory reason, it appends an `unlocked` event carrying\n * that reason and the actor, and it is gated on `staff.timesheets.reports.unlock`\n * \u2014 a feature distinct from `staff.timesheets.lock`, so \"who may restate billed\n * time\" can be answered by withholding it from a Team Leader without inventing\n * the admin role \u00A710 rejects.\n *\n * The freeze records are DELETED rather than kept. Two reasons: `staff_time_\n * report_entries` is what makes D-5 answerable (\"is this hour already billed?\"),\n * so leaving stale rows behind after the report reopened would keep hours out of\n * the next invoice for no reason; and the unique `(report_id, time_entry_id)`\n * index would otherwise refuse the re-close. The numbers they held are copied\n * into the `unlocked` event's metadata, so the audit trail keeps what was\n * frozen.\n */\nexport type StaffTimeReportUnlockResult = {\n reportId: string\n unlockedEntryCount: number\n}\n\nconst unlockReportCommand: CommandHandler<StaffTimeReportUnlockInput, StaffTimeReportUnlockResult> = {\n id: staffTimeReportCommandIds.unlock,\n async prepare(rawInput, ctx) {\n const parsed = staffTimeReportUnlockSchema.safeParse(rawInput)\n if (!parsed.success) return {}\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const before = await loadReportSnapshot(em, parsed.data.id, staffSnapshotScopeFromContext(ctx))\n if (!before) return {}\n return { before: { snapshot: before } }\n },\n async execute(rawInput, ctx) {\n const parsed = staffTimeReportUnlockSchema.parse(rawInput)\n const { translate } = await resolveTranslations()\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = commandActorScope(ctx)\n\n const report = await em.findOne(\n StaffTimeReport,\n applyScopeToWhere<StaffTimeReport>({ id: parsed.id, deletedAt: null }, scope),\n )\n if (!report) throw reportNotFoundError(translate)\n ensureTenantScope(ctx, report.tenantId)\n ensureOrganizationScope(ctx, report.organizationId)\n if (report.status !== 'closed') throw reportNotClosedError(translate)\n\n const actorId = actorUserId(ctx)\n let unlockedEntryCount = 0\n let frozenEntries: StaffTimeReportEntry[] = []\n let lockedRows: StaffTimeEntry[] = []\n const frozenTotals = {\n totalAmount: report.totalAmount,\n totalBillableMinutes: report.totalBillableMinutes ?? null,\n totalNonbillableMinutes: report.totalNonbillableMinutes ?? null,\n }\n\n await withAtomicFlush(\n em,\n [\n async () => {\n frozenEntries = await em.find(StaffTimeReportEntry, {\n reportId: report.id,\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n })\n lockedRows = await em.find(StaffTimeEntry, {\n lockedReportId: report.id,\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n })\n },\n () => {\n const now = new Date()\n for (const row of lockedRows) {\n row.lockedReportId = null\n row.lockedAt = null\n row.updatedAt = now\n unlockedEntryCount += 1\n }\n for (const frozen of frozenEntries) em.remove(frozen)\n\n report.status = 'draft'\n report.closedAt = null\n report.closedByUserId = null\n report.totalAmount = null\n report.totalBillableMinutes = null\n report.totalNonbillableMinutes = null\n report.updatedAt = now\n\n em.persist(\n em.create(StaffTimeReportEvent, {\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n reportId: report.id,\n eventType: 'unlocked',\n reason: parsed.reason,\n actorUserId: actorId,\n metadata: {\n unlockedEntryCount,\n frozenEntryCount: frozenEntries.length,\n frozenTotalAmount: frozenTotals.totalAmount,\n frozenBillableMinutes: frozenTotals.totalBillableMinutes,\n frozenNonbillableMinutes: frozenTotals.totalNonbillableMinutes,\n currencyCode: report.currencyCode,\n },\n createdAt: now,\n }),\n )\n },\n ],\n { transaction: true, label: staffTimeReportCommandIds.unlock },\n )\n\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine'),\n action: 'updated',\n entity: report,\n identifiers: { id: report.id, organizationId: report.organizationId, tenantId: report.tenantId },\n events: reportCrudEvents,\n indexer: reportCrudIndexer,\n })\n\n // `reason` is deliberately NOT on the wire.\n //\n // This event is `clientBroadcast: true`, and the DOM Event Bridge filters a\n // broadcast by tenant + organization only \u2014 no feature check \u2014 so every\n // signed-in user of the organization receives whatever the payload carries.\n // `reason` is mandatory operator prose of up to 2000 characters explaining why\n // a client's billing was reopened; broadcasting it organization-wide is a\n // disclosure the screen it comes from (`staff.timesheets.reports.unlock`) does\n // not make. It is already persisted verbatim on the `StaffTimeReportEvent`\n // audit row above, which is read behind the ACL, so nothing is lost.\n void emitStaffEvent('staff.timesheets.time_report.unlocked', {\n id: report.id,\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n reference: report.reference,\n actorUserId: actorId,\n unlockedEntryCount,\n }).catch((err) => {\n logger.error('staff.timesheets emit time_report.unlocked failed', { err })\n })\n\n if (unlockedEntryCount > 0) {\n void emitStaffEvent('staff.timesheets.time_entry.unlocked', {\n tenantId: report.tenantId,\n organizationId: report.organizationId,\n reportId: report.id,\n unlockedEntryCount,\n }).catch((err) => {\n logger.error('staff.timesheets emit time_entry.unlocked failed', { err })\n })\n }\n\n return { reportId: report.id, unlockedEntryCount }\n },\n buildLog: async ({ snapshots, ctx, input }) => {\n const before = (snapshots.before as { snapshot?: ReportSnapshot } | undefined)?.snapshot\n if (!before) return null\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const after = await loadReportSnapshot(em, before.id, staffSnapshotScopeFromSnapshot(before))\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.timesheets.reports.unlock', 'Unlock report entries'),\n resourceKind: STAFF_TIME_REPORT_RESOURCE_KIND,\n resourceId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: after,\n changes: buildChanges(\n before as unknown as Record<string, unknown>,\n after as unknown as Record<string, unknown>,\n [...DIFFED_FIELDS],\n ),\n payload: { reason: input?.reason ?? null },\n }\n },\n}\n\nregisterCommand(closeReportCommand)\nregisterCommand(unlockReportCommand)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|