@open-mercato/core 0.6.5-develop.5337.1.534b781eac → 0.6.5
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 +1 -1
- package/AGENTS.md +1 -1
- package/dist/bootstrap.js +46 -6
- package/dist/bootstrap.js.map +2 -2
- package/dist/generated/entities/organization/index.js +2 -0
- package/dist/generated/entities/organization/index.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +1 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/crmFixtures.js +4 -0
- package/dist/helpers/integration/crmFixtures.js.map +2 -2
- package/dist/modules/attachments/api/library/route.js +2 -2
- package/dist/modules/attachments/api/library/route.js.map +2 -2
- package/dist/modules/attachments/api/route.js +2 -0
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentContentPreview.js +9 -5
- package/dist/modules/attachments/components/AttachmentContentPreview.js.map +2 -2
- package/dist/modules/attachments/lib/access.js +18 -0
- package/dist/modules/attachments/lib/access.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +3 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js.map +2 -2
- package/dist/modules/audit_logs/data/entities.js +2 -1
- package/dist/modules/audit_logs/data/entities.js.map +2 -2
- package/dist/modules/audit_logs/migrations/Migration20260611104500.js +13 -0
- package/dist/modules/audit_logs/migrations/Migration20260611104500.js.map +7 -0
- package/dist/modules/audit_logs/services/accessLogService.js +10 -0
- package/dist/modules/audit_logs/services/accessLogService.js.map +2 -2
- package/dist/modules/auth/api/admin/nav.js +9 -0
- package/dist/modules/auth/api/admin/nav.js.map +2 -2
- package/dist/modules/auth/api/login.js +4 -13
- package/dist/modules/auth/api/login.js.map +2 -2
- package/dist/modules/auth/commands/users.js +20 -14
- package/dist/modules/auth/commands/users.js.map +2 -2
- package/dist/modules/auth/data/entities.js +4 -2
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/lib/backendChrome.js +35 -2
- package/dist/modules/auth/lib/backendChrome.js.map +2 -2
- package/dist/modules/auth/lib/consentIntegrity.js +3 -3
- package/dist/modules/auth/lib/consentIntegrity.js.map +2 -2
- package/dist/modules/auth/migrations/Migration20260610120000.js +30 -0
- package/dist/modules/auth/migrations/Migration20260610120000.js.map +7 -0
- package/dist/modules/auth/migrations/Migration20260611103000.js +15 -0
- package/dist/modules/auth/migrations/Migration20260611103000.js.map +7 -0
- package/dist/modules/auth/services/authService.js +5 -3
- package/dist/modules/auth/services/authService.js.map +2 -2
- package/dist/modules/auth/services/rbacService.js +3 -2
- package/dist/modules/auth/services/rbacService.js.map +2 -2
- package/dist/modules/catalog/ai-tools/configuration-pack.js.map +1 -1
- package/dist/modules/catalog/ai-tools/prices-offers-pack.js.map +1 -1
- package/dist/modules/catalog/ai-tools/products-pack.js.map +1 -1
- package/dist/modules/catalog/ai-tools/variants-pack.js.map +1 -1
- package/dist/modules/communication_channels/data/entities.js.map +1 -1
- package/dist/modules/communication_channels/encryption.js.map +1 -1
- package/dist/modules/communication_channels/lib/thread-matcher.js.map +1 -1
- package/dist/modules/communication_channels/lib/thread-token.js.map +1 -1
- package/dist/modules/currencies/api/currencies/route.js +4 -3
- package/dist/modules/currencies/api/currencies/route.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles.js +2 -1
- package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +0 -3
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +2 -2
- package/dist/modules/customer_accounts/events.js +1 -1
- package/dist/modules/customer_accounts/events.js.map +1 -1
- package/dist/modules/customer_accounts/lib/resolveTenantContext.js.map +1 -1
- package/dist/modules/customers/acl.js +1 -1
- package/dist/modules/customers/acl.js.map +1 -1
- package/dist/modules/customers/ai-tools/companies-pack.js.map +1 -1
- package/dist/modules/customers/ai-tools/deals-pack.js.map +1 -1
- package/dist/modules/customers/ai-tools/people-pack.js.map +1 -1
- package/dist/modules/customers/api/companies/route.js +4 -4
- package/dist/modules/customers/api/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/route.js +43 -2
- package/dist/modules/customers/api/deals/route.js.map +2 -2
- package/dist/modules/customers/api/deals/summary/route.js +402 -0
- package/dist/modules/customers/api/deals/summary/route.js.map +7 -0
- package/dist/modules/customers/api/people/route.js +4 -4
- package/dist/modules/customers/api/people/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +16 -5
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +22 -5
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +12 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +221 -56
- package/dist/modules/customers/backend/customers/deals/page.js.map +3 -3
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js +1 -1
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +18 -0
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/cli.js +15 -9
- package/dist/modules/customers/cli.js.map +2 -2
- package/dist/modules/customers/commands/addresses.js +5 -5
- package/dist/modules/customers/commands/addresses.js.map +2 -2
- package/dist/modules/customers/commands/comments.js +5 -5
- package/dist/modules/customers/commands/comments.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +2 -2
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/entity-roles.js +2 -1
- package/dist/modules/customers/commands/entity-roles.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +8 -5
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/commands/shared.js +21 -6
- package/dist/modules/customers/commands/shared.js.map +2 -2
- package/dist/modules/customers/commands/tags.js +3 -3
- package/dist/modules/customers/commands/tags.js.map +2 -2
- package/dist/modules/customers/components/DealsKpiStrip.js +282 -0
- package/dist/modules/customers/components/DealsKpiStrip.js.map +7 -0
- package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +0 -1
- package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +100 -17
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonDetailTabs.js +11 -3
- package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +1 -2
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/assignableStaff.js +21 -8
- package/dist/modules/customers/components/detail/assignableStaff.js.map +2 -2
- package/dist/modules/customers/components/kpi/PipelineStageBar.js +63 -0
- package/dist/modules/customers/components/kpi/PipelineStageBar.js.map +7 -0
- package/dist/modules/customers/lib/dealsMetrics.js +82 -0
- package/dist/modules/customers/lib/dealsMetrics.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260519120000_pipeline_stage_color_tones.js.map +1 -1
- package/dist/modules/data_sync/api/run.js +1 -1
- package/dist/modules/data_sync/api/run.js.map +2 -2
- package/dist/modules/directory/api/organization-branding/route.js +214 -0
- package/dist/modules/directory/api/organization-branding/route.js.map +7 -0
- package/dist/modules/directory/api/organizations/route.js +7 -0
- package/dist/modules/directory/api/organizations/route.js.map +3 -3
- package/dist/modules/directory/backend/directory/branding/page.js +214 -0
- package/dist/modules/directory/backend/directory/branding/page.js.map +7 -0
- package/dist/modules/directory/backend/directory/branding/page.meta.js +26 -0
- package/dist/modules/directory/backend/directory/branding/page.meta.js.map +7 -0
- package/dist/modules/directory/commands/organizations.js +8 -1
- package/dist/modules/directory/commands/organizations.js.map +2 -2
- package/dist/modules/directory/data/entities.js +3 -0
- package/dist/modules/directory/data/entities.js.map +2 -2
- package/dist/modules/directory/data/validators.js +9 -0
- package/dist/modules/directory/data/validators.js.map +2 -2
- package/dist/modules/directory/migrations/Migration20260607222259_directory.js +13 -0
- package/dist/modules/directory/migrations/Migration20260607222259_directory.js.map +7 -0
- package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js +2 -1
- package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js.map +2 -2
- package/dist/modules/directory/utils/organizationScope.js +59 -27
- package/dist/modules/directory/utils/organizationScope.js.map +2 -2
- package/dist/modules/entities/api/definitions.batch.js +2 -1
- package/dist/modules/entities/api/definitions.batch.js.map +2 -2
- package/dist/modules/entities/api/entities.js +7 -0
- package/dist/modules/entities/api/entities.js.map +2 -2
- package/dist/modules/entities/api/records.js +26 -15
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +14 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js +14 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +12 -0
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/entities/components/useRecordsEntityGuard.js +30 -0
- package/dist/modules/entities/components/useRecordsEntityGuard.js.map +7 -0
- package/dist/modules/payment_gateways/api/transactions/route.js +2 -4
- package/dist/modules/payment_gateways/api/transactions/route.js.map +2 -2
- package/dist/modules/progress/api/jobs/[id]/route.js +7 -2
- package/dist/modules/progress/api/jobs/[id]/route.js.map +2 -2
- package/dist/modules/progress/api/jobs/route.js +1 -1
- package/dist/modules/progress/api/jobs/route.js.map +2 -2
- package/dist/modules/progress/lib/progressServiceImpl.js +8 -2
- package/dist/modules/progress/lib/progressServiceImpl.js.map +2 -2
- package/dist/modules/query_index/data/entities.js +2 -1
- package/dist/modules/query_index/data/entities.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +4 -2
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/migrations/Migration20260611103000_query_index.js +16 -0
- package/dist/modules/query_index/migrations/Migration20260611103000_query_index.js.map +7 -0
- package/dist/modules/resources/api/resources.js +2 -3
- package/dist/modules/resources/api/resources.js.map +2 -2
- package/dist/modules/sales/api/documents/factory.js +2 -2
- package/dist/modules/sales/api/documents/factory.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +7 -5
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +2 -1
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/salesDocumentsColumns.js +10 -0
- package/dist/modules/sales/components/documents/salesDocumentsColumns.js.map +7 -0
- package/dist/modules/staff/api/team-members.js +9 -2
- package/dist/modules/staff/api/team-members.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +24 -1
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +11 -6
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/commands/team-members.js +1 -1
- package/dist/modules/staff/commands/team-members.js.map +2 -2
- package/dist/modules/staff/components/TeamMemberForm.js +1 -1
- package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
- package/dist/modules/staff/lib/scheduleSwitch.js +23 -0
- package/dist/modules/staff/lib/scheduleSwitch.js.map +7 -0
- package/dist/modules/sync_excel/api/import/route.js +1 -1
- package/dist/modules/sync_excel/api/import/route.js.map +2 -2
- package/dist/modules/workflows/api/definitions/route.js +3 -2
- package/dist/modules/workflows/api/definitions/route.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/create/page.js +1 -2
- package/dist/modules/workflows/backend/definitions/create/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +1 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js +1 -2
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialog.js +4 -13
- package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialogCrudForm.js +4 -13
- package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowGraphImpl.js +1 -4
- package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +2 -5
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +2 -2
- package/generated/entities/organization/index.ts +1 -0
- package/generated/entity-fields-registry.ts +1 -0
- package/package.json +11 -12
- package/src/bootstrap.ts +65 -7
- package/src/helpers/integration/crmFixtures.ts +21 -1
- package/src/modules/attachments/AGENTS.md +79 -0
- package/src/modules/attachments/api/library/route.ts +2 -2
- package/src/modules/attachments/api/route.ts +2 -0
- package/src/modules/attachments/components/AttachmentContentPreview.tsx +6 -6
- package/src/modules/attachments/lib/access.ts +36 -0
- package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +14 -2
- package/src/modules/audit_logs/data/entities.ts +1 -0
- package/src/modules/audit_logs/migrations/.snapshot-open-mercato.json +10 -0
- package/src/modules/audit_logs/migrations/Migration20260611104500.ts +13 -0
- package/src/modules/audit_logs/services/accessLogService.ts +15 -0
- package/src/modules/auth/api/admin/nav.ts +9 -0
- package/src/modules/auth/api/login.ts +13 -13
- package/src/modules/auth/commands/users.ts +32 -15
- package/src/modules/auth/data/entities.ts +13 -1
- package/src/modules/auth/i18n/de.json +0 -1
- package/src/modules/auth/i18n/en.json +0 -1
- package/src/modules/auth/i18n/es.json +0 -1
- package/src/modules/auth/i18n/pl.json +0 -1
- package/src/modules/auth/lib/backendChrome.tsx +37 -1
- package/src/modules/auth/lib/consentIntegrity.ts +6 -3
- package/src/modules/auth/migrations/.snapshot-open-mercato.json +20 -10
- package/src/modules/auth/migrations/Migration20260610120000.ts +53 -0
- package/src/modules/auth/migrations/Migration20260611103000.ts +21 -0
- package/src/modules/auth/services/authService.ts +24 -4
- package/src/modules/auth/services/rbacService.ts +11 -2
- package/src/modules/catalog/ai-tools/configuration-pack.ts +1 -1
- package/src/modules/catalog/ai-tools/prices-offers-pack.ts +1 -1
- package/src/modules/catalog/ai-tools/products-pack.ts +1 -1
- package/src/modules/catalog/ai-tools/variants-pack.ts +1 -1
- package/src/modules/communication_channels/data/entities.ts +2 -2
- package/src/modules/communication_channels/encryption.ts +1 -1
- package/src/modules/communication_channels/lib/adapter.ts +1 -1
- package/src/modules/communication_channels/lib/thread-matcher.ts +1 -1
- package/src/modules/communication_channels/lib/thread-token.ts +1 -1
- package/src/modules/currencies/api/currencies/route.ts +4 -3
- package/src/modules/customer_accounts/api/admin/roles.ts +2 -1
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +0 -3
- package/src/modules/customer_accounts/events.ts +1 -1
- package/src/modules/customer_accounts/lib/resolveTenantContext.ts +2 -2
- package/src/modules/customers/acl.ts +1 -1
- package/src/modules/customers/ai-tools/companies-pack.ts +1 -1
- package/src/modules/customers/ai-tools/deals-pack.ts +1 -1
- package/src/modules/customers/ai-tools/people-pack.ts +1 -1
- package/src/modules/customers/api/companies/route.ts +4 -4
- package/src/modules/customers/api/deals/route.ts +51 -2
- package/src/modules/customers/api/deals/summary/route.ts +496 -0
- package/src/modules/customers/api/people/route.ts +4 -4
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +28 -6
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +33 -6
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +17 -2
- package/src/modules/customers/backend/customers/deals/page.tsx +254 -66
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +1 -2
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +18 -0
- package/src/modules/customers/cli.ts +15 -15
- package/src/modules/customers/commands/addresses.ts +5 -5
- package/src/modules/customers/commands/comments.ts +5 -5
- package/src/modules/customers/commands/deals.ts +2 -2
- package/src/modules/customers/commands/entity-roles.ts +2 -1
- package/src/modules/customers/commands/interactions.ts +8 -5
- package/src/modules/customers/commands/shared.ts +26 -4
- package/src/modules/customers/commands/tags.ts +3 -3
- package/src/modules/customers/components/DealsKpiStrip.tsx +389 -0
- package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +0 -1
- package/src/modules/customers/components/detail/DealForm.tsx +121 -19
- package/src/modules/customers/components/detail/PersonDetailTabs.tsx +12 -2
- package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +1 -2
- package/src/modules/customers/components/detail/assignableStaff.ts +32 -8
- package/src/modules/customers/components/kpi/PipelineStageBar.tsx +77 -0
- package/src/modules/customers/i18n/de.json +43 -0
- package/src/modules/customers/i18n/en.json +43 -0
- package/src/modules/customers/i18n/es.json +43 -0
- package/src/modules/customers/i18n/pl.json +43 -0
- package/src/modules/customers/lib/dealsMetrics.ts +159 -0
- package/src/modules/customers/migrations/Migration20260519120000_pipeline_stage_color_tones.ts +1 -1
- package/src/modules/data_sync/api/run.ts +1 -1
- package/src/modules/directory/api/organization-branding/route.ts +238 -0
- package/src/modules/directory/api/organizations/route.ts +7 -0
- package/src/modules/directory/backend/directory/branding/page.meta.ts +24 -0
- package/src/modules/directory/backend/directory/branding/page.tsx +248 -0
- package/src/modules/directory/commands/organizations.ts +9 -1
- package/src/modules/directory/data/entities.ts +3 -0
- package/src/modules/directory/data/validators.ts +12 -0
- package/src/modules/directory/i18n/de.json +21 -0
- package/src/modules/directory/i18n/en.json +21 -0
- package/src/modules/directory/i18n/es.json +21 -0
- package/src/modules/directory/i18n/pl.json +21 -0
- package/src/modules/directory/migrations/.snapshot-open-mercato.json +40 -0
- package/src/modules/directory/migrations/Migration20260607222259_directory.ts +13 -0
- package/src/modules/directory/subscribers/invalidateOrgScopeCache.ts +3 -1
- package/src/modules/directory/utils/organizationScope.ts +85 -30
- package/src/modules/entities/api/definitions.batch.ts +11 -7
- package/src/modules/entities/api/entities.ts +11 -0
- package/src/modules/entities/api/records.ts +46 -25
- package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +15 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/create/page.tsx +15 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +23 -0
- package/src/modules/entities/components/useRecordsEntityGuard.ts +41 -0
- package/src/modules/entities/i18n/de.json +1 -0
- package/src/modules/entities/i18n/en.json +1 -0
- package/src/modules/entities/i18n/es.json +1 -0
- package/src/modules/entities/i18n/pl.json +1 -0
- package/src/modules/payment_gateways/api/transactions/route.ts +2 -5
- package/src/modules/progress/api/jobs/[id]/route.ts +6 -1
- package/src/modules/progress/api/jobs/route.ts +1 -1
- package/src/modules/progress/lib/progressServiceImpl.ts +7 -1
- package/src/modules/query_index/data/entities.ts +1 -0
- package/src/modules/query_index/lib/engine.ts +11 -5
- package/src/modules/query_index/migrations/.snapshot-open-mercato.json +11 -0
- package/src/modules/query_index/migrations/Migration20260611103000_query_index.ts +29 -0
- package/src/modules/resources/api/resources.ts +2 -3
- package/src/modules/sales/api/documents/factory.ts +2 -2
- package/src/modules/sales/commands/documents.ts +7 -5
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +2 -1
- package/src/modules/sales/components/documents/salesDocumentsColumns.ts +6 -0
- package/src/modules/staff/AGENTS.md +1 -1
- package/src/modules/staff/api/team-members.ts +9 -2
- package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +31 -1
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +18 -8
- package/src/modules/staff/commands/team-members.ts +5 -2
- package/src/modules/staff/components/TeamMemberForm.tsx +4 -1
- package/src/modules/staff/i18n/de.json +1 -0
- package/src/modules/staff/i18n/en.json +1 -0
- package/src/modules/staff/i18n/es.json +1 -0
- package/src/modules/staff/i18n/pl.json +1 -0
- package/src/modules/staff/lib/scheduleSwitch.ts +46 -0
- package/src/modules/sync_excel/api/import/route.ts +1 -1
- package/src/modules/workflows/api/definitions/route.ts +3 -2
- package/src/modules/workflows/backend/definitions/create/page.tsx +1 -2
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +1 -2
- package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +1 -2
- package/src/modules/workflows/components/NodeEditDialog.tsx +1 -4
- package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +4 -7
- package/src/modules/workflows/components/WorkflowGraphImpl.tsx +1 -2
- package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +2 -3
|
@@ -53,7 +53,7 @@ type DictionaryDefault = {
|
|
|
53
53
|
type CustomFieldValuesPayload = Parameters<DataEngine['setCustomFields']>[0]['values']
|
|
54
54
|
type ProgressBarHandle = ReturnType<typeof createProgressBar>
|
|
55
55
|
|
|
56
|
-
const DEAL_STATUS_DEFAULTS: DictionaryDefault[] = [
|
|
56
|
+
export const DEAL_STATUS_DEFAULTS: DictionaryDefault[] = [
|
|
57
57
|
{ value: 'open', label: 'Open', color: '#2563eb', icon: 'lucide:circle' },
|
|
58
58
|
{ value: 'closed', label: 'Closed', color: '#6b7280', icon: 'lucide:check-circle' },
|
|
59
59
|
{ value: 'win', label: 'Win', color: '#22c55e', icon: 'lucide:trophy' },
|
|
@@ -61,7 +61,7 @@ const DEAL_STATUS_DEFAULTS: DictionaryDefault[] = [
|
|
|
61
61
|
{ value: 'in_progress', label: 'In progress', color: '#f59e0b', icon: 'lucide:activity' },
|
|
62
62
|
]
|
|
63
63
|
|
|
64
|
-
const PIPELINE_STAGE_DEFAULTS: DictionaryDefault[] = [
|
|
64
|
+
export const PIPELINE_STAGE_DEFAULTS: DictionaryDefault[] = [
|
|
65
65
|
{ value: 'opportunity', label: 'Opportunity', color: '#38bdf8', icon: 'lucide:target' },
|
|
66
66
|
{ value: 'marketing_qualified_lead', label: 'Marketing Qualified Lead', color: '#a855f7', icon: 'lucide:sparkles' },
|
|
67
67
|
{ value: 'sales_qualified_lead', label: 'Sales Qualified Lead', color: '#f97316', icon: 'lucide:users' },
|
|
@@ -72,14 +72,14 @@ const PIPELINE_STAGE_DEFAULTS: DictionaryDefault[] = [
|
|
|
72
72
|
{ value: 'stalled', label: 'Stalled', color: '#6b7280', icon: 'lucide:alert-circle' },
|
|
73
73
|
]
|
|
74
74
|
|
|
75
|
-
const ENTITY_STATUS_DEFAULTS: DictionaryDefault[] = [
|
|
75
|
+
export const ENTITY_STATUS_DEFAULTS: DictionaryDefault[] = [
|
|
76
76
|
{ value: 'active', label: 'Active', color: '#22c55e', icon: 'lucide:user-check' },
|
|
77
77
|
{ value: 'inactive', label: 'Inactive', color: '#94a3b8', icon: 'lucide:pause-circle' },
|
|
78
78
|
{ value: 'pending', label: 'Pending', color: '#f59e0b', icon: 'lucide:clock' },
|
|
79
79
|
{ value: 'archived', label: 'Archived', color: '#64748b', icon: 'lucide:archive' },
|
|
80
80
|
]
|
|
81
81
|
|
|
82
|
-
const ENTITY_LIFECYCLE_STAGE_DEFAULTS: DictionaryDefault[] = [
|
|
82
|
+
export const ENTITY_LIFECYCLE_STAGE_DEFAULTS: DictionaryDefault[] = [
|
|
83
83
|
{ value: 'lead', label: 'Lead', color: '#3b82f6', icon: 'lucide:sparkles' },
|
|
84
84
|
{ value: 'prospect', label: 'Prospect', color: '#8b5cf6', icon: 'lucide:eye' },
|
|
85
85
|
{ value: 'customer', label: 'Customer', color: '#22c55e', icon: 'lucide:handshake' },
|
|
@@ -88,7 +88,7 @@ const ENTITY_LIFECYCLE_STAGE_DEFAULTS: DictionaryDefault[] = [
|
|
|
88
88
|
{ value: 'other', label: 'Other', color: '#94a3b8', icon: 'lucide:circle' },
|
|
89
89
|
]
|
|
90
90
|
|
|
91
|
-
const ENTITY_SOURCE_DEFAULTS: DictionaryDefault[] = [
|
|
91
|
+
export const ENTITY_SOURCE_DEFAULTS: DictionaryDefault[] = [
|
|
92
92
|
{ value: 'linkedin', label: 'LinkedIn', color: '#0a66c2', icon: 'lucide:linkedin' },
|
|
93
93
|
{ value: 'email', label: 'Email', color: '#3b82f6', icon: 'lucide:mail' },
|
|
94
94
|
{ value: 'web_form', label: 'Web form', color: '#22c55e', icon: 'lucide:globe' },
|
|
@@ -291,7 +291,7 @@ function isoDaysFromNow(days: number, options?: { hour?: number; minute?: number
|
|
|
291
291
|
return base.toISOString()
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
294
|
+
export const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
295
295
|
{
|
|
296
296
|
slug: 'brightside-solar',
|
|
297
297
|
displayName: 'Brightside Solar',
|
|
@@ -307,7 +307,7 @@ const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
|
307
307
|
primaryPhone: '+1 415-555-0148',
|
|
308
308
|
source: 'partner_referral',
|
|
309
309
|
lifecycleStage: 'customer',
|
|
310
|
-
status: '
|
|
310
|
+
status: 'active',
|
|
311
311
|
custom: {
|
|
312
312
|
relationship_health: 'healthy',
|
|
313
313
|
renewal_quarter: 'Q3',
|
|
@@ -364,7 +364,7 @@ const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
|
364
364
|
phone: '+1 628-555-0199',
|
|
365
365
|
timezone: 'America/Los_Angeles',
|
|
366
366
|
linkedInUrl: 'https://www.linkedin.com/in/danielcho-energy/',
|
|
367
|
-
source: '
|
|
367
|
+
source: 'cold_outreach',
|
|
368
368
|
custom: {
|
|
369
369
|
buying_role: 'economic_buyer',
|
|
370
370
|
preferred_pronouns: 'he/him',
|
|
@@ -438,7 +438,7 @@ const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
|
438
438
|
valueCurrency: 'USD',
|
|
439
439
|
expectedCloseAt: isoDaysFromNow(65),
|
|
440
440
|
probability: 40,
|
|
441
|
-
source: '
|
|
441
|
+
source: 'web_form',
|
|
442
442
|
custom: {
|
|
443
443
|
competitive_risk: 'high',
|
|
444
444
|
implementation_complexity: 'complex',
|
|
@@ -513,7 +513,7 @@ const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
|
513
513
|
'Boston-based analytics platform helping consumer brands optimize merchandising decisions.',
|
|
514
514
|
primaryEmail: 'info@harborviewanalytics.com',
|
|
515
515
|
primaryPhone: '+1 617-555-0024',
|
|
516
|
-
source: '
|
|
516
|
+
source: 'event',
|
|
517
517
|
lifecycleStage: 'prospect',
|
|
518
518
|
status: 'active',
|
|
519
519
|
custom: {
|
|
@@ -545,7 +545,7 @@ const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
|
545
545
|
phone: '+1 617-555-0168',
|
|
546
546
|
timezone: 'America/New_York',
|
|
547
547
|
linkedInUrl: 'https://www.linkedin.com/in/arjunpatel-sales/',
|
|
548
|
-
source: '
|
|
548
|
+
source: 'event',
|
|
549
549
|
custom: {
|
|
550
550
|
buying_role: 'economic_buyer',
|
|
551
551
|
preferred_pronouns: 'he/him',
|
|
@@ -563,7 +563,7 @@ const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
|
563
563
|
phone: '+1 617-555-0179',
|
|
564
564
|
timezone: 'America/New_York',
|
|
565
565
|
linkedInUrl: 'https://www.linkedin.com/in/lenaortiz-retail/',
|
|
566
|
-
source: '
|
|
566
|
+
source: 'event',
|
|
567
567
|
custom: {
|
|
568
568
|
buying_role: 'champion',
|
|
569
569
|
preferred_pronouns: 'she/her',
|
|
@@ -582,7 +582,7 @@ const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
|
582
582
|
valueCurrency: 'USD',
|
|
583
583
|
expectedCloseAt: isoDaysFromNow(-25),
|
|
584
584
|
probability: 100,
|
|
585
|
-
source: '
|
|
585
|
+
source: 'event',
|
|
586
586
|
custom: {
|
|
587
587
|
competitive_risk: 'low',
|
|
588
588
|
implementation_complexity: 'standard',
|
|
@@ -637,7 +637,7 @@ const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
|
637
637
|
valueCurrency: 'USD',
|
|
638
638
|
expectedCloseAt: isoDaysFromNow(120),
|
|
639
639
|
probability: 35,
|
|
640
|
-
source: '
|
|
640
|
+
source: 'cold_outreach',
|
|
641
641
|
custom: {
|
|
642
642
|
competitive_risk: 'medium',
|
|
643
643
|
implementation_complexity: 'complex',
|
|
@@ -715,7 +715,7 @@ const CUSTOMER_EXAMPLES: ExampleCompany[] = [
|
|
|
715
715
|
primaryPhone: '+1 512-555-0456',
|
|
716
716
|
source: 'customer_referral',
|
|
717
717
|
lifecycleStage: 'customer',
|
|
718
|
-
status: '
|
|
718
|
+
status: 'active',
|
|
719
719
|
custom: {
|
|
720
720
|
relationship_health: 'healthy',
|
|
721
721
|
renewal_quarter: 'Q1',
|
|
@@ -109,7 +109,7 @@ const createAddressCommand: CommandHandler<AddressCreateInput, { addressId: stri
|
|
|
109
109
|
ensureOrganizationScope(ctx, parsed.organizationId)
|
|
110
110
|
|
|
111
111
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
112
|
-
const entity = await requireCustomerEntity(em, parsed.entityId, undefined, 'Customer not found')
|
|
112
|
+
const entity = await requireCustomerEntity(em, parsed.entityId, { tenantId: parsed.tenantId, organizationId: parsed.organizationId }, undefined, 'Customer not found')
|
|
113
113
|
ensureSameScope(entity, parsed.organizationId, parsed.tenantId)
|
|
114
114
|
|
|
115
115
|
const address = em.create(CustomerAddress, {
|
|
@@ -198,7 +198,7 @@ const createAddressCommand: CommandHandler<AddressCreateInput, { addressId: stri
|
|
|
198
198
|
throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for address create' })
|
|
199
199
|
}
|
|
200
200
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
201
|
-
const entity = await requireCustomerEntity(em, after.entityId, undefined, 'Customer not found')
|
|
201
|
+
const entity = await requireCustomerEntity(em, after.entityId, { tenantId: after.tenantId, organizationId: after.organizationId }, undefined, 'Customer not found')
|
|
202
202
|
let address = await findOneWithDecryption(
|
|
203
203
|
em,
|
|
204
204
|
CustomerAddress,
|
|
@@ -293,7 +293,7 @@ const updateAddressCommand: CommandHandler<AddressUpdateInput, { addressId: stri
|
|
|
293
293
|
ensureOrganizationScope(ctx, address.organizationId)
|
|
294
294
|
|
|
295
295
|
if (parsed.entityId !== undefined) {
|
|
296
|
-
const entity = await requireCustomerEntity(em, parsed.entityId, undefined, 'Customer not found')
|
|
296
|
+
const entity = await requireCustomerEntity(em, parsed.entityId, { tenantId: address.tenantId, organizationId: address.organizationId }, undefined, 'Customer not found')
|
|
297
297
|
ensureSameScope(entity, address.organizationId, address.tenantId)
|
|
298
298
|
address.entity = entity
|
|
299
299
|
}
|
|
@@ -396,7 +396,7 @@ const updateAddressCommand: CommandHandler<AddressUpdateInput, { addressId: stri
|
|
|
396
396
|
if (!before) return
|
|
397
397
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
398
398
|
let address = await em.findOne(CustomerAddress, { id: before.id })
|
|
399
|
-
const entity = await requireCustomerEntity(em, before.entityId, undefined, 'Customer not found')
|
|
399
|
+
const entity = await requireCustomerEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId }, undefined, 'Customer not found')
|
|
400
400
|
if (!address) {
|
|
401
401
|
address = em.create(CustomerAddress, {
|
|
402
402
|
id: before.id,
|
|
@@ -523,7 +523,7 @@ const deleteAddressCommand: CommandHandler<{ body?: Record<string, unknown>; que
|
|
|
523
523
|
const before = payload?.before
|
|
524
524
|
if (!before) return
|
|
525
525
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
526
|
-
const entity = await requireCustomerEntity(em, before.entityId, undefined, 'Customer not found')
|
|
526
|
+
const entity = await requireCustomerEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId }, undefined, 'Customer not found')
|
|
527
527
|
let address = await em.findOne(CustomerAddress, { id: before.id })
|
|
528
528
|
if (!address) {
|
|
529
529
|
address = em.create(CustomerAddress, {
|
|
@@ -84,7 +84,7 @@ const createCommentCommand: CommandHandler<CommentCreateInput, { commentId: stri
|
|
|
84
84
|
const normalizedAuthor = normalizeAuthorUserId(parsed.authorUserId, ctx.auth)
|
|
85
85
|
|
|
86
86
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
87
|
-
const entity = await requireTimelineParentEntity(em, parsed.entityId)
|
|
87
|
+
const entity = await requireTimelineParentEntity(em, parsed.entityId, { tenantId: parsed.tenantId, organizationId: parsed.organizationId })
|
|
88
88
|
ensureSameScope(entity, parsed.organizationId, parsed.tenantId)
|
|
89
89
|
const deal = await requireDealInScope(em, parsed.dealId, parsed.tenantId, parsed.organizationId)
|
|
90
90
|
|
|
@@ -176,7 +176,7 @@ const createCommentCommand: CommandHandler<CommentCreateInput, { commentId: stri
|
|
|
176
176
|
appearanceColor: snapshot.appearanceColor,
|
|
177
177
|
}),
|
|
178
178
|
beforeRestore: async ({ em, snapshot }) => {
|
|
179
|
-
const entity = await requireTimelineParentEntity(em, snapshot.entityId)
|
|
179
|
+
const entity = await requireTimelineParentEntity(em, snapshot.entityId, { tenantId: snapshot.tenantId, organizationId: snapshot.organizationId })
|
|
180
180
|
const deal = await requireDealInScope(em, snapshot.dealId, snapshot.tenantId, snapshot.organizationId)
|
|
181
181
|
return { entity, deal }
|
|
182
182
|
},
|
|
@@ -201,7 +201,7 @@ const updateCommentCommand: CommandHandler<CommentUpdateInput, { commentId: stri
|
|
|
201
201
|
ensureOrganizationScope(ctx, comment.organizationId)
|
|
202
202
|
|
|
203
203
|
if (parsed.entityId !== undefined) {
|
|
204
|
-
const entity = await requireTimelineParentEntity(em, parsed.entityId)
|
|
204
|
+
const entity = await requireTimelineParentEntity(em, parsed.entityId, { tenantId: comment.tenantId, organizationId: comment.organizationId })
|
|
205
205
|
ensureSameScope(entity, comment.organizationId, comment.tenantId)
|
|
206
206
|
comment.entity = entity
|
|
207
207
|
}
|
|
@@ -275,7 +275,7 @@ const updateCommentCommand: CommandHandler<CommentUpdateInput, { commentId: stri
|
|
|
275
275
|
if (!before) return
|
|
276
276
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
277
277
|
let comment = await em.findOne(CustomerComment, { id: before.id })
|
|
278
|
-
const entity = await requireTimelineParentEntity(em, before.entityId)
|
|
278
|
+
const entity = await requireTimelineParentEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId })
|
|
279
279
|
const deal = await requireDealInScope(em, before.dealId, before.tenantId, before.organizationId)
|
|
280
280
|
|
|
281
281
|
if (!comment) {
|
|
@@ -380,7 +380,7 @@ const deleteCommentCommand: CommandHandler<{ body?: Record<string, unknown>; que
|
|
|
380
380
|
const before = payload?.before
|
|
381
381
|
if (!before) return
|
|
382
382
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
383
|
-
const entity = await requireTimelineParentEntity(em, before.entityId)
|
|
383
|
+
const entity = await requireTimelineParentEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId })
|
|
384
384
|
const deal = await requireDealInScope(em, before.dealId, before.tenantId, before.organizationId)
|
|
385
385
|
let comment = await em.findOne(CustomerComment, { id: before.id })
|
|
386
386
|
if (!comment) {
|
|
@@ -376,7 +376,7 @@ async function syncDealPeople(
|
|
|
376
376
|
if (!personIds || !personIds.length) return
|
|
377
377
|
const unique = Array.from(new Set(personIds))
|
|
378
378
|
for (const personId of unique) {
|
|
379
|
-
const person = await requireCustomerEntity(em, personId, 'person', 'Person not found')
|
|
379
|
+
const person = await requireCustomerEntity(em, personId, { tenantId: deal.tenantId, organizationId: deal.organizationId }, 'person', 'Person not found')
|
|
380
380
|
ensureSameScope(person, deal.organizationId, deal.tenantId)
|
|
381
381
|
const link = em.create(CustomerDealPersonLink, {
|
|
382
382
|
deal,
|
|
@@ -396,7 +396,7 @@ async function syncDealCompanies(
|
|
|
396
396
|
if (!companyIds || !companyIds.length) return
|
|
397
397
|
const unique = Array.from(new Set(companyIds))
|
|
398
398
|
for (const companyId of unique) {
|
|
399
|
-
const company = await requireCustomerEntity(em, companyId, 'company', 'Company not found')
|
|
399
|
+
const company = await requireCustomerEntity(em, companyId, { tenantId: deal.tenantId, organizationId: deal.organizationId }, 'company', 'Company not found')
|
|
400
400
|
ensureSameScope(company, deal.organizationId, deal.tenantId)
|
|
401
401
|
const link = em.create(CustomerDealCompanyLink, {
|
|
402
402
|
deal,
|
|
@@ -137,7 +137,7 @@ const createEntityRoleCommand: CommandHandler<EntityRoleCreateInput, { roleId: s
|
|
|
137
137
|
ensureOrganizationScope(ctx, parsed.organizationId)
|
|
138
138
|
|
|
139
139
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
140
|
-
const entity = await requireCustomerEntity(em, parsed.entityId, parsed.entityType, 'Customer not found')
|
|
140
|
+
const entity = await requireCustomerEntity(em, parsed.entityId, { tenantId: parsed.tenantId, organizationId: parsed.organizationId }, parsed.entityType, 'Customer not found')
|
|
141
141
|
ensureSameScope(entity, parsed.organizationId, parsed.tenantId)
|
|
142
142
|
|
|
143
143
|
const activeExisting = await findOneWithDecryption(
|
|
@@ -495,6 +495,7 @@ const deleteEntityRoleCommand: CommandHandler<EntityRoleDeleteInput, { roleId: s
|
|
|
495
495
|
const entity = await requireCustomerEntity(
|
|
496
496
|
em,
|
|
497
497
|
before.role.entityId,
|
|
498
|
+
{ tenantId: before.role.tenantId, organizationId: before.role.organizationId },
|
|
498
499
|
before.role.entityType,
|
|
499
500
|
'Customer not found',
|
|
500
501
|
)
|
|
@@ -374,7 +374,7 @@ const createInteractionCommand: CommandHandler<InteractionCreateInput, { interac
|
|
|
374
374
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
375
375
|
const normalizedAuthor = normalizeAuthorUserId(parsed.authorUserId ?? null, ctx.auth)
|
|
376
376
|
const { interaction, entityId, nextInteractionId } = await runInTransaction(em, async (trx) => {
|
|
377
|
-
const entity = await requireTimelineParentEntity(trx, parsed.entityId)
|
|
377
|
+
const entity = await requireTimelineParentEntity(trx, parsed.entityId, { tenantId: parsed.tenantId, organizationId: parsed.organizationId })
|
|
378
378
|
ensureTenantScope(ctx, entity.tenantId)
|
|
379
379
|
ensureOrganizationScope(ctx, entity.organizationId)
|
|
380
380
|
|
|
@@ -510,7 +510,7 @@ const createInteractionCommand: CommandHandler<InteractionCreateInput, { interac
|
|
|
510
510
|
}
|
|
511
511
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
512
512
|
const { interaction, nextInteractionId } = await runInTransaction(em, async (trx) => {
|
|
513
|
-
const entity = await requireTimelineParentEntity(trx, after.interaction.entityId)
|
|
513
|
+
const entity = await requireTimelineParentEntity(trx, after.interaction.entityId, { tenantId: after.interaction.tenantId, organizationId: after.interaction.organizationId })
|
|
514
514
|
let interaction = await findOneWithDecryption(trx, CustomerInteraction, { id: after.interaction.id })
|
|
515
515
|
if (!interaction) {
|
|
516
516
|
interaction = buildInteractionGraph(trx, {
|
|
@@ -781,7 +781,7 @@ const updateInteractionCommand: CommandHandler<InteractionUpdateInput, { interac
|
|
|
781
781
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
782
782
|
const { interaction, nextInteractionId } = await runInTransaction(em, async (trx) => {
|
|
783
783
|
let interaction = await findOneWithDecryption(trx, CustomerInteraction, { id: before.interaction.id })
|
|
784
|
-
const entity = await requireTimelineParentEntity(trx, before.interaction.entityId)
|
|
784
|
+
const entity = await requireTimelineParentEntity(trx, before.interaction.entityId, { tenantId: before.interaction.tenantId, organizationId: before.interaction.organizationId })
|
|
785
785
|
|
|
786
786
|
if (!interaction) {
|
|
787
787
|
interaction = trx.create(CustomerInteraction, {
|
|
@@ -1252,7 +1252,7 @@ const deleteInteractionCommand: CommandHandler<{ body?: Record<string, unknown>;
|
|
|
1252
1252
|
if (!before) return
|
|
1253
1253
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
1254
1254
|
const { interaction, nextInteractionId } = await runInTransaction(em, async (trx) => {
|
|
1255
|
-
const entity = await requireTimelineParentEntity(trx, before.interaction.entityId)
|
|
1255
|
+
const entity = await requireTimelineParentEntity(trx, before.interaction.entityId, { tenantId: before.interaction.tenantId, organizationId: before.interaction.organizationId })
|
|
1256
1256
|
let interaction = await findOneWithDecryption(trx, CustomerInteraction, { id: before.interaction.id })
|
|
1257
1257
|
if (!interaction) {
|
|
1258
1258
|
interaction = trx.create(CustomerInteraction, {
|
|
@@ -1372,7 +1372,10 @@ const recomputeNextCommand: CommandHandler<{ entityId: string }, { entityId: str
|
|
|
1372
1372
|
const parsed = recomputeNextSchema.parse(rawInput)
|
|
1373
1373
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
1374
1374
|
const projection = await recomputeNextInteraction(em, parsed.entityId)
|
|
1375
|
-
const entity = await requireTimelineParentEntity(em, parsed.entityId
|
|
1375
|
+
const entity = await requireTimelineParentEntity(em, parsed.entityId, {
|
|
1376
|
+
tenantId: ctx.auth?.tenantId ?? '',
|
|
1377
|
+
organizationId: ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? '',
|
|
1378
|
+
})
|
|
1376
1379
|
await emitNextInteractionUpdatedEvent(ctx, {
|
|
1377
1380
|
entityId: parsed.entityId,
|
|
1378
1381
|
nextInteractionId: projection.nextInteractionId,
|
|
@@ -26,13 +26,24 @@ export function normalizeDictionaryIcon(input: unknown): string | null {
|
|
|
26
26
|
|
|
27
27
|
export { assertFound } from '@open-mercato/shared/lib/crud/errors'
|
|
28
28
|
|
|
29
|
+
export type CustomerEntityScope = {
|
|
30
|
+
tenantId: string
|
|
31
|
+
organizationId: string
|
|
32
|
+
}
|
|
33
|
+
|
|
29
34
|
export async function requireCustomerEntity(
|
|
30
35
|
em: EntityManager,
|
|
31
36
|
id: string,
|
|
37
|
+
scope: CustomerEntityScope,
|
|
32
38
|
kind?: CustomerEntityKind,
|
|
33
39
|
message = 'Customer entity not found'
|
|
34
40
|
): Promise<CustomerEntity> {
|
|
35
|
-
const entity = await em.findOne(CustomerEntity, {
|
|
41
|
+
const entity = await em.findOne(CustomerEntity, {
|
|
42
|
+
id,
|
|
43
|
+
deletedAt: null,
|
|
44
|
+
tenantId: scope.tenantId,
|
|
45
|
+
organizationId: scope.organizationId,
|
|
46
|
+
})
|
|
36
47
|
if (!entity) throw new CrudHttpError(404, { error: message })
|
|
37
48
|
if (kind && entity.kind !== kind) {
|
|
38
49
|
throw new CrudHttpError(400, { error: 'Invalid entity type' })
|
|
@@ -43,15 +54,26 @@ export async function requireCustomerEntity(
|
|
|
43
54
|
export async function requireTimelineParentEntity(
|
|
44
55
|
em: EntityManager,
|
|
45
56
|
id: string,
|
|
57
|
+
scope: CustomerEntityScope,
|
|
46
58
|
): Promise<CustomerEntity> {
|
|
47
|
-
const entity = await em.findOne(CustomerEntity, {
|
|
59
|
+
const entity = await em.findOne(CustomerEntity, {
|
|
60
|
+
id,
|
|
61
|
+
deletedAt: null,
|
|
62
|
+
tenantId: scope.tenantId,
|
|
63
|
+
organizationId: scope.organizationId,
|
|
64
|
+
})
|
|
48
65
|
if (entity) {
|
|
49
66
|
if (entity.kind !== 'person' && entity.kind !== 'company') {
|
|
50
67
|
throw new CrudHttpError(422, { error: 'entityId must reference a person or company' })
|
|
51
68
|
}
|
|
52
69
|
return entity
|
|
53
70
|
}
|
|
54
|
-
const deal = await em.findOne(CustomerDeal, {
|
|
71
|
+
const deal = await em.findOne(CustomerDeal, {
|
|
72
|
+
id,
|
|
73
|
+
deletedAt: null,
|
|
74
|
+
tenantId: scope.tenantId,
|
|
75
|
+
organizationId: scope.organizationId,
|
|
76
|
+
})
|
|
55
77
|
if (deal) {
|
|
56
78
|
throw new CrudHttpError(422, { error: 'entityId must reference a person or company, not a deal' })
|
|
57
79
|
}
|
|
@@ -111,7 +133,7 @@ export async function requireDealInScope(
|
|
|
111
133
|
organizationId: string
|
|
112
134
|
): Promise<CustomerDeal | null> {
|
|
113
135
|
if (!dealId) return null
|
|
114
|
-
const deal = await em.findOne(CustomerDeal, { id: dealId, deletedAt: null })
|
|
136
|
+
const deal = await em.findOne(CustomerDeal, { id: dealId, deletedAt: null, tenantId, organizationId })
|
|
115
137
|
if (!deal) throw new CrudHttpError(400, { error: 'Deal not found' })
|
|
116
138
|
ensureSameScope(deal, organizationId, tenantId)
|
|
117
139
|
return deal
|
|
@@ -387,7 +387,7 @@ const assignTagCommand: CommandHandler<TagAssignmentInput, { assignmentId: strin
|
|
|
387
387
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
388
388
|
const tag = await em.findOne(CustomerTag, { id: parsed.tagId, tenantId: parsed.tenantId, organizationId: parsed.organizationId })
|
|
389
389
|
if (!tag) throw new CrudHttpError(404, { error: 'Tag not found' })
|
|
390
|
-
const entity = await requireCustomerEntity(em, parsed.entityId, undefined, 'Customer not found')
|
|
390
|
+
const entity = await requireCustomerEntity(em, parsed.entityId, { tenantId: parsed.tenantId, organizationId: parsed.organizationId }, undefined, 'Customer not found')
|
|
391
391
|
ensureSameScope(entity, parsed.organizationId, parsed.tenantId)
|
|
392
392
|
const tagIds = await loadEntityTagIds(em, entity)
|
|
393
393
|
if (tagIds.includes(parsed.tagId)) {
|
|
@@ -478,7 +478,7 @@ const assignTagCommand: CommandHandler<TagAssignmentInput, { assignmentId: strin
|
|
|
478
478
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
479
479
|
const tag = await em.findOne(CustomerTag, { id: before.tagId })
|
|
480
480
|
if (!tag) throw new CrudHttpError(404, { error: 'Tag not found' })
|
|
481
|
-
const entity = await requireCustomerEntity(em, before.entityId, undefined, 'Customer not found')
|
|
481
|
+
const entity = await requireCustomerEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId }, undefined, 'Customer not found')
|
|
482
482
|
ensureSameScope(entity, before.organizationId, before.tenantId)
|
|
483
483
|
|
|
484
484
|
let assignment = await em.findOne(CustomerTagAssignment, {
|
|
@@ -589,7 +589,7 @@ const unassignTagCommand: CommandHandler<TagAssignmentInput, { assignmentId: str
|
|
|
589
589
|
if (!before) return
|
|
590
590
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
591
591
|
const tag = await em.findOne(CustomerTag, { id: before.tagId })
|
|
592
|
-
const entity = await requireCustomerEntity(em, before.entityId, undefined, 'Customer not found')
|
|
592
|
+
const entity = await requireCustomerEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId }, undefined, 'Customer not found')
|
|
593
593
|
ensureSameScope(entity, before.organizationId, before.tenantId)
|
|
594
594
|
if (!tag) throw new CrudHttpError(404, { error: 'Tag not found' })
|
|
595
595
|
const existing = await em.findOne(CustomerTagAssignment, {
|