@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,94 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
|
|
3
|
+
export class Migration20260813073131_staff extends Migration {
|
|
4
|
+
|
|
5
|
+
override up(): void | Promise<void> {
|
|
6
|
+
this.addSql(`create table "staff_time_entry_tags" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "tag_id" uuid not null, "time_entry_id" uuid not null, "created_at" timestamptz not null, primary key ("id"));`);
|
|
7
|
+
this.addSql(`create unique index "staff_time_entry_tags_unique_idx" on "staff_time_entry_tags" ("tag_id", "time_entry_id");`);
|
|
8
|
+
this.addSql(`create index "staff_time_entry_tags_entry_idx" on "staff_time_entry_tags" ("organization_id", "time_entry_id");`);
|
|
9
|
+
this.addSql(`create index "staff_time_entry_tags_tenant_org_idx" on "staff_time_entry_tags" ("tenant_id", "organization_id");`);
|
|
10
|
+
|
|
11
|
+
this.addSql(`create table "staff_time_reports" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "customer_id" uuid not null, "customer_snapshot" jsonb null, "reference" text not null, "title" text not null, "period_kind" text not null default 'month', "period_from" date not null, "period_to" date not null, "currency_code" text not null, "grouping" text not null default 'project_task', "nonbillable_mode" text not null default 'separate', "include_already_reported" boolean not null default false, "show_rates" boolean not null default true, "rounding_unit_minutes" int not null default 0, "rounding_direction" text not null default 'up', "status" text not null default 'draft', "total_billable_minutes" int null, "total_nonbillable_minutes" int null, "total_amount" numeric(14,2) null, "closed_at" timestamptz null, "closed_by_user_id" uuid null, "created_by_user_id" uuid null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
|
|
12
|
+
this.addSql(`create unique index "staff_time_reports_reference_unique_idx" on "staff_time_reports" ("organization_id", "tenant_id", "reference") where "deleted_at" is null;`);
|
|
13
|
+
this.addSql(`create index "staff_time_reports_status_idx" on "staff_time_reports" ("organization_id", "status", "period_from");`);
|
|
14
|
+
this.addSql(`create index "staff_time_reports_customer_idx" on "staff_time_reports" ("organization_id", "customer_id");`);
|
|
15
|
+
this.addSql(`create index "staff_time_reports_tenant_org_idx" on "staff_time_reports" ("tenant_id", "organization_id");`);
|
|
16
|
+
|
|
17
|
+
this.addSql(`create table "staff_time_report_entries" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "report_id" uuid not null, "time_entry_id" uuid not null, "frozen_raw_minutes" int not null default 0, "frozen_rounded_minutes" int not null default 0, "frozen_rate_amount" numeric(14,4) null, "frozen_currency_code" text not null, "frozen_amount" numeric(14,2) null, "frozen_is_billable" boolean not null default true, "created_at" timestamptz not null, primary key ("id"));`);
|
|
18
|
+
this.addSql(`create unique index "staff_time_report_entries_unique_idx" on "staff_time_report_entries" ("report_id", "time_entry_id");`);
|
|
19
|
+
this.addSql(`create index "staff_time_report_entries_entry_idx" on "staff_time_report_entries" ("organization_id", "time_entry_id");`);
|
|
20
|
+
this.addSql(`create index "staff_time_report_entries_tenant_org_idx" on "staff_time_report_entries" ("tenant_id", "organization_id");`);
|
|
21
|
+
|
|
22
|
+
this.addSql(`create table "staff_time_report_events" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "report_id" uuid not null, "event_type" text not null, "reason" text null, "actor_user_id" uuid null, "metadata" jsonb null, "created_at" timestamptz not null, primary key ("id"));`);
|
|
23
|
+
this.addSql(`create index "staff_time_report_events_report_idx" on "staff_time_report_events" ("organization_id", "report_id", "created_at");`);
|
|
24
|
+
this.addSql(`create index "staff_time_report_events_tenant_org_idx" on "staff_time_report_events" ("tenant_id", "organization_id");`);
|
|
25
|
+
|
|
26
|
+
this.addSql(`create table "staff_time_report_projects" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "report_id" uuid not null, "time_project_id" uuid not null, "created_at" timestamptz not null, primary key ("id"));`);
|
|
27
|
+
this.addSql(`create unique index "staff_time_report_projects_unique_idx" on "staff_time_report_projects" ("report_id", "time_project_id");`);
|
|
28
|
+
this.addSql(`create index "staff_time_report_projects_project_idx" on "staff_time_report_projects" ("organization_id", "time_project_id");`);
|
|
29
|
+
this.addSql(`create index "staff_time_report_projects_tenant_org_idx" on "staff_time_report_projects" ("tenant_id", "organization_id");`);
|
|
30
|
+
|
|
31
|
+
this.addSql(`create table "staff_time_tags" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "slug" text not null, "label" text not null, "color" text null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
|
|
32
|
+
this.addSql(`create unique index "staff_time_tags_slug_unique_idx" on "staff_time_tags" ("organization_id", "tenant_id", "slug") where "deleted_at" is null;`);
|
|
33
|
+
this.addSql(`create index "staff_time_tags_tenant_org_idx" on "staff_time_tags" ("tenant_id", "organization_id");`);
|
|
34
|
+
|
|
35
|
+
this.addSql(`create table "staff_time_tasks" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "time_project_id" uuid not null, "parent_task_id" uuid null, "task_status_id" uuid not null, "sequence_number" int not null default 0, "reference" text not null, "title" text not null, "description" text null, "assignee_staff_member_id" uuid null, "position" int not null default 0, "created_by_user_id" uuid null, "closed_at" timestamptz null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
|
|
36
|
+
this.addSql(`create unique index "staff_time_tasks_reference_unique_idx" on "staff_time_tasks" ("organization_id", "tenant_id", "reference") where "deleted_at" is null;`);
|
|
37
|
+
this.addSql(`create unique index "staff_time_tasks_sequence_unique_idx" on "staff_time_tasks" ("organization_id", "tenant_id", "time_project_id", "sequence_number") where "deleted_at" is null;`);
|
|
38
|
+
this.addSql(`create index "staff_time_tasks_assignee_idx" on "staff_time_tasks" ("organization_id", "assignee_staff_member_id");`);
|
|
39
|
+
this.addSql(`create index "staff_time_tasks_parent_idx" on "staff_time_tasks" ("organization_id", "parent_task_id");`);
|
|
40
|
+
this.addSql(`create index "staff_time_tasks_board_idx" on "staff_time_tasks" ("organization_id", "time_project_id", "task_status_id", "position");`);
|
|
41
|
+
this.addSql(`create index "staff_time_tasks_tenant_org_idx" on "staff_time_tasks" ("tenant_id", "organization_id");`);
|
|
42
|
+
|
|
43
|
+
this.addSql(`create table "staff_time_task_comments" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "task_id" uuid not null, "body" text not null, "author_user_id" uuid null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
|
|
44
|
+
this.addSql(`create index "staff_time_task_comments_task_idx" on "staff_time_task_comments" ("organization_id", "task_id", "created_at");`);
|
|
45
|
+
this.addSql(`create index "staff_time_task_comments_tenant_org_idx" on "staff_time_task_comments" ("tenant_id", "organization_id");`);
|
|
46
|
+
|
|
47
|
+
this.addSql(`create table "staff_time_task_statuses" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "time_project_id" uuid not null, "name" text not null, "slug" text not null, "color" text null, "position" int not null default 0, "is_default" boolean not null default false, "is_done" boolean not null default false, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
|
|
48
|
+
this.addSql(`create unique index "staff_time_task_statuses_slug_unique_idx" on "staff_time_task_statuses" ("organization_id", "tenant_id", "time_project_id", "slug") where "deleted_at" is null;`);
|
|
49
|
+
this.addSql(`create index "staff_time_task_statuses_project_idx" on "staff_time_task_statuses" ("organization_id", "time_project_id", "position");`);
|
|
50
|
+
this.addSql(`create index "staff_time_task_statuses_tenant_org_idx" on "staff_time_task_statuses" ("tenant_id", "organization_id");`);
|
|
51
|
+
|
|
52
|
+
this.addSql(`create table "staff_time_task_tags" ("id" uuid not null default gen_random_uuid(), "tenant_id" uuid not null, "organization_id" uuid not null, "tag_id" uuid not null, "task_id" uuid not null, "created_at" timestamptz not null, primary key ("id"));`);
|
|
53
|
+
this.addSql(`create unique index "staff_time_task_tags_unique_idx" on "staff_time_task_tags" ("tag_id", "task_id");`);
|
|
54
|
+
this.addSql(`create index "staff_time_task_tags_task_idx" on "staff_time_task_tags" ("organization_id", "task_id");`);
|
|
55
|
+
this.addSql(`create index "staff_time_task_tags_tenant_org_idx" on "staff_time_task_tags" ("tenant_id", "organization_id");`);
|
|
56
|
+
|
|
57
|
+
this.addSql(`alter table "staff_time_reports" add constraint "staff_time_reports_period_kind_check" check ("period_kind" in ('week', 'month', 'year', 'custom'));`);
|
|
58
|
+
this.addSql(`alter table "staff_time_reports" add constraint "staff_time_reports_grouping_check" check ("grouping" in ('project_task', 'project_person', 'project_day'));`);
|
|
59
|
+
this.addSql(`alter table "staff_time_reports" add constraint "staff_time_reports_nonbillable_mode_check" check ("nonbillable_mode" in ('separate', 'exclude'));`);
|
|
60
|
+
this.addSql(`alter table "staff_time_reports" add constraint "staff_time_reports_status_check" check ("status" in ('draft', 'closed'));`);
|
|
61
|
+
|
|
62
|
+
this.addSql(`alter table "staff_time_report_events" add constraint "staff_time_report_events_event_type_check" check ("event_type" in ('closed', 'unlocked', 'exported'));`);
|
|
63
|
+
|
|
64
|
+
this.addSql(`alter table "staff_time_entries" add "task_id" uuid null, add "is_billable" boolean not null default true, add "rounded_minutes" int null, add "rate_override_amount" numeric(14,4) null, add "rate_currency_code" text null, add "locked_report_id" uuid null, add "locked_at" timestamptz null;`);
|
|
65
|
+
this.addSql(`create index "staff_time_entries_locked_report_idx" on "staff_time_entries" ("organization_id", "locked_report_id");`);
|
|
66
|
+
this.addSql(`create index "staff_time_entries_member_overlap_idx" on "staff_time_entries" ("organization_id", "staff_member_id", "date", "started_at");`);
|
|
67
|
+
this.addSql(`create index "staff_time_entries_task_idx" on "staff_time_entries" ("organization_id", "task_id");`);
|
|
68
|
+
|
|
69
|
+
this.addSql(`alter table "staff_time_projects" add "customer_snapshot" jsonb null, add "hourly_rate" numeric(14,4) null, add "currency_code" text null, add "billable_by_default" boolean not null default true, add "budget_kind" text not null default 'none', add "budget_value" numeric(14,4) null, add "budget_warn_at_percent" int not null default 80, add "budget_alerted_at_percent" int null;`);
|
|
70
|
+
this.addSql(`alter table "staff_time_projects" add constraint "staff_time_projects_budget_kind_check" check ("budget_kind" in ('none', 'hours', 'amount'));`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
override down(): void | Promise<void> {
|
|
74
|
+
this.addSql(`drop table if exists "staff_time_entry_tags" cascade;`);
|
|
75
|
+
this.addSql(`drop table if exists "staff_time_report_entries" cascade;`);
|
|
76
|
+
this.addSql(`drop table if exists "staff_time_report_events" cascade;`);
|
|
77
|
+
this.addSql(`drop table if exists "staff_time_report_projects" cascade;`);
|
|
78
|
+
this.addSql(`drop table if exists "staff_time_reports" cascade;`);
|
|
79
|
+
this.addSql(`drop table if exists "staff_time_task_tags" cascade;`);
|
|
80
|
+
this.addSql(`drop table if exists "staff_time_tags" cascade;`);
|
|
81
|
+
this.addSql(`drop table if exists "staff_time_task_comments" cascade;`);
|
|
82
|
+
this.addSql(`drop table if exists "staff_time_tasks" cascade;`);
|
|
83
|
+
this.addSql(`drop table if exists "staff_time_task_statuses" cascade;`);
|
|
84
|
+
|
|
85
|
+
this.addSql(`drop index "staff_time_entries_locked_report_idx";`);
|
|
86
|
+
this.addSql(`drop index "staff_time_entries_member_overlap_idx";`);
|
|
87
|
+
this.addSql(`drop index "staff_time_entries_task_idx";`);
|
|
88
|
+
this.addSql(`alter table "staff_time_entries" drop column "task_id", drop column "is_billable", drop column "rounded_minutes", drop column "rate_override_amount", drop column "rate_currency_code", drop column "locked_report_id", drop column "locked_at";`);
|
|
89
|
+
|
|
90
|
+
this.addSql(`alter table "staff_time_projects" drop constraint if exists "staff_time_projects_budget_kind_check";`);
|
|
91
|
+
this.addSql(`alter table "staff_time_projects" drop column "customer_snapshot", drop column "hourly_rate", drop column "currency_code", drop column "billable_by_default", drop column "budget_kind", drop column "budget_value", drop column "budget_warn_at_percent", drop column "budget_alerted_at_percent";`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
|
|
3
|
+
export class Migration20260824143357_staff extends Migration {
|
|
4
|
+
|
|
5
|
+
override up(): void | Promise<void> {
|
|
6
|
+
this.addSql(`alter table "staff_time_entries" drop constraint if exists "staff_time_entries_source_check";`);
|
|
7
|
+
|
|
8
|
+
this.addSql(`alter table "staff_time_reports" drop constraint if exists "staff_time_reports_grouping_check";`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
override down(): void | Promise<void> {
|
|
12
|
+
this.addSql(`alter table "staff_time_entries" add constraint "staff_time_entries_source_check" check ("source" in ('manual', 'timer', 'kiosk', 'mobile'));`);
|
|
13
|
+
|
|
14
|
+
this.addSql(`alter table "staff_time_reports" add constraint "staff_time_reports_grouping_check" check ("grouping" in ('project_task', 'project_person', 'project_day'));`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
|
|
4
|
+
import { notificationTypes } from './notifications'
|
|
5
|
+
import { TimeProjectAccessRequestedRenderer } from './widgets/notifications/TimeProjectAccessRequestedRenderer'
|
|
6
|
+
|
|
7
|
+
const rendererMap: Record<string, NotificationTypeDefinition['Renderer']> = {
|
|
8
|
+
'staff.timesheets.project_access.requested': TimeProjectAccessRequestedRenderer,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const staffNotificationTypes: NotificationTypeDefinition[] = notificationTypes.map((type) => ({
|
|
12
|
+
...type,
|
|
13
|
+
Renderer: rendererMap[type.type],
|
|
14
|
+
}))
|
|
15
|
+
|
|
16
|
+
export default staffNotificationTypes
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { NotificationHandler } from '@open-mercato/shared/modules/notifications/handler'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* EP-48. Reactive browser handlers for the time-tracking notification types.
|
|
5
|
+
*
|
|
6
|
+
* A handler is the module's own reaction to one of its notifications arriving in
|
|
7
|
+
* the browser: it re-broadcasts on the DOM Event Bridge so an open screen can
|
|
8
|
+
* refetch, and toasts the ones a person needs to see even when the bell is
|
|
9
|
+
* collapsed. Each `id` is the override key — `notifications.handlers.<id>` — so
|
|
10
|
+
* an app can disable or replace one without patching this file.
|
|
11
|
+
*
|
|
12
|
+
* `features` is checked with the wildcard-aware policy before `handle` runs, so
|
|
13
|
+
* a handler never fires for a caller who could not open the screen it points at.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const TIME_REPORT_APPROVED_EVENT = 'om:staff:time-report-approved'
|
|
17
|
+
export const TIME_REPORT_READY_FOR_APPROVAL_EVENT = 'om:staff:time-report-ready-for-approval'
|
|
18
|
+
export const TIMER_RUNNING_LONG_EVENT = 'om:staff:timer-running-long'
|
|
19
|
+
export const TIMESHEET_PERIOD_INCOMPLETE_EVENT = 'om:staff:timesheet-period-incomplete'
|
|
20
|
+
|
|
21
|
+
export const notificationHandlers: NotificationHandler[] = [
|
|
22
|
+
{
|
|
23
|
+
id: 'staff.time-report-approved-event',
|
|
24
|
+
notificationType: 'staff.timesheets.time_report.approved',
|
|
25
|
+
features: ['staff.timesheets.reports.view'],
|
|
26
|
+
priority: 100,
|
|
27
|
+
handle(notification, context) {
|
|
28
|
+
context.emitEvent(TIME_REPORT_APPROVED_EVENT, {
|
|
29
|
+
notificationId: notification.id,
|
|
30
|
+
reportId: notification.sourceEntityId ?? null,
|
|
31
|
+
reference: notification.bodyVariables?.reference ?? null,
|
|
32
|
+
})
|
|
33
|
+
context.refreshNotifications()
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'staff.time-report-ready-for-approval-event',
|
|
38
|
+
notificationType: 'staff.timesheets.time_report.ready_for_approval',
|
|
39
|
+
features: ['staff.timesheets.reports.view'],
|
|
40
|
+
priority: 100,
|
|
41
|
+
handle(notification, context) {
|
|
42
|
+
context.emitEvent(TIME_REPORT_READY_FOR_APPROVAL_EVENT, {
|
|
43
|
+
notificationId: notification.id,
|
|
44
|
+
reportId: notification.sourceEntityId ?? null,
|
|
45
|
+
reference: notification.bodyVariables?.reference ?? null,
|
|
46
|
+
})
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
/**
|
|
51
|
+
* A running timer keeps billing until somebody stops it, so this one toasts
|
|
52
|
+
* as well as broadcasting — the bell alone is too quiet for a notification
|
|
53
|
+
* whose whole point is that the person has forgotten something.
|
|
54
|
+
*/
|
|
55
|
+
id: 'staff.timer-running-long-toast',
|
|
56
|
+
notificationType: 'staff.timesheets.time_entry.timer_running_long',
|
|
57
|
+
features: ['staff.timesheets.view'],
|
|
58
|
+
priority: 110,
|
|
59
|
+
debounceMs: 60_000,
|
|
60
|
+
handle(notification, context) {
|
|
61
|
+
context.toast({
|
|
62
|
+
title: notification.title,
|
|
63
|
+
body: notification.body ?? undefined,
|
|
64
|
+
severity: 'warning',
|
|
65
|
+
})
|
|
66
|
+
context.emitEvent(TIMER_RUNNING_LONG_EVENT, {
|
|
67
|
+
notificationId: notification.id,
|
|
68
|
+
timeEntryId: notification.sourceEntityId ?? null,
|
|
69
|
+
})
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'staff.timesheet-period-incomplete-event',
|
|
74
|
+
notificationType: 'staff.timesheets.timesheet.period_incomplete',
|
|
75
|
+
features: ['staff.timesheets.view'],
|
|
76
|
+
priority: 90,
|
|
77
|
+
handle(notification, context) {
|
|
78
|
+
context.emitEvent(TIMESHEET_PERIOD_INCOMPLETE_EVENT, {
|
|
79
|
+
notificationId: notification.id,
|
|
80
|
+
staffMemberId: notification.sourceEntityId ?? null,
|
|
81
|
+
periodFrom: notification.bodyVariables?.periodFrom ?? null,
|
|
82
|
+
periodTo: notification.bodyVariables?.periodTo ?? null,
|
|
83
|
+
})
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
export default notificationHandlers
|
|
@@ -72,6 +72,169 @@ export const notificationTypes: NotificationTypeDefinition[] = [
|
|
|
72
72
|
linkHref: '/backend/staff/leave-requests/{sourceEntityId}',
|
|
73
73
|
expiresAfterHours: 168, // 7 days
|
|
74
74
|
},
|
|
75
|
+
{
|
|
76
|
+
// Spec D-6: the "Request access" button on screens 2 and 17 raises a real
|
|
77
|
+
// notification for every `staff.timesheets.projects.manage` holder. The
|
|
78
|
+
// subscriber overrides `linkHref` with the requester-specific deep link so
|
|
79
|
+
// the project team drawer opens with the requester pre-selected.
|
|
80
|
+
type: 'staff.timesheets.project_access.requested',
|
|
81
|
+
channels: ['in_app', 'email'],
|
|
82
|
+
module: 'staff',
|
|
83
|
+
titleKey: 'staff.notifications.timeProjectAccess.requested.title',
|
|
84
|
+
bodyKey: 'staff.notifications.timeProjectAccess.requested.body',
|
|
85
|
+
icon: 'user-plus',
|
|
86
|
+
severity: 'info',
|
|
87
|
+
actions: [
|
|
88
|
+
{
|
|
89
|
+
id: 'open-team',
|
|
90
|
+
labelKey: 'staff.notifications.timeProjectAccess.actions.openTeam',
|
|
91
|
+
variant: 'default',
|
|
92
|
+
icon: 'users',
|
|
93
|
+
href: '/backend/staff/time-tracking/projects/{sourceEntityId}?panel=team',
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
primaryActionId: 'open-team',
|
|
97
|
+
linkHref: '/backend/staff/time-tracking/projects',
|
|
98
|
+
expiresAfterHours: 168, // 7 days
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
// Screen 4 budget card: "Ostrzezenie przy 80% i 100% wykorzystania". One type
|
|
102
|
+
// covers both thresholds — the subscriber raises the severity to `error` for the
|
|
103
|
+
// 100% crossing and carries the numbers in `bodyVariables`, so the two alerts
|
|
104
|
+
// read differently without splitting the notification id.
|
|
105
|
+
type: 'staff.timesheets.time_project.budget_threshold_reached',
|
|
106
|
+
channels: ['in_app', 'email'],
|
|
107
|
+
module: 'staff',
|
|
108
|
+
titleKey: 'staff.notifications.timeProjectBudget.thresholdReached.title',
|
|
109
|
+
bodyKey: 'staff.notifications.timeProjectBudget.thresholdReached.body',
|
|
110
|
+
icon: 'gauge',
|
|
111
|
+
severity: 'warning',
|
|
112
|
+
actions: [
|
|
113
|
+
{
|
|
114
|
+
id: 'open-project',
|
|
115
|
+
labelKey: 'staff.notifications.timeProjectBudget.actions.openProject',
|
|
116
|
+
variant: 'default',
|
|
117
|
+
icon: 'external-link',
|
|
118
|
+
href: '/backend/staff/time-tracking/projects/{sourceEntityId}',
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
primaryActionId: 'open-project',
|
|
122
|
+
linkHref: '/backend/staff/time-tracking/projects/{sourceEntityId}',
|
|
123
|
+
expiresAfterHours: 168, // 7 days
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
/**
|
|
127
|
+
* EP-48. Raised by `subscribers/time-report-approved-notification.ts` when a
|
|
128
|
+
* report is closed — closing IS the approval in this module: it freezes every
|
|
129
|
+
* per-entry value and locks the entries, and `staff.timesheets.lock` is the
|
|
130
|
+
* feature that gates it. The recipient is the person who drafted the report,
|
|
131
|
+
* who otherwise learns about it only by reopening the screen.
|
|
132
|
+
*/
|
|
133
|
+
type: 'staff.timesheets.time_report.approved',
|
|
134
|
+
channels: ['in_app', 'email'],
|
|
135
|
+
module: 'staff',
|
|
136
|
+
titleKey: 'staff.notifications.timeReport.approved.title',
|
|
137
|
+
bodyKey: 'staff.notifications.timeReport.approved.body',
|
|
138
|
+
icon: 'file-check',
|
|
139
|
+
severity: 'success',
|
|
140
|
+
actions: [
|
|
141
|
+
{
|
|
142
|
+
id: 'open-report',
|
|
143
|
+
labelKey: 'staff.notifications.timeReport.actions.openReport',
|
|
144
|
+
variant: 'default',
|
|
145
|
+
icon: 'external-link',
|
|
146
|
+
href: '/backend/staff/time-tracking/reports/{sourceEntityId}',
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
primaryActionId: 'open-report',
|
|
150
|
+
linkHref: '/backend/staff/time-tracking/reports/{sourceEntityId}',
|
|
151
|
+
expiresAfterHours: 168, // 7 days
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
/**
|
|
155
|
+
* EP-48, contributable-only by design. The module has exactly one report
|
|
156
|
+
* transition — draft → closed — so there is no "submitted, awaiting a second
|
|
157
|
+
* pair of eyes" state for core to announce. This id exists so the multi-step
|
|
158
|
+
* approval a `registerReportApprovalPolicy` contribution (EP-41) implements
|
|
159
|
+
* has a published notification to raise instead of inventing its own, and so
|
|
160
|
+
* the renderer and delivery preferences are already in place when it does.
|
|
161
|
+
*/
|
|
162
|
+
type: 'staff.timesheets.time_report.ready_for_approval',
|
|
163
|
+
channels: ['in_app', 'email'],
|
|
164
|
+
module: 'staff',
|
|
165
|
+
titleKey: 'staff.notifications.timeReport.readyForApproval.title',
|
|
166
|
+
bodyKey: 'staff.notifications.timeReport.readyForApproval.body',
|
|
167
|
+
icon: 'file-clock',
|
|
168
|
+
severity: 'info',
|
|
169
|
+
actions: [
|
|
170
|
+
{
|
|
171
|
+
id: 'review-report',
|
|
172
|
+
labelKey: 'staff.notifications.timeReport.actions.reviewReport',
|
|
173
|
+
variant: 'default',
|
|
174
|
+
icon: 'external-link',
|
|
175
|
+
href: '/backend/staff/time-tracking/reports/{sourceEntityId}',
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
primaryActionId: 'review-report',
|
|
179
|
+
linkHref: '/backend/staff/time-tracking/reports/{sourceEntityId}',
|
|
180
|
+
expiresAfterHours: 168, // 7 days
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
/**
|
|
184
|
+
* EP-48, contributable-only by design. "This timer has been running for six
|
|
185
|
+
* hours" needs something that wakes up on a schedule and looks at open
|
|
186
|
+
* timers; the module ships no periodic job and inventing one to justify an id
|
|
187
|
+
* would be the tail wagging the dog. The id is the contract for a module that
|
|
188
|
+
* does ship one.
|
|
189
|
+
*/
|
|
190
|
+
type: 'staff.timesheets.time_entry.timer_running_long',
|
|
191
|
+
channels: ['in_app'],
|
|
192
|
+
module: 'staff',
|
|
193
|
+
titleKey: 'staff.notifications.timeEntryTimer.runningLong.title',
|
|
194
|
+
bodyKey: 'staff.notifications.timeEntryTimer.runningLong.body',
|
|
195
|
+
icon: 'timer',
|
|
196
|
+
severity: 'warning',
|
|
197
|
+
actions: [
|
|
198
|
+
{
|
|
199
|
+
id: 'open-timesheet',
|
|
200
|
+
labelKey: 'staff.notifications.timesheet.actions.openTimesheet',
|
|
201
|
+
variant: 'default',
|
|
202
|
+
icon: 'external-link',
|
|
203
|
+
href: '/backend/staff/time-tracking/timesheet',
|
|
204
|
+
},
|
|
205
|
+
],
|
|
206
|
+
primaryActionId: 'open-timesheet',
|
|
207
|
+
linkHref: '/backend/staff/time-tracking/timesheet',
|
|
208
|
+
expiresAfterHours: 24,
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
/**
|
|
212
|
+
* EP-48, contributable-only by design. Whether a period is "incomplete" is
|
|
213
|
+
* the capacity provider's question (EP-40), and the built-in provider spreads
|
|
214
|
+
* one flat daily number over the caller's working days on demand — it has no
|
|
215
|
+
* schedule and no opinion about when to complain. A contributed provider that
|
|
216
|
+
* knows contract hours and leave is the thing that can raise this honestly.
|
|
217
|
+
*/
|
|
218
|
+
type: 'staff.timesheets.timesheet.period_incomplete',
|
|
219
|
+
channels: ['in_app', 'email'],
|
|
220
|
+
module: 'staff',
|
|
221
|
+
titleKey: 'staff.notifications.timesheet.periodIncomplete.title',
|
|
222
|
+
bodyKey: 'staff.notifications.timesheet.periodIncomplete.body',
|
|
223
|
+
icon: 'calendar-clock',
|
|
224
|
+
severity: 'warning',
|
|
225
|
+
actions: [
|
|
226
|
+
{
|
|
227
|
+
id: 'open-timesheet',
|
|
228
|
+
labelKey: 'staff.notifications.timesheet.actions.openTimesheet',
|
|
229
|
+
variant: 'default',
|
|
230
|
+
icon: 'external-link',
|
|
231
|
+
href: '/backend/staff/time-tracking/timesheet',
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
primaryActionId: 'open-timesheet',
|
|
235
|
+
linkHref: '/backend/staff/time-tracking/timesheet',
|
|
236
|
+
expiresAfterHours: 168, // 7 days
|
|
237
|
+
},
|
|
75
238
|
]
|
|
76
239
|
|
|
77
240
|
export default notificationTypes
|
|
@@ -118,6 +118,74 @@ function buildIndexSource(
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* EP-46. The four time-tracking entities below join `staff:staff_time_project`
|
|
123
|
+
* in the index, and every one of them carries a gate that is deliberately
|
|
124
|
+
* stricter than the feature its REST route declares.
|
|
125
|
+
*
|
|
126
|
+
* The reason is a property of the search layer, not of this module: an entity's
|
|
127
|
+
* `aclFeatures` is the ONLY authorization the search pipeline applies. It is
|
|
128
|
+
* enforced twice per query — `resolveReadableEntityTypes` narrows the entity
|
|
129
|
+
* list before the query and `filterSearchResultsByEntityAccess` filters the
|
|
130
|
+
* results after it — but both decide **per entity type**, never per record.
|
|
131
|
+
* `SearchEntityConfig` has no row-level hook and `SearchOptions` has no record-id
|
|
132
|
+
* allowlist, so a search gate cannot reproduce the per-project membership
|
|
133
|
+
* intersection that `resolveProjectAccess` applies on every time-tracking route.
|
|
134
|
+
*
|
|
135
|
+
* So each gate below names the feature set whose holder already sees **every**
|
|
136
|
+
* record of that entity through the API. `staff.timesheets.projects.manage` is
|
|
137
|
+
* that feature for entries, tasks and reports: it is what makes
|
|
138
|
+
* `resolveProjectAccess` answer `canManageAll: true`, which is the only state in
|
|
139
|
+
* which those routes stop intersecting with the caller's project membership.
|
|
140
|
+
* A project member without it gets no hits at all rather than hits for projects
|
|
141
|
+
* they cannot open — the failure mode that costs a support ticket, not the one
|
|
142
|
+
* that discloses a client's work.
|
|
143
|
+
*/
|
|
144
|
+
const UNRESTRICTED_PROJECT_ACCESS_FEATURE = 'staff.timesheets.projects.manage'
|
|
145
|
+
|
|
146
|
+
function buildTimeTaskPresenter(t: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
|
|
147
|
+
const title =
|
|
148
|
+
pickString(record.title, record.reference) ?? (record.id as string | undefined) ?? t('staff.search.badge.timeTask', 'Task')
|
|
149
|
+
return {
|
|
150
|
+
title: String(title),
|
|
151
|
+
subtitle: formatSubtitle(record.reference, snippet(record.description, 80)),
|
|
152
|
+
icon: 'list-checks',
|
|
153
|
+
badge: t('staff.search.badge.timeTask', 'Task'),
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function buildTimeReportPresenter(t: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
|
|
158
|
+
const title =
|
|
159
|
+
pickString(record.title, record.reference) ?? (record.id as string | undefined) ?? t('staff.search.badge.timeReport', 'Report')
|
|
160
|
+
return {
|
|
161
|
+
title: String(title),
|
|
162
|
+
subtitle: formatSubtitle(record.reference, record.period_from ?? record.periodFrom, record.period_to ?? record.periodTo),
|
|
163
|
+
icon: 'file-text',
|
|
164
|
+
badge: t('staff.search.badge.timeReport', 'Report'),
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function buildTimeTagPresenter(t: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
|
|
169
|
+
const title =
|
|
170
|
+
pickString(record.label, record.slug) ?? (record.id as string | undefined) ?? t('staff.search.badge.timeTag', 'Tag')
|
|
171
|
+
return {
|
|
172
|
+
title: String(title),
|
|
173
|
+
subtitle: formatSubtitle(record.slug),
|
|
174
|
+
icon: 'tag',
|
|
175
|
+
badge: t('staff.search.badge.timeTag', 'Tag'),
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function buildTimeEntryPresenter(t: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
|
|
180
|
+
const title = snippet(record.notes, 80) ?? t('staff.search.badge.timeEntry', 'Time entry')
|
|
181
|
+
return {
|
|
182
|
+
title,
|
|
183
|
+
subtitle: formatSubtitle(record.date, record.duration_minutes ?? record.durationMinutes),
|
|
184
|
+
icon: 'timer',
|
|
185
|
+
badge: t('staff.search.badge.timeEntry', 'Time entry'),
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
121
189
|
export const searchConfig: SearchModuleConfig = {
|
|
122
190
|
entities: [
|
|
123
191
|
{
|
|
@@ -222,11 +290,133 @@ export const searchConfig: SearchModuleConfig = {
|
|
|
222
290
|
badge: t('staff.search.badge.timeProject', 'Project'),
|
|
223
291
|
}
|
|
224
292
|
},
|
|
225
|
-
resolveUrl: async (ctx) => `/backend/staff/
|
|
293
|
+
resolveUrl: async (ctx) => `/backend/staff/time-tracking/projects/${encodeURIComponent(String(ctx.record.id))}`,
|
|
226
294
|
fieldPolicy: {
|
|
227
295
|
searchable: ['name', 'code', 'description', 'project_type', 'cost_center'],
|
|
228
296
|
},
|
|
229
297
|
},
|
|
298
|
+
{
|
|
299
|
+
entityId: 'staff:staff_time_task',
|
|
300
|
+
aclFeatures: ['staff.timesheets.tasks.view', UNRESTRICTED_PROJECT_ACCESS_FEATURE],
|
|
301
|
+
enabled: true,
|
|
302
|
+
priority: 7,
|
|
303
|
+
buildSource: async (ctx) => {
|
|
304
|
+
const { t } = await resolveTranslations()
|
|
305
|
+
const record = ctx.record
|
|
306
|
+
const lines: string[] = []
|
|
307
|
+
appendLine(lines, 'Reference', record.reference)
|
|
308
|
+
appendLine(lines, 'Title', record.title)
|
|
309
|
+
appendLine(lines, 'Description', record.description)
|
|
310
|
+
return buildIndexSource(ctx, buildTimeTaskPresenter(t, record), lines)
|
|
311
|
+
},
|
|
312
|
+
formatResult: async (ctx) => {
|
|
313
|
+
const { t } = await resolveTranslations()
|
|
314
|
+
return buildTimeTaskPresenter(t, ctx.record)
|
|
315
|
+
},
|
|
316
|
+
resolveUrl: async (ctx) => {
|
|
317
|
+
const projectId = pickString(ctx.record.time_project_id, ctx.record.timeProjectId)
|
|
318
|
+
if (!projectId) return null
|
|
319
|
+
return `/backend/staff/time-tracking/board?projectId=${encodeURIComponent(projectId)}&task=${encodeURIComponent(String(ctx.record.id))}`
|
|
320
|
+
},
|
|
321
|
+
fieldPolicy: {
|
|
322
|
+
searchable: ['title', 'description', 'reference'],
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
entityId: 'staff:staff_time_report',
|
|
327
|
+
aclFeatures: ['staff.timesheets.reports.view', UNRESTRICTED_PROJECT_ACCESS_FEATURE],
|
|
328
|
+
enabled: true,
|
|
329
|
+
priority: 7,
|
|
330
|
+
buildSource: async (ctx) => {
|
|
331
|
+
const { t } = await resolveTranslations()
|
|
332
|
+
const record = ctx.record
|
|
333
|
+
const lines: string[] = []
|
|
334
|
+
appendLine(lines, 'Reference', record.reference)
|
|
335
|
+
appendLine(lines, 'Title', record.title)
|
|
336
|
+
appendLine(lines, 'Status', record.status)
|
|
337
|
+
return buildIndexSource(ctx, buildTimeReportPresenter(t, record), lines)
|
|
338
|
+
},
|
|
339
|
+
formatResult: async (ctx) => {
|
|
340
|
+
const { t } = await resolveTranslations()
|
|
341
|
+
return buildTimeReportPresenter(t, ctx.record)
|
|
342
|
+
},
|
|
343
|
+
resolveUrl: async (ctx) => `/backend/staff/time-tracking/reports/${encodeURIComponent(String(ctx.record.id))}`,
|
|
344
|
+
/**
|
|
345
|
+
* `total_amount` and the denormalised `customer_snapshot` are excluded, not
|
|
346
|
+
* merely left out of `searchable`: money in a time-tracking response is
|
|
347
|
+
* gated on `staff.timesheets.rates.view`, and the search pipeline has no way
|
|
348
|
+
* to apply a second feature to a subset of an indexed record's fields.
|
|
349
|
+
*/
|
|
350
|
+
fieldPolicy: {
|
|
351
|
+
searchable: ['reference', 'title'],
|
|
352
|
+
excluded: ['total_amount', 'customer_snapshot'],
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
entityId: 'staff:staff_time_tag',
|
|
357
|
+
aclFeatures: ['staff.timesheets.view'],
|
|
358
|
+
enabled: true,
|
|
359
|
+
priority: 5,
|
|
360
|
+
buildSource: async (ctx) => {
|
|
361
|
+
const { t } = await resolveTranslations()
|
|
362
|
+
const record = ctx.record
|
|
363
|
+
const lines: string[] = []
|
|
364
|
+
appendLine(lines, 'Label', record.label)
|
|
365
|
+
appendLine(lines, 'Slug', record.slug)
|
|
366
|
+
return buildIndexSource(ctx, buildTimeTagPresenter(t, record), lines)
|
|
367
|
+
},
|
|
368
|
+
formatResult: async (ctx) => {
|
|
369
|
+
const { t } = await resolveTranslations()
|
|
370
|
+
return buildTimeTagPresenter(t, ctx.record)
|
|
371
|
+
},
|
|
372
|
+
/**
|
|
373
|
+
* A tag has no detail screen and the entries list deep-links only `taskId`
|
|
374
|
+
* and `ids`, so there is no honest destination to send the caller to. The
|
|
375
|
+
* presenter still answers the question a tag search asks — "does this label
|
|
376
|
+
* exist, and what is it spelled" — and `url` is optional in the result
|
|
377
|
+
* contract, so an unlinked hit renders rather than pointing somewhere wrong.
|
|
378
|
+
*/
|
|
379
|
+
resolveUrl: async () => null,
|
|
380
|
+
fieldPolicy: {
|
|
381
|
+
searchable: ['label', 'slug'],
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
/**
|
|
386
|
+
* Entry notes are the most sensitive text time tracking holds — they are
|
|
387
|
+
* where a consultant writes what they did for a named client. The gate is
|
|
388
|
+
* therefore the strictest one the module has for entries: `staff.timesheets.view`
|
|
389
|
+
* AND `staff.timesheets.projects.manage`, the pair that makes
|
|
390
|
+
* `resolveProjectAccess` return `canManageAll`, which is the only state in
|
|
391
|
+
* which `/api/staff/timesheets/time-entries` stops narrowing to the caller's
|
|
392
|
+
* own entries plus their project memberships. A consultant with
|
|
393
|
+
* `staff.timesheets.manage_own` gets no entry hits at all — including their
|
|
394
|
+
* own — because the gate cannot express "own" and half a gate is worse than
|
|
395
|
+
* none.
|
|
396
|
+
*/
|
|
397
|
+
entityId: 'staff:staff_time_entry',
|
|
398
|
+
aclFeatures: ['staff.timesheets.view', UNRESTRICTED_PROJECT_ACCESS_FEATURE],
|
|
399
|
+
enabled: true,
|
|
400
|
+
priority: 4,
|
|
401
|
+
buildSource: async (ctx) => {
|
|
402
|
+
const { t } = await resolveTranslations()
|
|
403
|
+
const record = ctx.record
|
|
404
|
+
const lines: string[] = []
|
|
405
|
+
appendLine(lines, 'Notes', record.notes)
|
|
406
|
+
appendLine(lines, 'Date', record.date)
|
|
407
|
+
return buildIndexSource(ctx, buildTimeEntryPresenter(t, record), lines)
|
|
408
|
+
},
|
|
409
|
+
formatResult: async (ctx) => {
|
|
410
|
+
const { t } = await resolveTranslations()
|
|
411
|
+
return buildTimeEntryPresenter(t, ctx.record)
|
|
412
|
+
},
|
|
413
|
+
resolveUrl: async (ctx) =>
|
|
414
|
+
`/backend/staff/time-tracking/entries?ids=${encodeURIComponent(String(ctx.record.id))}`,
|
|
415
|
+
fieldPolicy: {
|
|
416
|
+
searchable: ['notes'],
|
|
417
|
+
excluded: ['rate_override_amount', 'rate_currency_code'],
|
|
418
|
+
},
|
|
419
|
+
},
|
|
230
420
|
],
|
|
231
421
|
}
|
|
232
422
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ModuleSetupConfig } from '@open-mercato/shared/modules/setup'
|
|
2
2
|
import { appendWidgetsToRoles } from '@open-mercato/core/modules/dashboards/lib/role-widgets'
|
|
3
3
|
import { seedStaffAddressTypes, seedStaffTeamExamples } from './lib/seeds'
|
|
4
|
+
import { seedStaffTimeTrackingExamples } from './lib/timeTrackingSeeds'
|
|
4
5
|
|
|
5
6
|
const TIMESHEETS_DASHBOARD_WIDGET_IDS = [
|
|
6
7
|
'staff.timesheets.timeReporting',
|
|
@@ -22,6 +23,9 @@ export const setup: ModuleSetupConfig = {
|
|
|
22
23
|
seedExamples: async (ctx) => {
|
|
23
24
|
const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId }
|
|
24
25
|
await seedStaffTeamExamples(ctx.em, scope)
|
|
26
|
+
// Runs after the team examples because every project it staffs, every task it
|
|
27
|
+
// assigns and every hour it logs points at a staff member those seeds create.
|
|
28
|
+
await seedStaffTimeTrackingExamples(ctx.em, scope)
|
|
25
29
|
},
|
|
26
30
|
|
|
27
31
|
defaultRoleFeatures: {
|
|
@@ -35,8 +39,26 @@ export const setup: ModuleSetupConfig = {
|
|
|
35
39
|
'staff.timesheets.view',
|
|
36
40
|
'staff.timesheets.manage_own',
|
|
37
41
|
'staff.timesheets.projects.view',
|
|
42
|
+
'staff.timesheets.tasks.view',
|
|
43
|
+
'staff.timesheets.tasks.manage',
|
|
44
|
+
'staff.timesheets.rates.view',
|
|
38
45
|
],
|
|
39
46
|
},
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* EP-50. `portal.time_reports.view` is a **customer** feature, granted through
|
|
50
|
+
* `CustomerRoleAcl`, and it is deliberately absent from `acl.ts` — that file is
|
|
51
|
+
* the staff feature catalog and the two namespaces are graded by different RBAC
|
|
52
|
+
* services.
|
|
53
|
+
*
|
|
54
|
+
* `viewer` gets it as well as `buyer`: reading the hours already delivered is a
|
|
55
|
+
* read, and a client who may see their invoices may see what they paid for.
|
|
56
|
+
* `portal_admin` holds `portal.*` and needs no entry.
|
|
57
|
+
*/
|
|
58
|
+
defaultCustomerRoleFeatures: {
|
|
59
|
+
buyer: ['portal.time_reports.view'],
|
|
60
|
+
viewer: ['portal.time_reports.view'],
|
|
61
|
+
},
|
|
40
62
|
}
|
|
41
63
|
|
|
42
64
|
export default setup
|