@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,142 @@
|
|
|
1
|
+
const AGENT_ID = "staff.time_tracking_assistant";
|
|
2
|
+
const MODULE_ID = "staff";
|
|
3
|
+
const ALLOWED_TOOLS = [
|
|
4
|
+
"staff.summarize_week",
|
|
5
|
+
"staff.find_missing_days",
|
|
6
|
+
"staff.draft_client_report",
|
|
7
|
+
"staff.log_time",
|
|
8
|
+
"staff.start_timer",
|
|
9
|
+
"staff.stop_timer",
|
|
10
|
+
"meta.describe_agent"
|
|
11
|
+
];
|
|
12
|
+
const REQUIRED_FEATURES = ["staff.timesheets.view"];
|
|
13
|
+
const PROMPT_SECTIONS = [
|
|
14
|
+
{
|
|
15
|
+
name: "role",
|
|
16
|
+
order: 1,
|
|
17
|
+
content: [
|
|
18
|
+
"ROLE",
|
|
19
|
+
"You are the Time Tracking Assistant inside Open Mercato. You help one person",
|
|
20
|
+
"keep their own timesheet honest: logging work they did, starting and stopping",
|
|
21
|
+
"timers, summarizing what they logged, and spotting days they missed."
|
|
22
|
+
].join("\n")
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "scope",
|
|
26
|
+
order: 2,
|
|
27
|
+
content: [
|
|
28
|
+
"SCOPE",
|
|
29
|
+
"You act as the signed-in user and nobody else. No tool accepts another",
|
|
30
|
+
"person's staff member id, and you must never offer to log time for a",
|
|
31
|
+
"colleague \u2014 that is a backoffice action on /backend/staff/time-tracking.",
|
|
32
|
+
"Respect tenant and organization isolation; the tools enforce it, do not try",
|
|
33
|
+
"to work around a refusal.",
|
|
34
|
+
'Act, do not interrogate. "How did my week go?" is a call to',
|
|
35
|
+
"staff.summarize_week with the current week, not a request for clarification."
|
|
36
|
+
].join("\n")
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "data",
|
|
40
|
+
order: 3,
|
|
41
|
+
content: [
|
|
42
|
+
"DATA",
|
|
43
|
+
"You can read the signed-in user's time entries and preview a customer",
|
|
44
|
+
"report over projects they can already see. All durations are MINUTES.",
|
|
45
|
+
"You never see rates, costs or amounts: they are gated on a feature this",
|
|
46
|
+
"agent does not carry, and staff.draft_client_report deliberately asks for a",
|
|
47
|
+
"preview without them. If the operator asks what something is worth, say the",
|
|
48
|
+
"figures are on the report screen and give the hours instead.",
|
|
49
|
+
"Never invent a project id, a task id or a time entry id. Use only ids a",
|
|
50
|
+
"previous tool call returned."
|
|
51
|
+
].join("\n")
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "tools",
|
|
55
|
+
order: 4,
|
|
56
|
+
content: [
|
|
57
|
+
"TOOLS",
|
|
58
|
+
"- staff.summarize_week \u2014 totals per day and per project for a date range.",
|
|
59
|
+
"- staff.find_missing_days \u2014 days in a range with no logged time.",
|
|
60
|
+
"- staff.draft_client_report \u2014 what a customer report would contain, without",
|
|
61
|
+
" creating one. Nothing is written and nothing is locked.",
|
|
62
|
+
"- staff.log_time \u2014 create one time entry.",
|
|
63
|
+
"- staff.start_timer / staff.stop_timer \u2014 begin and end a running timer.",
|
|
64
|
+
"Prefer the narrowest tool. If a read returns nothing after two different",
|
|
65
|
+
"ranges, say what you looked for and stop."
|
|
66
|
+
].join("\n")
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "attachments",
|
|
70
|
+
order: 5,
|
|
71
|
+
content: [
|
|
72
|
+
"ATTACHMENTS",
|
|
73
|
+
"This agent takes no attachments. If the operator attaches a file, say you",
|
|
74
|
+
"cannot read it here and point at the time-tracking screens."
|
|
75
|
+
].join("\n")
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "mutationPolicy",
|
|
79
|
+
order: 6,
|
|
80
|
+
content: [
|
|
81
|
+
"MUTATION POLICY",
|
|
82
|
+
"staff.log_time, staff.start_timer and staff.stop_timer are mutations. The",
|
|
83
|
+
"runtime short-circuits each call into an approval card; the write happens",
|
|
84
|
+
"only after the operator confirms it. Do NOT say the time was logged until a",
|
|
85
|
+
"mutation-result-card comes back \u2014 say you have prepared it for confirmation.",
|
|
86
|
+
"Never batch several days into one call hoping they slip through as one",
|
|
87
|
+
"approval; log one entry per call so each is reviewable.",
|
|
88
|
+
"If a per-tenant override has downgraded this agent to read-only, the runtime",
|
|
89
|
+
"refuses the call: tell the operator writes are locked for this tenant and",
|
|
90
|
+
"point at /backend/staff/time-tracking/timesheet."
|
|
91
|
+
].join("\n")
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "responseStyle",
|
|
95
|
+
order: 7,
|
|
96
|
+
content: [
|
|
97
|
+
"RESPONSE STYLE",
|
|
98
|
+
'Answer in hours and minutes, not raw minute counts: 450 minutes is "7h 30m".',
|
|
99
|
+
"Lead with the number the operator asked for, then the breakdown.",
|
|
100
|
+
"When you report missing days, list the dates plainly and offer to log them \u2014",
|
|
101
|
+
"one entry per confirmation.",
|
|
102
|
+
"Keep it short. A timesheet answer is two or three sentences plus a list."
|
|
103
|
+
].join("\n")
|
|
104
|
+
}
|
|
105
|
+
];
|
|
106
|
+
function compilePromptTemplate(template) {
|
|
107
|
+
return template.sections.slice().sort((left, right) => left.order - right.order).map((section) => section.content.trim()).join("\n\n");
|
|
108
|
+
}
|
|
109
|
+
const promptTemplate = {
|
|
110
|
+
id: `${AGENT_ID}.prompt`,
|
|
111
|
+
sections: PROMPT_SECTIONS
|
|
112
|
+
};
|
|
113
|
+
const agent = {
|
|
114
|
+
id: AGENT_ID,
|
|
115
|
+
moduleId: MODULE_ID,
|
|
116
|
+
label: "Time Tracking Assistant",
|
|
117
|
+
description: "Logs your time, runs your timer, summarizes what you logged and finds the days you missed. Every write goes through the approval card.",
|
|
118
|
+
systemPrompt: compilePromptTemplate(promptTemplate),
|
|
119
|
+
allowedTools: [...ALLOWED_TOOLS],
|
|
120
|
+
executionMode: "chat",
|
|
121
|
+
requiredFeatures: [...REQUIRED_FEATURES],
|
|
122
|
+
readOnly: false,
|
|
123
|
+
mutationPolicy: "confirm-required",
|
|
124
|
+
keywords: ["time tracking", "timesheet", "timer", "hours", "timesheets"],
|
|
125
|
+
domain: "staff",
|
|
126
|
+
dataCapabilities: {
|
|
127
|
+
entities: ["staff.staff_time_entry", "staff.staff_time_project", "staff.staff_time_report"],
|
|
128
|
+
operations: ["read"]
|
|
129
|
+
},
|
|
130
|
+
suggestions: [
|
|
131
|
+
{ label: "Summarize my week", prompt: "Summarize the hours I logged this week, per project." },
|
|
132
|
+
{ label: "Find missing days", prompt: "Which working days this month have no time logged?" }
|
|
133
|
+
]
|
|
134
|
+
};
|
|
135
|
+
const aiAgents = [agent];
|
|
136
|
+
var ai_agents_default = aiAgents;
|
|
137
|
+
export {
|
|
138
|
+
aiAgents,
|
|
139
|
+
ai_agents_default as default,
|
|
140
|
+
promptTemplate
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=ai-agents.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/staff/ai-agents.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * EP-49 \u2014 `staff.time_tracking_assistant`.\n *\n * A write-capable chat agent over the time-tracking tool pack. Its whole reason\n * to exist is the sentence \"log yesterday afternoon on the Acme migration\" \u2014\n * which is a mutation, so the agent ships `mutationPolicy: 'confirm-required'`\n * and every write surfaces as an approval card before it persists. A per-tenant\n * override can downgrade it to `read-only`, in which case the runtime filters the\n * three write tools out before the model ever sees them.\n *\n * `requiredFeatures` is the read floor. Each individual tool re-declares its own\n * `staff.timesheets.*` gate, and the API operation runner refuses a route whose\n * required features the tool does not carry, so a viewer who reaches the agent\n * still cannot reach `staff.log_time`.\n *\n * The prompt is a structured `PromptTemplate` with the seven named sections the\n * override system addresses by name.\n */\nimport type { AiAgentDefinition } from '@open-mercato/ai-assistant/modules/ai_assistant/lib/ai-agent-definition'\n\ntype PromptSectionName =\n | 'role'\n | 'scope'\n | 'data'\n | 'tools'\n | 'attachments'\n | 'mutationPolicy'\n | 'responseStyle'\n\ninterface PromptSection {\n name: PromptSectionName\n content: string\n order: number\n}\n\ninterface PromptTemplate {\n id: string\n sections: PromptSection[]\n}\n\nconst AGENT_ID = 'staff.time_tracking_assistant'\nconst MODULE_ID = 'staff'\n\nconst ALLOWED_TOOLS: readonly string[] = [\n 'staff.summarize_week',\n 'staff.find_missing_days',\n 'staff.draft_client_report',\n 'staff.log_time',\n 'staff.start_timer',\n 'staff.stop_timer',\n 'meta.describe_agent',\n]\n\nconst REQUIRED_FEATURES: readonly string[] = ['staff.timesheets.view']\n\nconst PROMPT_SECTIONS: PromptSection[] = [\n {\n name: 'role',\n order: 1,\n content: [\n 'ROLE',\n 'You are the Time Tracking Assistant inside Open Mercato. You help one person',\n 'keep their own timesheet honest: logging work they did, starting and stopping',\n 'timers, summarizing what they logged, and spotting days they missed.',\n ].join('\\n'),\n },\n {\n name: 'scope',\n order: 2,\n content: [\n 'SCOPE',\n 'You act as the signed-in user and nobody else. No tool accepts another',\n \"person's staff member id, and you must never offer to log time for a\",\n 'colleague \u2014 that is a backoffice action on /backend/staff/time-tracking.',\n 'Respect tenant and organization isolation; the tools enforce it, do not try',\n 'to work around a refusal.',\n 'Act, do not interrogate. \"How did my week go?\" is a call to',\n 'staff.summarize_week with the current week, not a request for clarification.',\n ].join('\\n'),\n },\n {\n name: 'data',\n order: 3,\n content: [\n 'DATA',\n 'You can read the signed-in user\\'s time entries and preview a customer',\n 'report over projects they can already see. All durations are MINUTES.',\n 'You never see rates, costs or amounts: they are gated on a feature this',\n 'agent does not carry, and staff.draft_client_report deliberately asks for a',\n 'preview without them. If the operator asks what something is worth, say the',\n 'figures are on the report screen and give the hours instead.',\n 'Never invent a project id, a task id or a time entry id. Use only ids a',\n 'previous tool call returned.',\n ].join('\\n'),\n },\n {\n name: 'tools',\n order: 4,\n content: [\n 'TOOLS',\n '- staff.summarize_week \u2014 totals per day and per project for a date range.',\n '- staff.find_missing_days \u2014 days in a range with no logged time.',\n '- staff.draft_client_report \u2014 what a customer report would contain, without',\n ' creating one. Nothing is written and nothing is locked.',\n '- staff.log_time \u2014 create one time entry.',\n '- staff.start_timer / staff.stop_timer \u2014 begin and end a running timer.',\n 'Prefer the narrowest tool. If a read returns nothing after two different',\n 'ranges, say what you looked for and stop.',\n ].join('\\n'),\n },\n {\n name: 'attachments',\n order: 5,\n content: [\n 'ATTACHMENTS',\n 'This agent takes no attachments. If the operator attaches a file, say you',\n 'cannot read it here and point at the time-tracking screens.',\n ].join('\\n'),\n },\n {\n name: 'mutationPolicy',\n order: 6,\n content: [\n 'MUTATION POLICY',\n 'staff.log_time, staff.start_timer and staff.stop_timer are mutations. The',\n 'runtime short-circuits each call into an approval card; the write happens',\n 'only after the operator confirms it. Do NOT say the time was logged until a',\n 'mutation-result-card comes back \u2014 say you have prepared it for confirmation.',\n 'Never batch several days into one call hoping they slip through as one',\n 'approval; log one entry per call so each is reviewable.',\n 'If a per-tenant override has downgraded this agent to read-only, the runtime',\n 'refuses the call: tell the operator writes are locked for this tenant and',\n 'point at /backend/staff/time-tracking/timesheet.',\n ].join('\\n'),\n },\n {\n name: 'responseStyle',\n order: 7,\n content: [\n 'RESPONSE STYLE',\n 'Answer in hours and minutes, not raw minute counts: 450 minutes is \"7h 30m\".',\n 'Lead with the number the operator asked for, then the breakdown.',\n 'When you report missing days, list the dates plainly and offer to log them \u2014',\n 'one entry per confirmation.',\n 'Keep it short. A timesheet answer is two or three sentences plus a list.',\n ].join('\\n'),\n },\n]\n\nfunction compilePromptTemplate(template: PromptTemplate): string {\n return template.sections\n .slice()\n .sort((left, right) => left.order - right.order)\n .map((section) => section.content.trim())\n .join('\\n\\n')\n}\n\nexport const promptTemplate: PromptTemplate = {\n id: `${AGENT_ID}.prompt`,\n sections: PROMPT_SECTIONS,\n}\n\nconst agent: AiAgentDefinition = {\n id: AGENT_ID,\n moduleId: MODULE_ID,\n label: 'Time Tracking Assistant',\n description:\n 'Logs your time, runs your timer, summarizes what you logged and finds the days you missed. Every write goes through the approval card.',\n systemPrompt: compilePromptTemplate(promptTemplate),\n allowedTools: [...ALLOWED_TOOLS],\n executionMode: 'chat',\n requiredFeatures: [...REQUIRED_FEATURES],\n readOnly: false,\n mutationPolicy: 'confirm-required',\n keywords: ['time tracking', 'timesheet', 'timer', 'hours', 'timesheets'],\n domain: 'staff',\n dataCapabilities: {\n entities: ['staff.staff_time_entry', 'staff.staff_time_project', 'staff.staff_time_report'],\n operations: ['read'],\n },\n suggestions: [\n { label: 'Summarize my week', prompt: 'Summarize the hours I logged this week, per project.' },\n { label: 'Find missing days', prompt: 'Which working days this month have no time logged?' },\n ],\n}\n\nexport const aiAgents: AiAgentDefinition[] = [agent]\n\nexport default aiAgents\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { defineApiBackedAiTool } from "@open-mercato/ai-assistant/modules/ai_assistant/lib/api-backed-tool";
|
|
3
|
+
import {
|
|
4
|
+
assertTenantScope,
|
|
5
|
+
enumerateDates,
|
|
6
|
+
isWeekend,
|
|
7
|
+
resolveStaffToolScope,
|
|
8
|
+
toIsoDate,
|
|
9
|
+
toMinutes
|
|
10
|
+
} from "./types.js";
|
|
11
|
+
const VIEW_FEATURE = "staff.timesheets.view";
|
|
12
|
+
const MANAGE_OWN_FEATURE = "staff.timesheets.manage_own";
|
|
13
|
+
const REPORTS_VIEW_FEATURE = "staff.timesheets.reports.view";
|
|
14
|
+
const isoDate = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Use a yyyy-mm-dd calendar date.");
|
|
15
|
+
function readDate(row) {
|
|
16
|
+
return toIsoDate(row.date);
|
|
17
|
+
}
|
|
18
|
+
function readMinutes(row) {
|
|
19
|
+
const rounded = toMinutes(row.roundedMinutes);
|
|
20
|
+
if (rounded > 0) return rounded;
|
|
21
|
+
return toMinutes(row.durationMinutes ?? row.duration_minutes);
|
|
22
|
+
}
|
|
23
|
+
function readProjectId(row) {
|
|
24
|
+
const value = row.timeProjectId ?? row.time_project_id;
|
|
25
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
26
|
+
}
|
|
27
|
+
const logTimeInput = z.object({
|
|
28
|
+
date: isoDate.describe("The calendar day the work happened, as yyyy-mm-dd."),
|
|
29
|
+
durationMinutes: z.number().int().min(1).max(1440).describe("How long the work took, in whole minutes (1\u20131440)."),
|
|
30
|
+
timeProjectId: z.string().uuid().optional().describe("Project the time belongs to. Omit for unassigned time."),
|
|
31
|
+
taskId: z.string().uuid().optional().describe("Task the time belongs to; the task carries its own project."),
|
|
32
|
+
notes: z.string().max(2e3).optional().describe("What was done. Shown to whoever reviews the timesheet."),
|
|
33
|
+
isBillable: z.boolean().optional().describe("Override the project default for whether the time is billable.")
|
|
34
|
+
});
|
|
35
|
+
const logTimeTool = defineApiBackedAiTool({
|
|
36
|
+
name: "staff.log_time",
|
|
37
|
+
displayName: "Log time",
|
|
38
|
+
description: "Create a time entry for the signed-in user. Mutation tool \u2014 the write is held for approval and shown as a preview card before it runs.",
|
|
39
|
+
inputSchema: logTimeInput,
|
|
40
|
+
requiredFeatures: [MANAGE_OWN_FEATURE],
|
|
41
|
+
isMutation: true,
|
|
42
|
+
loadBeforeRecord: async (input, ctx) => {
|
|
43
|
+
const scope = await resolveStaffToolScope(ctx);
|
|
44
|
+
return {
|
|
45
|
+
recordId: `new:${scope.staffMemberId}:${input.date}`,
|
|
46
|
+
entityType: "staff.staff_time_entry",
|
|
47
|
+
recordVersion: null,
|
|
48
|
+
before: {},
|
|
49
|
+
after: {
|
|
50
|
+
date: input.date,
|
|
51
|
+
durationMinutes: input.durationMinutes,
|
|
52
|
+
timeProjectId: input.timeProjectId ?? null,
|
|
53
|
+
taskId: input.taskId ?? null,
|
|
54
|
+
notes: input.notes ?? null,
|
|
55
|
+
isBillable: input.isBillable ?? null
|
|
56
|
+
},
|
|
57
|
+
display: {
|
|
58
|
+
fieldLabels: {
|
|
59
|
+
date: "Date",
|
|
60
|
+
durationMinutes: "Minutes",
|
|
61
|
+
timeProjectId: "Project",
|
|
62
|
+
taskId: "Task",
|
|
63
|
+
notes: "Notes",
|
|
64
|
+
isBillable: "Billable"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
toOperation: async (input, ctx) => {
|
|
70
|
+
const scope = await resolveStaffToolScope(ctx);
|
|
71
|
+
return {
|
|
72
|
+
method: "POST",
|
|
73
|
+
path: "/staff/timesheets/time-entries",
|
|
74
|
+
body: {
|
|
75
|
+
tenantId: scope.tenantId,
|
|
76
|
+
organizationId: scope.organizationId,
|
|
77
|
+
staffMemberId: scope.staffMemberId,
|
|
78
|
+
date: input.date,
|
|
79
|
+
durationMinutes: input.durationMinutes,
|
|
80
|
+
...input.timeProjectId ? { timeProjectId: input.timeProjectId } : {},
|
|
81
|
+
...input.taskId ? { taskId: input.taskId } : {},
|
|
82
|
+
...input.notes ? { notes: input.notes } : {},
|
|
83
|
+
...input.isBillable === void 0 ? {} : { isBillable: input.isBillable }
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
mapResponse: (response, input) => ({
|
|
88
|
+
recordId: typeof response.data?.id === "string" ? response.data.id : null,
|
|
89
|
+
commandName: "staff.timesheets.time_entries.create",
|
|
90
|
+
before: {},
|
|
91
|
+
after: {
|
|
92
|
+
date: input.date,
|
|
93
|
+
durationMinutes: input.durationMinutes,
|
|
94
|
+
timeProjectId: input.timeProjectId ?? null,
|
|
95
|
+
taskId: input.taskId ?? null
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
const startTimerInput = z.object({
|
|
100
|
+
date: isoDate.optional().describe("Day to file the running timer under; defaults to today."),
|
|
101
|
+
timeProjectId: z.string().uuid().optional().describe("Project to start the timer against."),
|
|
102
|
+
taskId: z.string().uuid().optional().describe("Task to start the timer against; it carries its own project."),
|
|
103
|
+
notes: z.string().max(2e3).optional().describe("What the timer is for.")
|
|
104
|
+
});
|
|
105
|
+
const startTimerTool = defineApiBackedAiTool({
|
|
106
|
+
name: "staff.start_timer",
|
|
107
|
+
displayName: "Start timer",
|
|
108
|
+
description: "Start a running timer for the signed-in user. Mutation tool \u2014 held for approval before it runs.",
|
|
109
|
+
inputSchema: startTimerInput,
|
|
110
|
+
requiredFeatures: [MANAGE_OWN_FEATURE],
|
|
111
|
+
isMutation: true,
|
|
112
|
+
loadBeforeRecord: async (input, ctx) => {
|
|
113
|
+
const scope = await resolveStaffToolScope(ctx);
|
|
114
|
+
const date = input.date ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
115
|
+
return {
|
|
116
|
+
recordId: `timer:${scope.staffMemberId}:${date}`,
|
|
117
|
+
entityType: "staff.staff_time_entry",
|
|
118
|
+
recordVersion: null,
|
|
119
|
+
before: {},
|
|
120
|
+
after: {
|
|
121
|
+
date,
|
|
122
|
+
timeProjectId: input.timeProjectId ?? null,
|
|
123
|
+
taskId: input.taskId ?? null,
|
|
124
|
+
notes: input.notes ?? null
|
|
125
|
+
},
|
|
126
|
+
display: { fieldLabels: { date: "Date", timeProjectId: "Project", taskId: "Task", notes: "Notes" } }
|
|
127
|
+
};
|
|
128
|
+
},
|
|
129
|
+
toOperation: async (input, ctx) => {
|
|
130
|
+
const scope = await resolveStaffToolScope(ctx);
|
|
131
|
+
return {
|
|
132
|
+
method: "POST",
|
|
133
|
+
path: "/staff/timesheets/time-entries/start-timer",
|
|
134
|
+
body: {
|
|
135
|
+
tenantId: scope.tenantId,
|
|
136
|
+
organizationId: scope.organizationId,
|
|
137
|
+
staffMemberId: scope.staffMemberId,
|
|
138
|
+
date: input.date ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
139
|
+
...input.timeProjectId ? { timeProjectId: input.timeProjectId } : {},
|
|
140
|
+
...input.taskId ? { taskId: input.taskId } : {},
|
|
141
|
+
...input.notes ? { notes: input.notes } : {}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
},
|
|
145
|
+
mapResponse: (response, input) => ({
|
|
146
|
+
recordId: typeof response.data?.id === "string" ? response.data.id : null,
|
|
147
|
+
commandName: "staff.timesheets.time_entries.start_timer",
|
|
148
|
+
before: {},
|
|
149
|
+
after: { timeProjectId: input.timeProjectId ?? null, taskId: input.taskId ?? null }
|
|
150
|
+
})
|
|
151
|
+
});
|
|
152
|
+
const stopTimerInput = z.object({
|
|
153
|
+
timeEntryId: z.string().uuid().describe("The time entry whose running timer should be stopped.")
|
|
154
|
+
});
|
|
155
|
+
const stopTimerTool = defineApiBackedAiTool({
|
|
156
|
+
name: "staff.stop_timer",
|
|
157
|
+
displayName: "Stop timer",
|
|
158
|
+
description: "Stop the running timer on a time entry and freeze its duration. Mutation tool \u2014 held for approval before it runs.",
|
|
159
|
+
inputSchema: stopTimerInput,
|
|
160
|
+
requiredFeatures: [MANAGE_OWN_FEATURE],
|
|
161
|
+
isMutation: true,
|
|
162
|
+
loadBeforeRecord: async (input, ctx) => {
|
|
163
|
+
assertTenantScope(ctx);
|
|
164
|
+
return {
|
|
165
|
+
recordId: input.timeEntryId,
|
|
166
|
+
entityType: "staff.staff_time_entry",
|
|
167
|
+
recordVersion: null,
|
|
168
|
+
before: { timerRunning: true },
|
|
169
|
+
after: { timerRunning: false },
|
|
170
|
+
display: { fieldLabels: { timerRunning: "Timer running" } }
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
toOperation: async (input, ctx) => {
|
|
174
|
+
assertTenantScope(ctx);
|
|
175
|
+
return {
|
|
176
|
+
method: "POST",
|
|
177
|
+
path: `/staff/timesheets/time-entries/${input.timeEntryId}/timer-stop`,
|
|
178
|
+
body: {}
|
|
179
|
+
};
|
|
180
|
+
},
|
|
181
|
+
mapResponse: (response, input) => ({
|
|
182
|
+
recordId: input.timeEntryId,
|
|
183
|
+
commandName: "staff.timesheets.time_entries.stop_timer",
|
|
184
|
+
before: { timerRunning: true },
|
|
185
|
+
after: { timerRunning: false, durationMinutes: toMinutes(response.data?.durationMinutes) }
|
|
186
|
+
})
|
|
187
|
+
});
|
|
188
|
+
const summarizeWeekInput = z.object({
|
|
189
|
+
from: isoDate.describe("First day of the range, yyyy-mm-dd."),
|
|
190
|
+
to: isoDate.describe("Last day of the range, inclusive, yyyy-mm-dd.")
|
|
191
|
+
});
|
|
192
|
+
const summarizeWeekTool = defineApiBackedAiTool({
|
|
193
|
+
name: "staff.summarize_week",
|
|
194
|
+
displayName: "Summarize logged time",
|
|
195
|
+
description: "Summarize the signed-in user\u2019s logged time over a date range: totals per day and per project. Read-only. Returns minutes, never money.",
|
|
196
|
+
inputSchema: summarizeWeekInput,
|
|
197
|
+
requiredFeatures: [VIEW_FEATURE],
|
|
198
|
+
toOperation: async (input, ctx) => {
|
|
199
|
+
const scope = await resolveStaffToolScope(ctx);
|
|
200
|
+
return {
|
|
201
|
+
method: "GET",
|
|
202
|
+
path: "/staff/timesheets/time-entries",
|
|
203
|
+
query: {
|
|
204
|
+
from: input.from,
|
|
205
|
+
to: input.to,
|
|
206
|
+
staffMemberId: scope.staffMemberId,
|
|
207
|
+
page: 1,
|
|
208
|
+
pageSize: 100
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
},
|
|
212
|
+
mapResponse: (response, input) => {
|
|
213
|
+
const items = Array.isArray(response.data?.items) ? response.data.items : [];
|
|
214
|
+
const byDate = /* @__PURE__ */ new Map();
|
|
215
|
+
const byProject = /* @__PURE__ */ new Map();
|
|
216
|
+
let totalMinutes = 0;
|
|
217
|
+
for (const row of items) {
|
|
218
|
+
const date = readDate(row);
|
|
219
|
+
const minutes = readMinutes(row);
|
|
220
|
+
totalMinutes += minutes;
|
|
221
|
+
if (date) byDate.set(date, (byDate.get(date) ?? 0) + minutes);
|
|
222
|
+
const projectKey = readProjectId(row) ?? "";
|
|
223
|
+
const bucket = byProject.get(projectKey) ?? { minutes: 0, entryCount: 0 };
|
|
224
|
+
bucket.minutes += minutes;
|
|
225
|
+
bucket.entryCount += 1;
|
|
226
|
+
byProject.set(projectKey, bucket);
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
from: input.from,
|
|
230
|
+
to: input.to,
|
|
231
|
+
totalMinutes,
|
|
232
|
+
entryCount: items.length,
|
|
233
|
+
byDate: Array.from(byDate.entries()).map(([date, minutes]) => ({ date, minutes })).sort((left, right) => left.date.localeCompare(right.date)),
|
|
234
|
+
byProject: Array.from(byProject.entries()).map(([key, value]) => ({
|
|
235
|
+
timeProjectId: key.length > 0 ? key : null,
|
|
236
|
+
minutes: value.minutes,
|
|
237
|
+
entryCount: value.entryCount
|
|
238
|
+
}))
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
const findMissingDaysInput = z.object({
|
|
243
|
+
from: isoDate.describe("First day of the range, yyyy-mm-dd."),
|
|
244
|
+
to: isoDate.describe("Last day of the range, inclusive, yyyy-mm-dd."),
|
|
245
|
+
includeWeekends: z.boolean().optional().describe("Count Saturdays and Sundays as days that need time logged. Defaults to false.")
|
|
246
|
+
});
|
|
247
|
+
const findMissingDaysTool = defineApiBackedAiTool({
|
|
248
|
+
name: "staff.find_missing_days",
|
|
249
|
+
displayName: "Find days with no logged time",
|
|
250
|
+
description: "List the days in a range on which the signed-in user logged no time. Weekends are excluded unless asked for. Read-only.",
|
|
251
|
+
inputSchema: findMissingDaysInput,
|
|
252
|
+
requiredFeatures: [VIEW_FEATURE],
|
|
253
|
+
toOperation: async (input, ctx) => {
|
|
254
|
+
const scope = await resolveStaffToolScope(ctx);
|
|
255
|
+
return {
|
|
256
|
+
method: "GET",
|
|
257
|
+
path: "/staff/timesheets/time-entries",
|
|
258
|
+
query: {
|
|
259
|
+
from: input.from,
|
|
260
|
+
to: input.to,
|
|
261
|
+
staffMemberId: scope.staffMemberId,
|
|
262
|
+
page: 1,
|
|
263
|
+
pageSize: 100
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
},
|
|
267
|
+
mapResponse: (response, input) => {
|
|
268
|
+
const items = Array.isArray(response.data?.items) ? response.data.items : [];
|
|
269
|
+
const logged = /* @__PURE__ */ new Set();
|
|
270
|
+
for (const row of items) {
|
|
271
|
+
const date = readDate(row);
|
|
272
|
+
if (date && readMinutes(row) > 0) logged.add(date);
|
|
273
|
+
}
|
|
274
|
+
const candidates = enumerateDates(input.from, input.to).filter(
|
|
275
|
+
(date) => (input.includeWeekends ?? false) || !isWeekend(date)
|
|
276
|
+
);
|
|
277
|
+
return {
|
|
278
|
+
from: input.from,
|
|
279
|
+
to: input.to,
|
|
280
|
+
missingDates: candidates.filter((date) => !logged.has(date)),
|
|
281
|
+
checkedDayCount: candidates.length
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
const draftClientReportInput = z.object({
|
|
286
|
+
timeProjectIds: z.array(z.string().uuid()).min(1).max(100).describe("Projects the report covers. They must all belong to the same customer."),
|
|
287
|
+
periodFrom: isoDate.describe("First day of the reported period, yyyy-mm-dd."),
|
|
288
|
+
periodTo: isoDate.describe("Last day of the reported period, inclusive, yyyy-mm-dd."),
|
|
289
|
+
customerId: z.string().uuid().optional().describe("Customer the report is for."),
|
|
290
|
+
grouping: z.string().optional().describe("Report grouping id, e.g. project_task, project_person or project_day."),
|
|
291
|
+
includeAlreadyReported: z.boolean().optional().describe("Include entries already frozen into an earlier report. Defaults to false.")
|
|
292
|
+
});
|
|
293
|
+
const draftClientReportTool = defineApiBackedAiTool({
|
|
294
|
+
name: "staff.draft_client_report",
|
|
295
|
+
displayName: "Draft a client report",
|
|
296
|
+
description: "Preview what a customer report would contain for a set of projects and a period, without creating one. Read-only \u2014 no report is written and nothing is locked. Amounts are omitted; ask the reports screen for money.",
|
|
297
|
+
inputSchema: draftClientReportInput,
|
|
298
|
+
requiredFeatures: [REPORTS_VIEW_FEATURE],
|
|
299
|
+
toOperation: async (input, ctx) => {
|
|
300
|
+
assertTenantScope(ctx);
|
|
301
|
+
return {
|
|
302
|
+
method: "POST",
|
|
303
|
+
path: "/staff/timesheets/reports/preview",
|
|
304
|
+
body: {
|
|
305
|
+
timeProjectIds: input.timeProjectIds,
|
|
306
|
+
periodFrom: input.periodFrom,
|
|
307
|
+
periodTo: input.periodTo,
|
|
308
|
+
periodKind: "custom",
|
|
309
|
+
...input.customerId ? { customerId: input.customerId } : {},
|
|
310
|
+
...input.grouping ? { grouping: input.grouping } : {},
|
|
311
|
+
includeAlreadyReported: input.includeAlreadyReported ?? false,
|
|
312
|
+
showRates: false
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
},
|
|
316
|
+
/**
|
|
317
|
+
* The preview response carries rates and amounts when the caller holds
|
|
318
|
+
* `staff.timesheets.rates.view`. The tool asks for `showRates: false` and then
|
|
319
|
+
* projects only the minute columns, so an agent transcript never becomes a
|
|
320
|
+
* second, ungated copy of the customer's rate card.
|
|
321
|
+
*/
|
|
322
|
+
mapResponse: (response, input) => ({
|
|
323
|
+
periodFrom: input.periodFrom,
|
|
324
|
+
periodTo: input.periodTo,
|
|
325
|
+
grouping: typeof response.data?.grouping === "string" ? response.data.grouping : null,
|
|
326
|
+
projects: (response.data?.projects ?? []).map((project) => ({
|
|
327
|
+
id: typeof project.id === "string" ? project.id : null,
|
|
328
|
+
name: typeof project.name === "string" ? project.name : null,
|
|
329
|
+
billableMinutes: toMinutes(project.billableMinutes),
|
|
330
|
+
nonbillableMinutes: toMinutes(project.nonbillableMinutes),
|
|
331
|
+
entryCount: toMinutes(project.entryCount)
|
|
332
|
+
}))
|
|
333
|
+
})
|
|
334
|
+
});
|
|
335
|
+
const timeTrackingAiTools = [
|
|
336
|
+
logTimeTool,
|
|
337
|
+
startTimerTool,
|
|
338
|
+
stopTimerTool,
|
|
339
|
+
summarizeWeekTool,
|
|
340
|
+
findMissingDaysTool,
|
|
341
|
+
draftClientReportTool
|
|
342
|
+
];
|
|
343
|
+
var time_tracking_pack_default = timeTrackingAiTools;
|
|
344
|
+
export {
|
|
345
|
+
time_tracking_pack_default as default,
|
|
346
|
+
timeTrackingAiTools
|
|
347
|
+
};
|
|
348
|
+
//# sourceMappingURL=time-tracking-pack.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/staff/ai-tools/time-tracking-pack.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * EP-49 \u2014 the time-tracking AI tool pack.\n *\n * Six tools, three of them writes. The write path is the platform's approval\n * contract, and the shape of that contract is the one thing worth stating\n * plainly here, because the spec described it inside out:\n *\n * A module tool does NOT call `prepareMutation`. `prepareMutation` is framework\n * code \u2014 its only call site is `agent-tools.ts` in `@open-mercato/ai-assistant`,\n * which intercepts the model's call, short-circuits the handler, persists an\n * `AiPendingAction` and returns a preview card. A tool opts into that by\n * declaring `isMutation: true` and a `loadBeforeRecord` resolver that renders the\n * diff; the agent opts in with `mutationPolicy: 'confirm-required'`. The handler\n * runs later, once, from the confirm route, with the stored input. Calling\n * `prepareMutation` from here would be calling the interceptor from inside the\n * thing it intercepts.\n *\n * Every tool is API-backed. `createAiApiOperationRunner` resolves the route from\n * the generated manifest and refuses to run a mutation route whose\n * `requiredFeatures` the tool does not itself declare, so the `staff.timesheets.*`\n * gate on each tool below is checked twice: once by the tool registry before the\n * handler, once by the runner against the route. The route then applies the\n * project-access intersection, the mutation guards, the interceptors and the\n * commands \u2014 none of which is reimplemented here.\n */\n\nimport { z } from 'zod'\nimport { defineApiBackedAiTool } from '@open-mercato/ai-assistant/modules/ai_assistant/lib/api-backed-tool'\nimport type {\n AiApiOperationRequest,\n AiToolExecutionContext,\n} from '@open-mercato/ai-assistant/modules/ai_assistant/lib/ai-api-operation-runner'\nimport type { AiToolDefinition } from '@open-mercato/ai-assistant/modules/ai_assistant/lib/types'\nimport {\n assertTenantScope,\n enumerateDates,\n isWeekend,\n resolveStaffToolScope,\n toIsoDate,\n toMinutes,\n} from './types'\n\nconst VIEW_FEATURE = 'staff.timesheets.view'\nconst MANAGE_OWN_FEATURE = 'staff.timesheets.manage_own'\nconst REPORTS_VIEW_FEATURE = 'staff.timesheets.reports.view'\n\nconst isoDate = z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'Use a yyyy-mm-dd calendar date.')\n\ntype EntryRow = {\n id?: unknown\n date?: unknown\n durationMinutes?: unknown\n duration_minutes?: unknown\n roundedMinutes?: unknown\n timeProjectId?: unknown\n time_project_id?: unknown\n projectName?: unknown\n taskId?: unknown\n notes?: unknown\n isBillable?: unknown\n is_billable?: unknown\n}\n\ntype EntriesApiResponse = {\n items?: EntryRow[]\n total?: number\n}\n\nfunction readDate(row: EntryRow): string | null {\n return toIsoDate(row.date)\n}\n\nfunction readMinutes(row: EntryRow): number {\n const rounded = toMinutes(row.roundedMinutes)\n if (rounded > 0) return rounded\n return toMinutes(row.durationMinutes ?? row.duration_minutes)\n}\n\nfunction readProjectId(row: EntryRow): string | null {\n const value = row.timeProjectId ?? row.time_project_id\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null\n}\n\n/* ------------------------------------------------------------------ writes */\n\nconst logTimeInput = z.object({\n date: isoDate.describe('The calendar day the work happened, as yyyy-mm-dd.'),\n durationMinutes: z\n .number()\n .int()\n .min(1)\n .max(1440)\n .describe('How long the work took, in whole minutes (1\u20131440).'),\n timeProjectId: z.string().uuid().optional().describe('Project the time belongs to. Omit for unassigned time.'),\n taskId: z.string().uuid().optional().describe('Task the time belongs to; the task carries its own project.'),\n notes: z.string().max(2000).optional().describe('What was done. Shown to whoever reviews the timesheet.'),\n isBillable: z.boolean().optional().describe('Override the project default for whether the time is billable.'),\n})\n\ntype LogTimeInput = z.infer<typeof logTimeInput>\n\nconst logTimeTool = defineApiBackedAiTool<LogTimeInput, { id?: string }, { recordId: string | null; commandName: string; before: Record<string, unknown>; after: Record<string, unknown> }>({\n name: 'staff.log_time',\n displayName: 'Log time',\n description:\n 'Create a time entry for the signed-in user. Mutation tool \u2014 the write is held for approval and shown as a preview card before it runs.',\n inputSchema: logTimeInput,\n requiredFeatures: [MANAGE_OWN_FEATURE],\n isMutation: true,\n loadBeforeRecord: async (input, ctx) => {\n const scope = await resolveStaffToolScope(ctx as unknown as AiToolExecutionContext)\n return {\n recordId: `new:${scope.staffMemberId}:${input.date}`,\n entityType: 'staff.staff_time_entry',\n recordVersion: null,\n before: {},\n after: {\n date: input.date,\n durationMinutes: input.durationMinutes,\n timeProjectId: input.timeProjectId ?? null,\n taskId: input.taskId ?? null,\n notes: input.notes ?? null,\n isBillable: input.isBillable ?? null,\n },\n display: {\n fieldLabels: {\n date: 'Date',\n durationMinutes: 'Minutes',\n timeProjectId: 'Project',\n taskId: 'Task',\n notes: 'Notes',\n isBillable: 'Billable',\n },\n },\n }\n },\n toOperation: async (input, ctx) => {\n const scope = await resolveStaffToolScope(ctx)\n return {\n method: 'POST',\n path: '/staff/timesheets/time-entries',\n body: {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n staffMemberId: scope.staffMemberId,\n date: input.date,\n durationMinutes: input.durationMinutes,\n ...(input.timeProjectId ? { timeProjectId: input.timeProjectId } : {}),\n ...(input.taskId ? { taskId: input.taskId } : {}),\n ...(input.notes ? { notes: input.notes } : {}),\n ...(input.isBillable === undefined ? {} : { isBillable: input.isBillable }),\n },\n } satisfies AiApiOperationRequest\n },\n mapResponse: (response, input) => ({\n recordId: typeof response.data?.id === 'string' ? response.data.id : null,\n commandName: 'staff.timesheets.time_entries.create',\n before: {},\n after: {\n date: input.date,\n durationMinutes: input.durationMinutes,\n timeProjectId: input.timeProjectId ?? null,\n taskId: input.taskId ?? null,\n },\n }),\n}) as unknown as AiToolDefinition\n\nconst startTimerInput = z.object({\n date: isoDate.optional().describe('Day to file the running timer under; defaults to today.'),\n timeProjectId: z.string().uuid().optional().describe('Project to start the timer against.'),\n taskId: z.string().uuid().optional().describe('Task to start the timer against; it carries its own project.'),\n notes: z.string().max(2000).optional().describe('What the timer is for.'),\n})\n\ntype StartTimerInput = z.infer<typeof startTimerInput>\n\nconst startTimerTool = defineApiBackedAiTool<StartTimerInput, { id?: string | null }, { recordId: string | null; commandName: string; before: Record<string, unknown>; after: Record<string, unknown> }>({\n name: 'staff.start_timer',\n displayName: 'Start timer',\n description:\n 'Start a running timer for the signed-in user. Mutation tool \u2014 held for approval before it runs.',\n inputSchema: startTimerInput,\n requiredFeatures: [MANAGE_OWN_FEATURE],\n isMutation: true,\n loadBeforeRecord: async (input, ctx) => {\n const scope = await resolveStaffToolScope(ctx as unknown as AiToolExecutionContext)\n const date = input.date ?? new Date().toISOString().slice(0, 10)\n return {\n recordId: `timer:${scope.staffMemberId}:${date}`,\n entityType: 'staff.staff_time_entry',\n recordVersion: null,\n before: {},\n after: {\n date,\n timeProjectId: input.timeProjectId ?? null,\n taskId: input.taskId ?? null,\n notes: input.notes ?? null,\n },\n display: { fieldLabels: { date: 'Date', timeProjectId: 'Project', taskId: 'Task', notes: 'Notes' } },\n }\n },\n toOperation: async (input, ctx) => {\n const scope = await resolveStaffToolScope(ctx)\n return {\n method: 'POST',\n path: '/staff/timesheets/time-entries/start-timer',\n body: {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n staffMemberId: scope.staffMemberId,\n date: input.date ?? new Date().toISOString().slice(0, 10),\n ...(input.timeProjectId ? { timeProjectId: input.timeProjectId } : {}),\n ...(input.taskId ? { taskId: input.taskId } : {}),\n ...(input.notes ? { notes: input.notes } : {}),\n },\n } satisfies AiApiOperationRequest\n },\n mapResponse: (response, input) => ({\n recordId: typeof response.data?.id === 'string' ? response.data.id : null,\n commandName: 'staff.timesheets.time_entries.start_timer',\n before: {},\n after: { timeProjectId: input.timeProjectId ?? null, taskId: input.taskId ?? null },\n }),\n}) as unknown as AiToolDefinition\n\nconst stopTimerInput = z.object({\n timeEntryId: z.string().uuid().describe('The time entry whose running timer should be stopped.'),\n})\n\ntype StopTimerInput = z.infer<typeof stopTimerInput>\n\nconst stopTimerTool = defineApiBackedAiTool<StopTimerInput, { durationMinutes?: number }, { recordId: string; commandName: string; before: Record<string, unknown>; after: Record<string, unknown> }>({\n name: 'staff.stop_timer',\n displayName: 'Stop timer',\n description:\n 'Stop the running timer on a time entry and freeze its duration. Mutation tool \u2014 held for approval before it runs.',\n inputSchema: stopTimerInput,\n requiredFeatures: [MANAGE_OWN_FEATURE],\n isMutation: true,\n loadBeforeRecord: async (input, ctx) => {\n assertTenantScope(ctx as unknown as AiToolExecutionContext)\n return {\n recordId: input.timeEntryId,\n entityType: 'staff.staff_time_entry',\n recordVersion: null,\n before: { timerRunning: true },\n after: { timerRunning: false },\n display: { fieldLabels: { timerRunning: 'Timer running' } },\n }\n },\n toOperation: async (input, ctx) => {\n assertTenantScope(ctx)\n return {\n method: 'POST',\n path: `/staff/timesheets/time-entries/${input.timeEntryId}/timer-stop`,\n body: {},\n } satisfies AiApiOperationRequest\n },\n mapResponse: (response, input) => ({\n recordId: input.timeEntryId,\n commandName: 'staff.timesheets.time_entries.stop_timer',\n before: { timerRunning: true },\n after: { timerRunning: false, durationMinutes: toMinutes(response.data?.durationMinutes) },\n }),\n}) as unknown as AiToolDefinition\n\n/* ------------------------------------------------------------------- reads */\n\nconst summarizeWeekInput = z.object({\n from: isoDate.describe('First day of the range, yyyy-mm-dd.'),\n to: isoDate.describe('Last day of the range, inclusive, yyyy-mm-dd.'),\n})\n\ntype SummarizeWeekInput = z.infer<typeof summarizeWeekInput>\n\nconst summarizeWeekTool = defineApiBackedAiTool<\n SummarizeWeekInput,\n EntriesApiResponse,\n {\n from: string\n to: string\n totalMinutes: number\n entryCount: number\n byDate: Array<{ date: string; minutes: number }>\n byProject: Array<{ timeProjectId: string | null; minutes: number; entryCount: number }>\n }\n>({\n name: 'staff.summarize_week',\n displayName: 'Summarize logged time',\n description:\n 'Summarize the signed-in user\u2019s logged time over a date range: totals per day and per project. Read-only. Returns minutes, never money.',\n inputSchema: summarizeWeekInput,\n requiredFeatures: [VIEW_FEATURE],\n toOperation: async (input, ctx) => {\n const scope = await resolveStaffToolScope(ctx)\n return {\n method: 'GET',\n path: '/staff/timesheets/time-entries',\n query: {\n from: input.from,\n to: input.to,\n staffMemberId: scope.staffMemberId,\n page: 1,\n pageSize: 100,\n },\n } satisfies AiApiOperationRequest\n },\n mapResponse: (response, input) => {\n const items = Array.isArray(response.data?.items) ? response.data.items : []\n const byDate = new Map<string, number>()\n const byProject = new Map<string, { minutes: number; entryCount: number }>()\n let totalMinutes = 0\n for (const row of items) {\n const date = readDate(row)\n const minutes = readMinutes(row)\n totalMinutes += minutes\n if (date) byDate.set(date, (byDate.get(date) ?? 0) + minutes)\n const projectKey = readProjectId(row) ?? ''\n const bucket = byProject.get(projectKey) ?? { minutes: 0, entryCount: 0 }\n bucket.minutes += minutes\n bucket.entryCount += 1\n byProject.set(projectKey, bucket)\n }\n return {\n from: input.from,\n to: input.to,\n totalMinutes,\n entryCount: items.length,\n byDate: Array.from(byDate.entries())\n .map(([date, minutes]) => ({ date, minutes }))\n .sort((left, right) => left.date.localeCompare(right.date)),\n byProject: Array.from(byProject.entries()).map(([key, value]) => ({\n timeProjectId: key.length > 0 ? key : null,\n minutes: value.minutes,\n entryCount: value.entryCount,\n })),\n }\n },\n}) as unknown as AiToolDefinition\n\nconst findMissingDaysInput = z.object({\n from: isoDate.describe('First day of the range, yyyy-mm-dd.'),\n to: isoDate.describe('Last day of the range, inclusive, yyyy-mm-dd.'),\n includeWeekends: z\n .boolean()\n .optional()\n .describe('Count Saturdays and Sundays as days that need time logged. Defaults to false.'),\n})\n\ntype FindMissingDaysInput = z.infer<typeof findMissingDaysInput>\n\nconst findMissingDaysTool = defineApiBackedAiTool<\n FindMissingDaysInput,\n EntriesApiResponse,\n { from: string; to: string; missingDates: string[]; checkedDayCount: number }\n>({\n name: 'staff.find_missing_days',\n displayName: 'Find days with no logged time',\n description:\n 'List the days in a range on which the signed-in user logged no time. Weekends are excluded unless asked for. Read-only.',\n inputSchema: findMissingDaysInput,\n requiredFeatures: [VIEW_FEATURE],\n toOperation: async (input, ctx) => {\n const scope = await resolveStaffToolScope(ctx)\n return {\n method: 'GET',\n path: '/staff/timesheets/time-entries',\n query: {\n from: input.from,\n to: input.to,\n staffMemberId: scope.staffMemberId,\n page: 1,\n pageSize: 100,\n },\n } satisfies AiApiOperationRequest\n },\n mapResponse: (response, input) => {\n const items = Array.isArray(response.data?.items) ? response.data.items : []\n const logged = new Set<string>()\n for (const row of items) {\n const date = readDate(row)\n if (date && readMinutes(row) > 0) logged.add(date)\n }\n const candidates = enumerateDates(input.from, input.to).filter(\n (date) => (input.includeWeekends ?? false) || !isWeekend(date),\n )\n return {\n from: input.from,\n to: input.to,\n missingDates: candidates.filter((date) => !logged.has(date)),\n checkedDayCount: candidates.length,\n }\n },\n}) as unknown as AiToolDefinition\n\nconst draftClientReportInput = z.object({\n timeProjectIds: z\n .array(z.string().uuid())\n .min(1)\n .max(100)\n .describe('Projects the report covers. They must all belong to the same customer.'),\n periodFrom: isoDate.describe('First day of the reported period, yyyy-mm-dd.'),\n periodTo: isoDate.describe('Last day of the reported period, inclusive, yyyy-mm-dd.'),\n customerId: z.string().uuid().optional().describe('Customer the report is for.'),\n grouping: z\n .string()\n .optional()\n .describe('Report grouping id, e.g. project_task, project_person or project_day.'),\n includeAlreadyReported: z\n .boolean()\n .optional()\n .describe('Include entries already frozen into an earlier report. Defaults to false.'),\n})\n\ntype DraftClientReportInput = z.infer<typeof draftClientReportInput>\n\ntype PreviewApiResponse = {\n currencyCode?: unknown\n grouping?: unknown\n projects?: Array<{\n id?: unknown\n name?: unknown\n entryCount?: unknown\n billableMinutes?: unknown\n nonbillableMinutes?: unknown\n }>\n totals?: unknown\n}\n\nconst draftClientReportTool = defineApiBackedAiTool<\n DraftClientReportInput,\n PreviewApiResponse,\n {\n periodFrom: string\n periodTo: string\n grouping: string | null\n projects: Array<{ id: string | null; name: string | null; billableMinutes: number; nonbillableMinutes: number; entryCount: number }>\n }\n>({\n name: 'staff.draft_client_report',\n displayName: 'Draft a client report',\n description:\n 'Preview what a customer report would contain for a set of projects and a period, without creating one. Read-only \u2014 no report is written and nothing is locked. Amounts are omitted; ask the reports screen for money.',\n inputSchema: draftClientReportInput,\n requiredFeatures: [REPORTS_VIEW_FEATURE],\n toOperation: async (input, ctx) => {\n assertTenantScope(ctx)\n return {\n method: 'POST',\n path: '/staff/timesheets/reports/preview',\n body: {\n timeProjectIds: input.timeProjectIds,\n periodFrom: input.periodFrom,\n periodTo: input.periodTo,\n periodKind: 'custom',\n ...(input.customerId ? { customerId: input.customerId } : {}),\n ...(input.grouping ? { grouping: input.grouping } : {}),\n includeAlreadyReported: input.includeAlreadyReported ?? false,\n showRates: false,\n },\n } satisfies AiApiOperationRequest\n },\n /**\n * The preview response carries rates and amounts when the caller holds\n * `staff.timesheets.rates.view`. The tool asks for `showRates: false` and then\n * projects only the minute columns, so an agent transcript never becomes a\n * second, ungated copy of the customer's rate card.\n */\n mapResponse: (response, input) => ({\n periodFrom: input.periodFrom,\n periodTo: input.periodTo,\n grouping: typeof response.data?.grouping === 'string' ? response.data.grouping : null,\n projects: (response.data?.projects ?? []).map((project) => ({\n id: typeof project.id === 'string' ? project.id : null,\n name: typeof project.name === 'string' ? project.name : null,\n billableMinutes: toMinutes(project.billableMinutes),\n nonbillableMinutes: toMinutes(project.nonbillableMinutes),\n entryCount: toMinutes(project.entryCount),\n })),\n }),\n}) as unknown as AiToolDefinition\n\nexport const timeTrackingAiTools: AiToolDefinition[] = [\n logTimeTool,\n startTimerTool,\n stopTimerTool,\n summarizeWeekTool,\n findMissingDaysTool,\n draftClientReportTool,\n]\n\nexport default timeTrackingAiTools\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { getStaffMemberByUserId } from "../lib/staffMemberResolver.js";
|
|
2
|
+
function assertTenantScope(ctx) {
|
|
3
|
+
if (!ctx.tenantId) throw new Error("[internal] Tenant context is required for staff.* tools");
|
|
4
|
+
if (!ctx.organizationId) {
|
|
5
|
+
throw new Error("[internal] Organization context is required for staff.* tools");
|
|
6
|
+
}
|
|
7
|
+
return { tenantId: ctx.tenantId, organizationId: ctx.organizationId };
|
|
8
|
+
}
|
|
9
|
+
async function resolveStaffToolScope(ctx) {
|
|
10
|
+
const { tenantId, organizationId } = assertTenantScope(ctx);
|
|
11
|
+
if (!ctx.userId) throw new Error("[internal] User context is required for staff.* tools");
|
|
12
|
+
const container = ctx.container;
|
|
13
|
+
const em = container.resolve("em").fork();
|
|
14
|
+
const member = await getStaffMemberByUserId(em, ctx.userId, tenantId, organizationId);
|
|
15
|
+
if (!member) {
|
|
16
|
+
throw new Error("The signed-in user has no staff profile, so time cannot be logged for them.");
|
|
17
|
+
}
|
|
18
|
+
return { tenantId, organizationId, staffMemberId: member.id };
|
|
19
|
+
}
|
|
20
|
+
function toIsoDate(value) {
|
|
21
|
+
if (value instanceof Date) {
|
|
22
|
+
if (Number.isNaN(value.getTime())) return null;
|
|
23
|
+
return value.toISOString().slice(0, 10);
|
|
24
|
+
}
|
|
25
|
+
if (typeof value === "string" && value.trim().length > 0) return value.trim().slice(0, 10);
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
function toMinutes(value) {
|
|
29
|
+
const parsed = typeof value === "number" ? value : Number(value ?? 0);
|
|
30
|
+
return Number.isFinite(parsed) ? Math.trunc(parsed) : 0;
|
|
31
|
+
}
|
|
32
|
+
function enumerateDates(from, to) {
|
|
33
|
+
const start = Date.parse(`${from}T00:00:00Z`);
|
|
34
|
+
const end = Date.parse(`${to}T00:00:00Z`);
|
|
35
|
+
if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return [];
|
|
36
|
+
const dates = [];
|
|
37
|
+
for (let cursor = start; cursor <= end && dates.length < 366; cursor += 864e5) {
|
|
38
|
+
dates.push(new Date(cursor).toISOString().slice(0, 10));
|
|
39
|
+
}
|
|
40
|
+
return dates;
|
|
41
|
+
}
|
|
42
|
+
function isWeekend(date) {
|
|
43
|
+
const day = (/* @__PURE__ */ new Date(`${date}T00:00:00Z`)).getUTCDay();
|
|
44
|
+
return day === 0 || day === 6;
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
assertTenantScope,
|
|
48
|
+
enumerateDates,
|
|
49
|
+
isWeekend,
|
|
50
|
+
resolveStaffToolScope,
|
|
51
|
+
toIsoDate,
|
|
52
|
+
toMinutes
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/staff/ai-tools/types.ts"],
|
|
4
|
+
"sourcesContent": ["import type { AwilixContainer } from 'awilix'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { AiToolExecutionContext } from '@open-mercato/ai-assistant/modules/ai_assistant/lib/ai-api-operation-runner'\nimport { getStaffMemberByUserId } from '../lib/staffMemberResolver'\n\n/**\n * EP-49. Shared context helpers for the time-tracking AI tool pack.\n *\n * Every tool in the pack is API-backed: it re-uses a documented\n * `/api/staff/timesheets/*` route through `createAiApiOperationRunner`, which\n * resolves the route from the generated manifest, refuses a mutation route whose\n * `requiredFeatures` are not covered by the tool's own, and invokes the handler\n * in process with the caller's identity. So the tools inherit \u2014 rather than\n * restate \u2014 the project-access intersection, the money gate, the mutation guards,\n * the interceptors and the commands' audit and undo. Nothing here writes a time\n * entry itself.\n */\n\nexport type StaffToolScope = {\n tenantId: string\n organizationId: string\n staffMemberId: string\n}\n\nexport function assertTenantScope(ctx: AiToolExecutionContext): {\n tenantId: string\n organizationId: string\n} {\n if (!ctx.tenantId) throw new Error('[internal] Tenant context is required for staff.* tools')\n if (!ctx.organizationId) {\n throw new Error('[internal] Organization context is required for staff.* tools')\n }\n return { tenantId: ctx.tenantId, organizationId: ctx.organizationId }\n}\n\n/**\n * The pack is written for \"log MY time\": every tool acts as the caller's own\n * staff member and none of them accepts a `staffMemberId` from the model. A user\n * with no staff profile is refused rather than defaulted to somebody else.\n */\nexport async function resolveStaffToolScope(ctx: AiToolExecutionContext): Promise<StaffToolScope> {\n const { tenantId, organizationId } = assertTenantScope(ctx)\n if (!ctx.userId) throw new Error('[internal] User context is required for staff.* tools')\n const container = ctx.container as AwilixContainer\n const em = (container.resolve('em') as EntityManager).fork()\n const member = await getStaffMemberByUserId(em, ctx.userId, tenantId, organizationId)\n if (!member) {\n throw new Error('The signed-in user has no staff profile, so time cannot be logged for them.')\n }\n return { tenantId, organizationId, staffMemberId: member.id }\n}\n\nexport function toIsoDate(value: unknown): string | null {\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) return null\n return value.toISOString().slice(0, 10)\n }\n if (typeof value === 'string' && value.trim().length > 0) return value.trim().slice(0, 10)\n return null\n}\n\nexport function toMinutes(value: unknown): number {\n const parsed = typeof value === 'number' ? value : Number(value ?? 0)\n return Number.isFinite(parsed) ? Math.trunc(parsed) : 0\n}\n\n/** Inclusive `yyyy-mm-dd` walk; caps at a year so a bad range cannot build an unbounded array. */\nexport function enumerateDates(from: string, to: string): string[] {\n const start = Date.parse(`${from}T00:00:00Z`)\n const end = Date.parse(`${to}T00:00:00Z`)\n if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return []\n const dates: string[] = []\n for (let cursor = start; cursor <= end && dates.length < 366; cursor += 86_400_000) {\n dates.push(new Date(cursor).toISOString().slice(0, 10))\n }\n return dates\n}\n\nexport function isWeekend(date: string): boolean {\n const day = new Date(`${date}T00:00:00Z`).getUTCDay()\n return day === 0 || day === 6\n}\n"],
|
|
5
|
+
"mappings": "AAGA,SAAS,8BAA8B;AAqBhC,SAAS,kBAAkB,KAGhC;AACA,MAAI,CAAC,IAAI,SAAU,OAAM,IAAI,MAAM,yDAAyD;AAC5F,MAAI,CAAC,IAAI,gBAAgB;AACvB,UAAM,IAAI,MAAM,+DAA+D;AAAA,EACjF;AACA,SAAO,EAAE,UAAU,IAAI,UAAU,gBAAgB,IAAI,eAAe;AACtE;AAOA,eAAsB,sBAAsB,KAAsD;AAChG,QAAM,EAAE,UAAU,eAAe,IAAI,kBAAkB,GAAG;AAC1D,MAAI,CAAC,IAAI,OAAQ,OAAM,IAAI,MAAM,uDAAuD;AACxF,QAAM,YAAY,IAAI;AACtB,QAAM,KAAM,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC3D,QAAM,SAAS,MAAM,uBAAuB,IAAI,IAAI,QAAQ,UAAU,cAAc;AACpF,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,6EAA6E;AAAA,EAC/F;AACA,SAAO,EAAE,UAAU,gBAAgB,eAAe,OAAO,GAAG;AAC9D;AAEO,SAAS,UAAU,OAA+B;AACvD,MAAI,iBAAiB,MAAM;AACzB,QAAI,OAAO,MAAM,MAAM,QAAQ,CAAC,EAAG,QAAO;AAC1C,WAAO,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,EACxC;AACA,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,EAAG,QAAO,MAAM,KAAK,EAAE,MAAM,GAAG,EAAE;AACzF,SAAO;AACT;AAEO,SAAS,UAAU,OAAwB;AAChD,QAAM,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,SAAS,CAAC;AACpE,SAAO,OAAO,SAAS,MAAM,IAAI,KAAK,MAAM,MAAM,IAAI;AACxD;AAGO,SAAS,eAAe,MAAc,IAAsB;AACjE,QAAM,QAAQ,KAAK,MAAM,GAAG,IAAI,YAAY;AAC5C,QAAM,MAAM,KAAK,MAAM,GAAG,EAAE,YAAY;AACxC,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,CAAC,OAAO,SAAS,GAAG,KAAK,MAAM,MAAO,QAAO,CAAC;AAC7E,QAAM,QAAkB,CAAC;AACzB,WAAS,SAAS,OAAO,UAAU,OAAO,MAAM,SAAS,KAAK,UAAU,OAAY;AAClF,UAAM,KAAK,IAAI,KAAK,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,EACxD;AACA,SAAO;AACT;AAEO,SAAS,UAAU,MAAuB;AAC/C,QAAM,OAAM,oBAAI,KAAK,GAAG,IAAI,YAAY,GAAE,UAAU;AACpD,SAAO,QAAQ,KAAK,QAAQ;AAC9B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|