@open-mercato/core 0.6.4-develop.4371.1.8f3030407e → 0.6.4
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/AGENTS.md +37 -0
- package/dist/generated/entities/channel_ingest_dead_letter/index.js +25 -0
- package/dist/generated/entities/channel_ingest_dead_letter/index.js.map +7 -0
- package/dist/generated/entities/channel_thread_mapping/index.js +25 -0
- package/dist/generated/entities/channel_thread_mapping/index.js.map +7 -0
- package/dist/generated/entities/channel_thread_token/index.js +17 -0
- package/dist/generated/entities/channel_thread_token/index.js.map +7 -0
- package/dist/generated/entities/communication_channel/index.js +43 -0
- package/dist/generated/entities/communication_channel/index.js.map +7 -0
- package/dist/generated/entities/customer_interaction/index.js +4 -0
- package/dist/generated/entities/customer_interaction/index.js.map +2 -2
- package/dist/generated/entities/customer_settings/index.js +2 -0
- package/dist/generated/entities/customer_settings/index.js.map +2 -2
- package/dist/generated/entities/dictionary/index.js +2 -0
- package/dist/generated/entities/dictionary/index.js.map +2 -2
- package/dist/generated/entities/external_conversation/index.js +25 -0
- package/dist/generated/entities/external_conversation/index.js.map +7 -0
- package/dist/generated/entities/external_message/index.js +25 -0
- package/dist/generated/entities/external_message/index.js.map +7 -0
- package/dist/generated/entities/inbox_settings/index.js +2 -0
- package/dist/generated/entities/inbox_settings/index.js.map +2 -2
- package/dist/generated/entities/integration_credentials/index.js +3 -1
- package/dist/generated/entities/integration_credentials/index.js.map +2 -2
- package/dist/generated/entities/message/index.js +2 -0
- package/dist/generated/entities/message/index.js.map +2 -2
- package/dist/generated/entities/message_channel_link/index.js +33 -0
- package/dist/generated/entities/message_channel_link/index.js.map +7 -0
- package/dist/generated/entities/message_reaction/index.js +25 -0
- package/dist/generated/entities/message_reaction/index.js.map +7 -0
- package/dist/generated/entities/role/index.js +3 -1
- package/dist/generated/entities/role/index.js.map +2 -2
- package/dist/generated/entities/step_instance/index.js +2 -0
- package/dist/generated/entities/step_instance/index.js.map +2 -2
- package/dist/generated/entities/user/index.js +3 -1
- package/dist/generated/entities/user/index.js.map +2 -2
- package/dist/generated/entities/user_task/index.js +2 -0
- package/dist/generated/entities/user_task/index.js.map +2 -2
- package/dist/generated/entities/workflow_branch_instance/index.js +39 -0
- package/dist/generated/entities/workflow_branch_instance/index.js.map +7 -0
- package/dist/generated/entities/workflow_event/index.js +2 -0
- package/dist/generated/entities/workflow_event/index.js.map +2 -2
- package/dist/generated/entities/workflow_instance/index.js +2 -0
- package/dist/generated/entities/workflow_instance/index.js.map +2 -2
- package/dist/generated/entities.ids.generated.js +12 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +146 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/api.js +14 -1
- package/dist/helpers/integration/api.js.map +2 -2
- package/dist/helpers/integration/authFixtures.js +2 -1
- package/dist/helpers/integration/authFixtures.js.map +2 -2
- package/dist/helpers/integration/communicationChannelsFixtures.js +58 -0
- package/dist/helpers/integration/communicationChannelsFixtures.js.map +7 -0
- package/dist/helpers/integration/crudFormFields.js +33 -0
- package/dist/helpers/integration/crudFormFields.js.map +7 -0
- package/dist/helpers/integration/crudFormPersistence.js +107 -0
- package/dist/helpers/integration/crudFormPersistence.js.map +7 -0
- package/dist/helpers/integration/currenciesFixtures.js +52 -1
- package/dist/helpers/integration/currenciesFixtures.js.map +2 -2
- package/dist/helpers/integration/customerAccountsFixtures.js +124 -0
- package/dist/helpers/integration/customerAccountsFixtures.js.map +7 -0
- package/dist/helpers/integration/dbFixtures.js +9 -1
- package/dist/helpers/integration/dbFixtures.js.map +2 -2
- package/dist/helpers/integration/inboxFixtures.js +11 -0
- package/dist/helpers/integration/inboxFixtures.js.map +2 -2
- package/dist/helpers/integration/optimisticLockUi.js +104 -0
- package/dist/helpers/integration/optimisticLockUi.js.map +7 -0
- package/dist/helpers/integration/salesFixtures.js +17 -0
- package/dist/helpers/integration/salesFixtures.js.map +2 -2
- package/dist/helpers/integration/salesUi.js +17 -9
- package/dist/helpers/integration/salesUi.js.map +2 -2
- package/dist/helpers/integration/standaloneEnv.js +58 -0
- package/dist/helpers/integration/standaloneEnv.js.map +7 -0
- package/dist/helpers/integration/undoHarness.js +177 -0
- package/dist/helpers/integration/undoHarness.js.map +7 -0
- package/dist/helpers/integration/workflowsFixtures.js +161 -0
- package/dist/helpers/integration/workflowsFixtures.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/page.js +18 -5
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/api_keys/data/validators.js +3 -1
- package/dist/modules/api_keys/data/validators.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +17 -9
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
- package/dist/modules/attachments/lib/ocrQueue.js +6 -1
- package/dist/modules/attachments/lib/ocrQueue.js.map +2 -2
- package/dist/modules/attachments/lib/security.js +1 -1
- package/dist/modules/attachments/lib/security.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +4 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/undo/route.js +3 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/undo/route.js.map +2 -2
- package/dist/modules/audit_logs/data/entities.js.map +1 -1
- package/dist/modules/audit_logs/services/actionLogService.js +16 -0
- package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
- package/dist/modules/auth/api/logout.js +0 -12
- package/dist/modules/auth/api/logout.js.map +2 -2
- package/dist/modules/auth/api/roles/acl/route.js +32 -13
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/roles/route.js +52 -3
- package/dist/modules/auth/api/roles/route.js.map +2 -2
- package/dist/modules/auth/api/sidebar/preferences/route.js +73 -4
- package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +88 -34
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/consents/route.js +17 -0
- package/dist/modules/auth/api/users/consents/route.js.map +2 -2
- package/dist/modules/auth/api/users/resend-invite/route.js +18 -0
- package/dist/modules/auth/api/users/resend-invite/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +40 -2
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/roles/[id]/edit/page.js +24 -4
- package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +17 -4
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +72 -7
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +15 -2
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/auth/cli.js +19 -21
- package/dist/modules/auth/cli.js.map +2 -2
- package/dist/modules/auth/commands/roles.js +78 -1
- package/dist/modules/auth/commands/roles.js.map +2 -2
- package/dist/modules/auth/commands/users.js +106 -6
- package/dist/modules/auth/commands/users.js.map +3 -3
- package/dist/modules/auth/components/AclEditor.js +3 -1
- package/dist/modules/auth/components/AclEditor.js.map +2 -2
- package/dist/modules/auth/data/entities.js +6 -0
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/frontend/reset/[token]/page.js +6 -2
- package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
- package/dist/modules/auth/lib/consentIntegrity.js +15 -2
- package/dist/modules/auth/lib/consentIntegrity.js.map +2 -2
- package/dist/modules/auth/lib/emailHash.js +6 -2
- package/dist/modules/auth/lib/emailHash.js.map +2 -2
- package/dist/modules/auth/lib/grantChecks.js +44 -1
- package/dist/modules/auth/lib/grantChecks.js.map +2 -2
- package/dist/modules/auth/lib/sessionIntegrity.js +11 -1
- package/dist/modules/auth/lib/sessionIntegrity.js.map +2 -2
- package/dist/modules/auth/services/authService.js +10 -19
- package/dist/modules/auth/services/authService.js.map +2 -2
- package/dist/modules/auth/services/sidebarPreferencesService.js +32 -4
- package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
- package/dist/modules/business_rules/api/rules/route.js +28 -0
- package/dist/modules/business_rules/api/rules/route.js.map +2 -2
- package/dist/modules/business_rules/api/sets/route.js +28 -0
- package/dist/modules/business_rules/api/sets/route.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/[id]/page.js +11 -4
- package/dist/modules/business_rules/backend/rules/[id]/page.js.map +3 -3
- package/dist/modules/business_rules/backend/rules/page.js +30 -12
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/[id]/page.js +11 -4
- package/dist/modules/business_rules/backend/sets/[id]/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/page.js +29 -11
- package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
- package/dist/modules/catalog/api/categories/route.js +2 -0
- package/dist/modules/catalog/api/categories/route.js.map +2 -2
- package/dist/modules/catalog/api/products/route.js +2 -1
- package/dist/modules/catalog/api/products/route.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +2 -0
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +138 -75
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +87 -24
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js +18 -3
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/create/page.js +4 -17
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js.map +2 -2
- package/dist/modules/catalog/commands/categories.js +42 -1
- package/dist/modules/catalog/commands/categories.js.map +2 -2
- package/dist/modules/catalog/commands/offers.js +44 -1
- package/dist/modules/catalog/commands/offers.js.map +2 -2
- package/dist/modules/catalog/commands/optionSchemas.js +6 -1
- package/dist/modules/catalog/commands/optionSchemas.js.map +2 -2
- package/dist/modules/catalog/commands/priceKinds.js +6 -1
- package/dist/modules/catalog/commands/priceKinds.js.map +2 -2
- package/dist/modules/catalog/commands/prices.js +50 -1
- package/dist/modules/catalog/commands/prices.js.map +2 -2
- package/dist/modules/catalog/commands/productUnitConversions.js +25 -1
- package/dist/modules/catalog/commands/productUnitConversions.js.map +2 -2
- package/dist/modules/catalog/commands/products.js +84 -0
- package/dist/modules/catalog/commands/products.js.map +2 -2
- package/dist/modules/catalog/commands/variants.js +117 -31
- package/dist/modules/catalog/commands/variants.js.map +2 -2
- package/dist/modules/catalog/components/PriceKindSettings.js +14 -6
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js +9 -0
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductMediaManager.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +14 -3
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/VariantBuilder.js +38 -11
- package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
- package/dist/modules/catalog/components/products/productForm.js +21 -0
- package/dist/modules/catalog/components/products/productForm.js.map +2 -2
- package/dist/modules/catalog/components/products/variantForm.js +2 -1
- package/dist/modules/catalog/components/products/variantForm.js.map +2 -2
- package/dist/modules/catalog/lib/pricing.js +3 -0
- package/dist/modules/catalog/lib/pricing.js.map +2 -2
- package/dist/modules/communication_channels/acl.js +47 -0
- package/dist/modules/communication_channels/acl.js.map +7 -0
- package/dist/modules/communication_channels/api/delete/channels/[id]/route.js +133 -0
- package/dist/modules/communication_channels/api/delete/channels/[id]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.js +113 -0
- package/dist/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/health/route.js +138 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/health/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/route.js +93 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/channels/route.js +96 -0
- package/dist/modules/communication_channels/api/get/channels/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/me/channels/route.js +82 -0
- package/dist/modules/communication_channels/api/get/me/channels/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js +274 -0
- package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js +168 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/poll-now/route.js +143 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/poll-now/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js +127 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/set-primary/route.js +99 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/set-primary/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +197 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js +124 -0
- package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/messages/[messageId]/reactions/route.js +120 -0
- package/dist/modules/communication_channels/api/post/messages/[messageId]/reactions/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js +157 -0
- package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/send-as-user/route.js +115 -0
- package/dist/modules/communication_channels/api/post/send-as-user/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/test-seed/route.js +238 -0
- package/dist/modules/communication_channels/api/post/test-seed/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js +175 -0
- package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js +123 -0
- package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js.map +7 -0
- package/dist/modules/communication_channels/api/put/threads/[threadId]/assign/route.js +117 -0
- package/dist/modules/communication_channels/api/put/threads/[threadId]/assign/route.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js +180 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.js +36 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +107 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.meta.js +38 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.meta.js.map +7 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +732 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +7 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.meta.js +38 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.meta.js.map +7 -0
- package/dist/modules/communication_channels/commands/connect-credential-channel.js +154 -0
- package/dist/modules/communication_channels/commands/connect-credential-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/delete-channel.js +137 -0
- package/dist/modules/communication_channels/commands/delete-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/deliver-outbound-message.js +400 -0
- package/dist/modules/communication_channels/commands/deliver-outbound-message.js.map +7 -0
- package/dist/modules/communication_channels/commands/disconnect-channel.js +163 -0
- package/dist/modules/communication_channels/commands/disconnect-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js +413 -0
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +7 -0
- package/dist/modules/communication_channels/commands/interceptors.js +68 -0
- package/dist/modules/communication_channels/commands/interceptors.js.map +7 -0
- package/dist/modules/communication_channels/commands/process-inbound-reaction.js +198 -0
- package/dist/modules/communication_channels/commands/process-inbound-reaction.js.map +7 -0
- package/dist/modules/communication_channels/commands/push-register.js +146 -0
- package/dist/modules/communication_channels/commands/push-register.js.map +7 -0
- package/dist/modules/communication_channels/commands/push-renew.js +23 -0
- package/dist/modules/communication_channels/commands/push-renew.js.map +7 -0
- package/dist/modules/communication_channels/commands/push-unregister.js +108 -0
- package/dist/modules/communication_channels/commands/push-unregister.js.map +7 -0
- package/dist/modules/communication_channels/commands/queue-import-history.js +113 -0
- package/dist/modules/communication_channels/commands/queue-import-history.js.map +7 -0
- package/dist/modules/communication_channels/commands/reassign-conversation.js +193 -0
- package/dist/modules/communication_channels/commands/reassign-conversation.js.map +7 -0
- package/dist/modules/communication_channels/commands/set-primary-channel.js +115 -0
- package/dist/modules/communication_channels/commands/set-primary-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/toggle-outbound-reaction.js +260 -0
- package/dist/modules/communication_channels/commands/toggle-outbound-reaction.js.map +7 -0
- package/dist/modules/communication_channels/data/enrichers.js +286 -0
- package/dist/modules/communication_channels/data/enrichers.js.map +7 -0
- package/dist/modules/communication_channels/data/entities.js +447 -0
- package/dist/modules/communication_channels/data/entities.js.map +7 -0
- package/dist/modules/communication_channels/data/extensions.js +67 -0
- package/dist/modules/communication_channels/data/extensions.js.map +7 -0
- package/dist/modules/communication_channels/data/validators.js +123 -0
- package/dist/modules/communication_channels/data/validators.js.map +7 -0
- package/dist/modules/communication_channels/di.js +35 -0
- package/dist/modules/communication_channels/di.js.map +7 -0
- package/dist/modules/communication_channels/encryption.js +12 -0
- package/dist/modules/communication_channels/encryption.js.map +7 -0
- package/dist/modules/communication_channels/events.js +124 -0
- package/dist/modules/communication_channels/events.js.map +7 -0
- package/dist/modules/communication_channels/index.js +20 -0
- package/dist/modules/communication_channels/index.js.map +7 -0
- package/dist/modules/communication_channels/lib/access-control.js +43 -0
- package/dist/modules/communication_channels/lib/access-control.js.map +7 -0
- package/dist/modules/communication_channels/lib/adapter-compat.js +36 -0
- package/dist/modules/communication_channels/lib/adapter-compat.js.map +7 -0
- package/dist/modules/communication_channels/lib/adapter-registry-singleton.js +22 -0
- package/dist/modules/communication_channels/lib/adapter-registry-singleton.js.map +7 -0
- package/dist/modules/communication_channels/lib/adapter.js +1 -0
- package/dist/modules/communication_channels/lib/adapter.js.map +7 -0
- package/dist/modules/communication_channels/lib/connect-channel.js +95 -0
- package/dist/modules/communication_channels/lib/connect-channel.js.map +7 -0
- package/dist/modules/communication_channels/lib/contact-resolver.js +79 -0
- package/dist/modules/communication_channels/lib/contact-resolver.js.map +7 -0
- package/dist/modules/communication_channels/lib/credential-refresh.js +97 -0
- package/dist/modules/communication_channels/lib/credential-refresh.js.map +7 -0
- package/dist/modules/communication_channels/lib/dead-letter.js +62 -0
- package/dist/modules/communication_channels/lib/dead-letter.js.map +7 -0
- package/dist/modules/communication_channels/lib/email-capabilities.js +47 -0
- package/dist/modules/communication_channels/lib/email-capabilities.js.map +7 -0
- package/dist/modules/communication_channels/lib/email-contact.js +14 -0
- package/dist/modules/communication_channels/lib/email-contact.js.map +7 -0
- package/dist/modules/communication_channels/lib/email-mime.js +299 -0
- package/dist/modules/communication_channels/lib/email-mime.js.map +7 -0
- package/dist/modules/communication_channels/lib/error-classification.js +101 -0
- package/dist/modules/communication_channels/lib/error-classification.js.map +7 -0
- package/dist/modules/communication_channels/lib/gmail-pubsub-jwt.js +185 -0
- package/dist/modules/communication_channels/lib/gmail-pubsub-jwt.js.map +7 -0
- package/dist/modules/communication_channels/lib/mutation-guards.js +114 -0
- package/dist/modules/communication_channels/lib/mutation-guards.js.map +7 -0
- package/dist/modules/communication_channels/lib/oauth-client-config.js +32 -0
- package/dist/modules/communication_channels/lib/oauth-client-config.js.map +7 -0
- package/dist/modules/communication_channels/lib/oauth-state.js +128 -0
- package/dist/modules/communication_channels/lib/oauth-state.js.map +7 -0
- package/dist/modules/communication_channels/lib/oauth-token.js +45 -0
- package/dist/modules/communication_channels/lib/oauth-token.js.map +7 -0
- package/dist/modules/communication_channels/lib/pg-errors.js +11 -0
- package/dist/modules/communication_channels/lib/pg-errors.js.map +7 -0
- package/dist/modules/communication_channels/lib/provider-health.js +24 -0
- package/dist/modules/communication_channels/lib/provider-health.js.map +7 -0
- package/dist/modules/communication_channels/lib/push-state.js +19 -0
- package/dist/modules/communication_channels/lib/push-state.js.map +7 -0
- package/dist/modules/communication_channels/lib/queue.js +54 -0
- package/dist/modules/communication_channels/lib/queue.js.map +7 -0
- package/dist/modules/communication_channels/lib/reaction-processor-types.js +5 -0
- package/dist/modules/communication_channels/lib/reaction-processor-types.js.map +7 -0
- package/dist/modules/communication_channels/lib/reaction-semantics.js +11 -0
- package/dist/modules/communication_channels/lib/reaction-semantics.js.map +7 -0
- package/dist/modules/communication_channels/lib/registry.js +67 -0
- package/dist/modules/communication_channels/lib/registry.js.map +7 -0
- package/dist/modules/communication_channels/lib/route-mutation-guard.js +43 -0
- package/dist/modules/communication_channels/lib/route-mutation-guard.js.map +7 -0
- package/dist/modules/communication_channels/lib/sanitize-channel-html.js +96 -0
- package/dist/modules/communication_channels/lib/sanitize-channel-html.js.map +7 -0
- package/dist/modules/communication_channels/lib/send-as-user.js +194 -0
- package/dist/modules/communication_channels/lib/send-as-user.js.map +7 -0
- package/dist/modules/communication_channels/lib/system-user.js +22 -0
- package/dist/modules/communication_channels/lib/system-user.js.map +7 -0
- package/dist/modules/communication_channels/lib/test-seed.js +68 -0
- package/dist/modules/communication_channels/lib/test-seed.js.map +7 -0
- package/dist/modules/communication_channels/lib/thread-matcher.js +263 -0
- package/dist/modules/communication_channels/lib/thread-matcher.js.map +7 -0
- package/dist/modules/communication_channels/lib/thread-token.js +219 -0
- package/dist/modules/communication_channels/lib/thread-token.js.map +7 -0
- package/dist/modules/communication_channels/lib/use-connect-channel.js +61 -0
- package/dist/modules/communication_channels/lib/use-connect-channel.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260526134719_communication_channels.js +50 -0
- package/dist/modules/communication_channels/migrations/Migration20260526134719_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260527195446_communication_channels.js +19 -0
- package/dist/modules/communication_channels/migrations/Migration20260527195446_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260529231848_communication_channels.js +13 -0
- package/dist/modules/communication_channels/migrations/Migration20260529231848_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260531120000_communication_channels.js +17 -0
- package/dist/modules/communication_channels/migrations/Migration20260531120000_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/notifications.client.js +51 -0
- package/dist/modules/communication_channels/notifications.client.js.map +7 -0
- package/dist/modules/communication_channels/notifications.handlers.js +53 -0
- package/dist/modules/communication_channels/notifications.handlers.js.map +7 -0
- package/dist/modules/communication_channels/notifications.js +56 -0
- package/dist/modules/communication_channels/notifications.js.map +7 -0
- package/dist/modules/communication_channels/setup.js +105 -0
- package/dist/modules/communication_channels/setup.js.map +7 -0
- package/dist/modules/communication_channels/subscribers/channel-requires-reauth-notification.js +71 -0
- package/dist/modules/communication_channels/subscribers/channel-requires-reauth-notification.js.map +7 -0
- package/dist/modules/communication_channels/subscribers/outbound-bridge.js +103 -0
- package/dist/modules/communication_channels/subscribers/outbound-bridge.js.map +7 -0
- package/dist/modules/communication_channels/subscribers/user-deleted-cascade.js +51 -0
- package/dist/modules/communication_channels/subscribers/user-deleted-cascade.js.map +7 -0
- package/dist/modules/communication_channels/widgets/components.js +7 -0
- package/dist/modules/communication_channels/widgets/components.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.client.js +18 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.js +30 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.js +185 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.js +17 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js +44 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.js +17 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/profile-channels-menu/widget.js +23 -0
- package/dist/modules/communication_channels/widgets/injection/profile-channels-menu/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.client.js +141 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.js +17 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection-table.js +38 -0
- package/dist/modules/communication_channels/widgets/injection-table.js.map +7 -0
- package/dist/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.js +25 -0
- package/dist/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.js.map +7 -0
- package/dist/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.js +19 -0
- package/dist/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.js.map +7 -0
- package/dist/modules/communication_channels/widgets/notifications/index.js +7 -0
- package/dist/modules/communication_channels/widgets/notifications/index.js.map +7 -0
- package/dist/modules/communication_channels/workers/channel-import-history.js +185 -0
- package/dist/modules/communication_channels/workers/channel-import-history.js.map +7 -0
- package/dist/modules/communication_channels/workers/gmail-history-sync.js +154 -0
- package/dist/modules/communication_channels/workers/gmail-history-sync.js.map +7 -0
- package/dist/modules/communication_channels/workers/gmail-renew-watch.js +95 -0
- package/dist/modules/communication_channels/workers/gmail-renew-watch.js.map +7 -0
- package/dist/modules/communication_channels/workers/inbound-processor.js +56 -0
- package/dist/modules/communication_channels/workers/inbound-processor.js.map +7 -0
- package/dist/modules/communication_channels/workers/outbound-delivery.js +85 -0
- package/dist/modules/communication_channels/workers/outbound-delivery.js.map +7 -0
- package/dist/modules/communication_channels/workers/poll-channel.js +240 -0
- package/dist/modules/communication_channels/workers/poll-channel.js.map +7 -0
- package/dist/modules/communication_channels/workers/poll-tick.js +132 -0
- package/dist/modules/communication_channels/workers/poll-tick.js.map +7 -0
- package/dist/modules/communication_channels/workers/reaction-processor.js +192 -0
- package/dist/modules/communication_channels/workers/reaction-processor.js.map +7 -0
- package/dist/modules/configs/api/openapi.js +11 -2
- package/dist/modules/configs/api/openapi.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/[id]/page.js +6 -3
- package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +27 -11
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js +1 -0
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +21 -7
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/currencies/commands/currencies.js +37 -16
- package/dist/modules/currencies/commands/currencies.js.map +2 -2
- package/dist/modules/currencies/commands/exchange-rates.js +19 -9
- package/dist/modules/currencies/commands/exchange-rates.js.map +2 -2
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js +26 -19
- package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles/[id].js +28 -5
- package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles.js +4 -2
- package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users/[id].js +39 -5
- package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users-invite.js +17 -1
- package/dist/modules/customer_accounts/api/admin/users-invite.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users.js +60 -23
- package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
- package/dist/modules/customer_accounts/api/login.js +11 -4
- package/dist/modules/customer_accounts/api/login.js.map +2 -2
- package/dist/modules/customer_accounts/api/portal/users-invite.js +17 -1
- package/dist/modules/customer_accounts/api/portal/users-invite.js.map +2 -2
- package/dist/modules/customer_accounts/api/signup.js +3 -1
- package/dist/modules/customer_accounts/api/signup.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +16 -8
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +19 -5
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +8 -4
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +29 -18
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +27 -11
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customer_accounts/data/validators.js +2 -1
- package/dist/modules/customer_accounts/data/validators.js.map +2 -2
- package/dist/modules/customer_accounts/lib/customerEntityOwnership.js +22 -0
- package/dist/modules/customer_accounts/lib/customerEntityOwnership.js.map +7 -0
- package/dist/modules/customer_accounts/lib/rateLimiter.js +14 -0
- package/dist/modules/customer_accounts/lib/rateLimiter.js.map +2 -2
- package/dist/modules/customer_accounts/lib/resolveTenantContext.js +44 -1
- package/dist/modules/customer_accounts/lib/resolveTenantContext.js.map +3 -3
- package/dist/modules/customer_accounts/services/customerInvitationService.js +28 -1
- package/dist/modules/customer_accounts/services/customerInvitationService.js.map +2 -2
- package/dist/modules/customer_accounts/services/customerUserService.js +13 -7
- package/dist/modules/customer_accounts/services/customerUserService.js.map +2 -2
- package/dist/modules/customer_accounts/subscribers/autoLinkCrmReverse.js +3 -3
- package/dist/modules/customer_accounts/subscribers/autoLinkCrmReverse.js.map +2 -2
- package/dist/modules/customers/acl.js +18 -0
- package/dist/modules/customers/acl.js.map +2 -2
- package/dist/modules/customers/api/activities/route.js +32 -10
- package/dist/modules/customers/api/activities/route.js.map +2 -2
- package/dist/modules/customers/api/addresses/route.js +2 -0
- package/dist/modules/customers/api/addresses/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/route.js +22 -9
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/companies/route.js +18 -7
- package/dist/modules/customers/api/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/route.js +2 -0
- package/dist/modules/customers/api/deals/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/[kind]/route.js +22 -38
- package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/cache.js +2 -1
- package/dist/modules/customers/api/dictionaries/cache.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/context.js +1 -0
- package/dist/modules/customers/api/dictionaries/context.js.map +2 -2
- package/dist/modules/customers/api/interactions/[id]/visibility/route.js +151 -0
- package/dist/modules/customers/api/interactions/[id]/visibility/route.js.map +7 -0
- package/dist/modules/customers/api/interactions/counts/route.js +6 -0
- package/dist/modules/customers/api/interactions/counts/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/route.js +33 -12
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/email-threads/route.js +82 -0
- package/dist/modules/customers/api/people/[id]/email-threads/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/emails/route.js +157 -0
- package/dist/modules/customers/api/people/[id]/emails/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/route.js +20 -10
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/people/route.js +16 -7
- package/dist/modules/customers/api/people/route.js.map +2 -2
- package/dist/modules/customers/api/pipeline-stages/route.js +0 -13
- package/dist/modules/customers/api/pipeline-stages/route.js.map +2 -2
- package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js +223 -0
- package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js.map +7 -0
- package/dist/modules/customers/api/todos/route.js +29 -11
- package/dist/modules/customers/api/todos/route.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +34 -21
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/[id]/page.js +45 -27
- package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +10 -1
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +22 -5
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +30 -8
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -0
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +26 -7
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js +62 -39
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/[id]/page.js +41 -26
- package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +10 -1
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +60 -23
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/commands/activities.js +19 -0
- package/dist/modules/customers/commands/activities.js.map +2 -2
- package/dist/modules/customers/commands/addresses.js +98 -14
- package/dist/modules/customers/commands/addresses.js.map +2 -2
- package/dist/modules/customers/commands/comments.js +30 -1
- package/dist/modules/customers/commands/comments.js.map +2 -2
- package/dist/modules/customers/commands/companies.js +113 -1
- package/dist/modules/customers/commands/companies.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +196 -77
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/dictionaries.js +44 -0
- package/dist/modules/customers/commands/dictionaries.js.map +2 -2
- package/dist/modules/customers/commands/entity-roles.js +47 -0
- package/dist/modules/customers/commands/entity-roles.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +200 -8
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/commands/labels.js +83 -1
- package/dist/modules/customers/commands/labels.js.map +2 -2
- package/dist/modules/customers/commands/people.js +167 -13
- package/dist/modules/customers/commands/people.js.map +2 -2
- package/dist/modules/customers/commands/personCompanyLinks.js +141 -69
- package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
- package/dist/modules/customers/commands/pipeline-stages.js +13 -11
- package/dist/modules/customers/commands/pipeline-stages.js.map +3 -3
- package/dist/modules/customers/commands/settings.js +31 -0
- package/dist/modules/customers/commands/settings.js.map +2 -2
- package/dist/modules/customers/commands/tags.js +56 -1
- package/dist/modules/customers/commands/tags.js.map +2 -2
- package/dist/modules/customers/commands/todos.js +19 -0
- package/dist/modules/customers/commands/todos.js.map +2 -2
- package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
- package/dist/modules/customers/components/CustomersConfigurationSections.js +3 -0
- package/dist/modules/customers/components/CustomersConfigurationSections.js.map +2 -2
- package/dist/modules/customers/components/DictionarySettings.js +20 -13
- package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
- package/dist/modules/customers/components/DictionarySortSettings.js +214 -0
- package/dist/modules/customers/components/DictionarySortSettings.js.map +7 -0
- package/dist/modules/customers/components/PipelineSettings.js +38 -23
- package/dist/modules/customers/components/PipelineSettings.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityCard.js +32 -0
- package/dist/modules/customers/components/detail/ActivityCard.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityForm.js +1 -0
- package/dist/modules/customers/components/detail/ActivityForm.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityTimeline.js +1 -1
- package/dist/modules/customers/components/detail/ActivityTimeline.js.map +2 -2
- package/dist/modules/customers/components/detail/AddressesSection.js +4 -0
- package/dist/modules/customers/components/detail/AddressesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/AnnualRevenueField.js +1 -0
- package/dist/modules/customers/components/detail/AnnualRevenueField.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js +28 -22
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
- package/dist/modules/customers/components/detail/ComposeEmailDialog.js +242 -0
- package/dist/modules/customers/components/detail/ComposeEmailDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/DealForm.js +3 -1
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/DealsSection.js +46 -24
- package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
- package/dist/modules/customers/components/detail/EmailCardActions.js +184 -0
- package/dist/modules/customers/components/detail/EmailCardActions.js.map +7 -0
- package/dist/modules/customers/components/detail/EmailReplyForwardActions.js +52 -0
- package/dist/modules/customers/components/detail/EmailReplyForwardActions.js.map +7 -0
- package/dist/modules/customers/components/detail/EntityTagsDialog.js +7 -0
- package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/ManageTagsDialog.js +34 -22
- package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js +41 -29
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonDetailTabs.js +7 -1
- package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonEmailThreadsTab.js +366 -0
- package/dist/modules/customers/components/detail/PersonEmailThreadsTab.js.map +7 -0
- package/dist/modules/customers/components/detail/RoleAssignmentRow.js +14 -8
- package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +2 -2
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +14 -6
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/create/DealCurrencyField.js +1 -0
- package/dist/modules/customers/components/detail/create/DealCurrencyField.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js +2 -1
- package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +29 -13
- package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useInteractions.js +77 -35
- package/dist/modules/customers/components/detail/hooks/useInteractions.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +25 -17
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
- package/dist/modules/customers/components/formConfig.js +62 -12
- package/dist/modules/customers/components/formConfig.js.map +2 -2
- package/dist/modules/customers/data/enrichers.js +133 -2
- package/dist/modules/customers/data/enrichers.js.map +2 -2
- package/dist/modules/customers/data/entities.js +21 -0
- package/dist/modules/customers/data/entities.js.map +2 -2
- package/dist/modules/customers/data/extensions.js +16 -0
- package/dist/modules/customers/data/extensions.js.map +7 -0
- package/dist/modules/customers/data/guards.js +66 -0
- package/dist/modules/customers/data/guards.js.map +7 -0
- package/dist/modules/customers/data/validators.js +33 -8
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/di.js +37 -0
- package/dist/modules/customers/di.js.map +2 -2
- package/dist/modules/customers/encryption.js +11 -0
- package/dist/modules/customers/encryption.js.map +2 -2
- package/dist/modules/customers/events.js +4 -1
- package/dist/modules/customers/events.js.map +2 -2
- package/dist/modules/customers/lib/detailTenantScope.js +15 -0
- package/dist/modules/customers/lib/detailTenantScope.js.map +7 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js +64 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js.map +7 -0
- package/dist/modules/customers/lib/kysely.js.map +2 -2
- package/dist/modules/customers/lib/link-channel-message-handler.js +303 -0
- package/dist/modules/customers/lib/link-channel-message-handler.js.map +7 -0
- package/dist/modules/customers/lib/personCompanyLinkTable.js +15 -1
- package/dist/modules/customers/lib/personCompanyLinkTable.js.map +2 -2
- package/dist/modules/customers/lib/personEmailThreads.js +205 -0
- package/dist/modules/customers/lib/personEmailThreads.js.map +7 -0
- package/dist/modules/customers/lib/todoCompatibility.js +11 -0
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/customers/lib/visibilityFilter.js +51 -0
- package/dist/modules/customers/lib/visibilityFilter.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260527012240_customers.js +20 -0
- package/dist/modules/customers/migrations/Migration20260527012240_customers.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260602202147_customers.js +13 -0
- package/dist/modules/customers/migrations/Migration20260602202147_customers.js.map +7 -0
- package/dist/modules/customers/search.js +12 -6
- package/dist/modules/customers/search.js.map +2 -2
- package/dist/modules/customers/setup.js +2 -1
- package/dist/modules/customers/setup.js.map +2 -2
- package/dist/modules/customers/subscribers/link-channel-message-received.js +12 -0
- package/dist/modules/customers/subscribers/link-channel-message-received.js.map +7 -0
- package/dist/modules/customers/subscribers/link-channel-message-sent.js +12 -0
- package/dist/modules/customers/subscribers/link-channel-message-sent.js.map +7 -0
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
- package/dist/modules/data_sync/api/options.js +4 -4
- package/dist/modules/data_sync/api/options.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/route.js +9 -1
- package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +17 -8
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js +43 -22
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-schedule-service.js +9 -0
- package/dist/modules/data_sync/lib/sync-schedule-service.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +8 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +12 -5
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js +25 -1
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/openapi.js +2 -0
- package/dist/modules/dictionaries/api/openapi.js.map +2 -2
- package/dist/modules/dictionaries/api/route.js +7 -0
- package/dist/modules/dictionaries/api/route.js.map +2 -2
- package/dist/modules/dictionaries/commands/entry-operations.js +8 -0
- package/dist/modules/dictionaries/commands/entry-operations.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionariesManager.js +95 -16
- package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +29 -16
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +51 -11
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionarySelectControl.js +9 -1
- package/dist/modules/dictionaries/components/DictionarySelectControl.js.map +2 -2
- package/dist/modules/dictionaries/components/dictionaryAppearance.js +2 -1
- package/dist/modules/dictionaries/components/dictionaryAppearance.js.map +2 -2
- package/dist/modules/dictionaries/components/hooks/useDictionaryEntries.js +2 -1
- package/dist/modules/dictionaries/components/hooks/useDictionaryEntries.js.map +2 -2
- package/dist/modules/dictionaries/data/entities.js +5 -0
- package/dist/modules/dictionaries/data/entities.js.map +2 -2
- package/dist/modules/dictionaries/data/validators.js +3 -1
- package/dist/modules/dictionaries/data/validators.js.map +2 -2
- package/dist/modules/dictionaries/fields/dictionary.js +2 -2
- package/dist/modules/dictionaries/fields/dictionary.js.map +1 -1
- package/dist/modules/dictionaries/lib/entrySort.js +61 -0
- package/dist/modules/dictionaries/lib/entrySort.js.map +7 -0
- package/dist/modules/dictionaries/migrations/Migration20260602202147_dictionaries.js +13 -0
- package/dist/modules/dictionaries/migrations/Migration20260602202147_dictionaries.js.map +7 -0
- package/dist/modules/directory/api/get/organizations/lookup.js +3 -7
- package/dist/modules/directory/api/get/organizations/lookup.js.map +2 -2
- package/dist/modules/directory/api/organizations/route.js +41 -16
- package/dist/modules/directory/api/organizations/route.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +2 -0
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/page.js +18 -5
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +7 -3
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +17 -4
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/directory/commands/organizations.js +70 -2
- package/dist/modules/directory/commands/organizations.js.map +2 -2
- package/dist/modules/directory/commands/tenants.js +16 -3
- package/dist/modules/directory/commands/tenants.js.map +2 -2
- package/dist/modules/entities/api/records.js +107 -7
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +1 -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/page.js +8 -4
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/entities/components/UserEntitiesTable.js +9 -0
- package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
- package/dist/modules/entities/lib/entityAcl.js +82 -0
- package/dist/modules/entities/lib/entityAcl.js.map +7 -0
- package/dist/modules/entities/lib/helpers.js +79 -65
- package/dist/modules/entities/lib/helpers.js.map +2 -2
- package/dist/modules/feature_toggles/api/global/[id]/override/route.js +15 -10
- package/dist/modules/feature_toggles/api/global/[id]/override/route.js.map +2 -2
- package/dist/modules/feature_toggles/api/global/[id]/route.js +2 -1
- package/dist/modules/feature_toggles/api/global/[id]/route.js.map +2 -2
- package/dist/modules/feature_toggles/api/overrides/route.js +20 -7
- package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
- package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js +21 -16
- package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js.map +2 -2
- package/dist/modules/feature_toggles/commands/global.js +127 -8
- package/dist/modules/feature_toggles/commands/global.js.map +2 -2
- package/dist/modules/feature_toggles/commands/overrides.js +8 -6
- package/dist/modules/feature_toggles/commands/overrides.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js +20 -12
- package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +15 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/formConfig.js +2 -1
- package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
- package/dist/modules/feature_toggles/components/overrideFormConfig.js +5 -1
- package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
- package/dist/modules/feature_toggles/data/validators.js +7 -4
- package/dist/modules/feature_toggles/data/validators.js.map +2 -2
- package/dist/modules/feature_toggles/lib/queries.js +5 -5
- package/dist/modules/feature_toggles/lib/queries.js.map +2 -2
- package/dist/modules/feature_toggles/lib/utils.js.map +2 -2
- package/dist/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.js +8 -1
- package/dist/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/settings/route.js +23 -2
- package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
- package/dist/modules/inbox_ops/api/webhook/inbound.js +53 -14
- package/dist/modules/inbox_ops/api/webhook/inbound.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +13 -8
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +9 -4
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
- package/dist/modules/inbox_ops/data/entities.js +3 -0
- package/dist/modules/inbox_ops/data/entities.js.map +2 -2
- package/dist/modules/inbox_ops/data/validators.js +5 -1
- package/dist/modules/inbox_ops/data/validators.js.map +2 -2
- package/dist/modules/inbox_ops/encryption.js +9 -0
- package/dist/modules/inbox_ops/encryption.js.map +2 -2
- package/dist/modules/inbox_ops/lib/executionEngine.js +6 -1
- package/dist/modules/inbox_ops/lib/executionEngine.js.map +2 -2
- package/dist/modules/inbox_ops/lib/executionHelpers.js +2 -7
- package/dist/modules/inbox_ops/lib/executionHelpers.js.map +2 -2
- package/dist/modules/inbox_ops/lib/priceValidator.js +35 -7
- package/dist/modules/inbox_ops/lib/priceValidator.js.map +2 -2
- package/dist/modules/inbox_ops/lib/rateLimiter.js +58 -23
- package/dist/modules/inbox_ops/lib/rateLimiter.js.map +2 -2
- package/dist/modules/inbox_ops/lib/translationProvider.js +33 -5
- package/dist/modules/inbox_ops/lib/translationProvider.js.map +2 -2
- package/dist/modules/inbox_ops/migrations/Migration20260607205834.js +13 -0
- package/dist/modules/inbox_ops/migrations/Migration20260607205834.js.map +7 -0
- package/dist/modules/inbox_ops/subscribers/extractionWorker.js +2 -1
- package/dist/modules/inbox_ops/subscribers/extractionWorker.js.map +2 -2
- package/dist/modules/integrations/api/[id]/credentials/route.js +11 -0
- package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +8 -0
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +18 -11
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/page.js +12 -8
- package/dist/modules/integrations/backend/integrations/page.js.map +2 -2
- package/dist/modules/integrations/data/entities.js +8 -1
- package/dist/modules/integrations/data/entities.js.map +2 -2
- package/dist/modules/integrations/lib/credentials-field-validation.js +32 -0
- package/dist/modules/integrations/lib/credentials-field-validation.js.map +7 -0
- package/dist/modules/integrations/lib/credentials-service.js +29 -14
- package/dist/modules/integrations/lib/credentials-service.js.map +2 -2
- package/dist/modules/integrations/migrations/Migration20260526154136_integrations.js +15 -0
- package/dist/modules/integrations/migrations/Migration20260526154136_integrations.js.map +7 -0
- package/dist/modules/messages/api/route.js +2 -2
- package/dist/modules/messages/api/route.js.map +2 -2
- package/dist/modules/messages/api/token/[token]/route.js +1 -1
- package/dist/modules/messages/api/token/[token]/route.js.map +2 -2
- package/dist/modules/messages/commands/actions.js +9 -7
- package/dist/modules/messages/commands/actions.js.map +2 -2
- package/dist/modules/messages/commands/messages.js +83 -18
- package/dist/modules/messages/commands/messages.js.map +2 -2
- package/dist/modules/messages/commands/tokens.js +1 -1
- package/dist/modules/messages/commands/tokens.js.map +2 -2
- package/dist/modules/messages/components/ComposeMessagePageClient.js +24 -13
- package/dist/modules/messages/components/ComposeMessagePageClient.js.map +2 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js +39 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +10 -0
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js +2 -2
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js.map +2 -2
- package/dist/modules/messages/components/message-detail/utils.js +17 -0
- package/dist/modules/messages/components/message-detail/utils.js.map +2 -2
- package/dist/modules/messages/data/entities.js +8 -1
- package/dist/modules/messages/data/entities.js.map +2 -2
- package/dist/modules/messages/data/validators.js +5 -1
- package/dist/modules/messages/data/validators.js.map +2 -2
- package/dist/modules/messages/lib/actions.js +5 -3
- package/dist/modules/messages/lib/actions.js.map +2 -2
- package/dist/modules/messages/migrations/Migration20260531130000.js +15 -0
- package/dist/modules/messages/migrations/Migration20260531130000.js.map +7 -0
- package/dist/modules/messages/widgets/injection-table.js +7 -0
- package/dist/modules/messages/widgets/injection-table.js.map +7 -0
- package/dist/modules/notifications/api/[id]/action/route.js +12 -2
- package/dist/modules/notifications/api/[id]/action/route.js.map +2 -2
- package/dist/modules/notifications/api/route.js +17 -4
- package/dist/modules/notifications/api/route.js.map +2 -2
- package/dist/modules/notifications/lib/notificationService.js +26 -21
- package/dist/modules/notifications/lib/notificationService.js.map +2 -2
- package/dist/modules/notifications/lib/routeHelpers.js +46 -8
- package/dist/modules/notifications/lib/routeHelpers.js.map +2 -2
- package/dist/modules/payment_gateways/api/status/route.js +6 -0
- package/dist/modules/payment_gateways/api/status/route.js.map +2 -2
- package/dist/modules/perspectives/api/[tableId]/route.js +39 -30
- package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
- package/dist/modules/perspectives/services/perspectiveService.js +7 -0
- package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js +6 -14
- package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js.map +3 -3
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js +4 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
- package/dist/modules/planner/commands/availability-rule-sets.js +20 -1
- package/dist/modules/planner/commands/availability-rule-sets.js.map +2 -2
- package/dist/modules/planner/commands/availability.js +9 -0
- package/dist/modules/planner/commands/availability.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRuleSetForm.js +3 -1
- package/dist/modules/planner/components/AvailabilityRuleSetForm.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRulesEditor.js +52 -13
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/planner/components/AvailabilitySchedule.js +9 -5
- package/dist/modules/planner/components/AvailabilitySchedule.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +15 -14
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/page.js +14 -21
- package/dist/modules/portal/frontend/[orgSlug]/portal/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +11 -1
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js +15 -5
- package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js.map +2 -2
- package/dist/modules/progress/api/jobs/[id]/route.js +7 -1
- package/dist/modules/progress/api/jobs/[id]/route.js.map +2 -2
- package/dist/modules/query_index/api/openapi.js +2 -1
- package/dist/modules/query_index/api/openapi.js.map +2 -2
- package/dist/modules/query_index/api/reindex.js +4 -0
- package/dist/modules/query_index/api/reindex.js.map +2 -2
- package/dist/modules/query_index/data/entities.js +5 -1
- package/dist/modules/query_index/data/entities.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +48 -15
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/lib/indexer.js +50 -24
- package/dist/modules/query_index/lib/indexer.js.map +2 -2
- package/dist/modules/query_index/lib/jobs.js +28 -0
- package/dist/modules/query_index/lib/jobs.js.map +2 -2
- package/dist/modules/query_index/lib/reindexer.js +24 -15
- package/dist/modules/query_index/lib/reindexer.js.map +2 -2
- package/dist/modules/query_index/lib/search-tokens.js +3 -3
- package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
- package/dist/modules/query_index/migrations/Migration20260606205453_query_index.js +35 -0
- package/dist/modules/query_index/migrations/Migration20260606205453_query_index.js.map +7 -0
- package/dist/modules/query_index/subscribers/delete_one.js +28 -15
- package/dist/modules/query_index/subscribers/delete_one.js.map +2 -2
- package/dist/modules/query_index/subscribers/upsert_one.js +31 -13
- package/dist/modules/query_index/subscribers/upsert_one.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +18 -2
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js +4 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js +31 -4
- package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +17 -4
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/resources/commands/activities.js +64 -0
- package/dist/modules/resources/commands/activities.js.map +2 -2
- package/dist/modules/resources/commands/comments.js +21 -1
- package/dist/modules/resources/commands/comments.js.map +2 -2
- package/dist/modules/resources/commands/resource-types.js +22 -1
- package/dist/modules/resources/commands/resource-types.js.map +2 -2
- package/dist/modules/resources/commands/resources.js +87 -0
- package/dist/modules/resources/commands/resources.js.map +2 -2
- package/dist/modules/resources/commands/tag-assignments.js +53 -0
- package/dist/modules/resources/commands/tag-assignments.js.map +2 -2
- package/dist/modules/resources/components/ResourceCrudForm.js +90 -50
- package/dist/modules/resources/components/ResourceCrudForm.js.map +2 -2
- package/dist/modules/resources/components/ResourceTypeCrudForm.js +2 -1
- package/dist/modules/resources/components/ResourceTypeCrudForm.js.map +2 -2
- package/dist/modules/sales/api/documents/factory.js +7 -2
- package/dist/modules/sales/api/documents/factory.js.map +2 -2
- package/dist/modules/sales/api/shipping-methods/route.js +4 -0
- package/dist/modules/sales/api/shipping-methods/route.js.map +2 -2
- package/dist/modules/sales/api/tax-rates/route.js +4 -0
- package/dist/modules/sales/api/tax-rates/route.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +3 -1
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js +13 -4
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +16 -4
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +70 -22
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/create/page.js.map +2 -2
- package/dist/modules/sales/commands/configuration.js +112 -7
- package/dist/modules/sales/commands/configuration.js.map +2 -2
- package/dist/modules/sales/commands/documentAddresses.js +181 -2
- package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +46 -14
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/commands/notes.js +39 -1
- package/dist/modules/sales/commands/notes.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +121 -14
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/commands/returns.js +178 -2
- package/dist/modules/sales/commands/returns.js.map +2 -2
- package/dist/modules/sales/commands/shared.js +15 -0
- package/dist/modules/sales/commands/shared.js.map +2 -2
- package/dist/modules/sales/commands/shipments.js +48 -6
- package/dist/modules/sales/commands/shipments.js.map +2 -2
- package/dist/modules/sales/components/AdjustmentKindSettings.js +19 -11
- package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
- package/dist/modules/sales/components/DocumentNumberSettings.js.map +2 -2
- package/dist/modules/sales/components/OrderEditingSettings.js.map +2 -2
- package/dist/modules/sales/components/PaymentMethodsSettings.js +12 -4
- package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/ShippingMethodsSettings.js +12 -4
- package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/StatusSettings.js +18 -11
- package/dist/modules/sales/components/StatusSettings.js.map +2 -2
- package/dist/modules/sales/components/TaxRatesSettings.js +12 -4
- package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
- package/dist/modules/sales/components/channels/ChannelOfferForm.js +65 -18
- package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +11 -4
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
- package/dist/modules/sales/components/documents/AddressesSection.js +101 -36
- package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentDialog.js +37 -10
- package/dist/modules/sales/components/documents/AdjustmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentsSection.js +43 -23
- package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +23 -14
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +70 -28
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentDialog.js +29 -14
- package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +20 -10
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnDialog.js +26 -17
- package/dist/modules/sales/components/documents/ReturnDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnsSection.js +3 -1
- package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js +1 -0
- package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +11 -6
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +102 -17
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentsSection.js +19 -10
- package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/optimisticLock.js +27 -0
- package/dist/modules/sales/components/documents/optimisticLock.js.map +7 -0
- package/dist/modules/sales/di.js +18 -0
- package/dist/modules/sales/di.js.map +2 -2
- package/dist/modules/sales/frontend/quote/[token]/page.js +11 -1
- package/dist/modules/sales/frontend/quote/[token]/page.js.map +2 -2
- package/dist/modules/sales/lib/calculations.js +18 -1
- package/dist/modules/sales/lib/calculations.js.map +2 -2
- package/dist/modules/sales/lib/dictionaries.js +2 -2
- package/dist/modules/sales/lib/dictionaries.js.map +2 -2
- package/dist/modules/sales/lib/makeStatusDictionaryRoute.js +2 -0
- package/dist/modules/sales/lib/makeStatusDictionaryRoute.js.map +2 -2
- package/dist/modules/shipping_carriers/api/cancel/route.js +2 -2
- package/dist/modules/shipping_carriers/api/cancel/route.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/status-sync.js +8 -1
- package/dist/modules/shipping_carriers/lib/status-sync.js.map +2 -2
- package/dist/modules/staff/api/job-histories.js +11 -2
- package/dist/modules/staff/api/job-histories.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-entries/route.js +11 -4
- package/dist/modules/staff/api/timesheets/time-entries/route.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +13 -8
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/page.js +9 -1
- package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +2 -1
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/profile/create/page.js +1 -1
- package/dist/modules/staff/backend/staff/profile/create/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +7 -4
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/page.js +17 -27
- package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +48 -2
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js +17 -35
- package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +5 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js +24 -14
- package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/page.js +4 -1
- package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js +18 -3
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js +35 -5
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js +12 -3
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
- package/dist/modules/staff/commands/activities.js +53 -0
- package/dist/modules/staff/commands/activities.js.map +2 -2
- package/dist/modules/staff/commands/addresses.js +70 -0
- package/dist/modules/staff/commands/addresses.js.map +2 -2
- package/dist/modules/staff/commands/comments.js +21 -1
- package/dist/modules/staff/commands/comments.js.map +2 -2
- package/dist/modules/staff/commands/job-histories.js +88 -3
- package/dist/modules/staff/commands/job-histories.js.map +2 -2
- package/dist/modules/staff/commands/leave-requests.js +39 -1
- package/dist/modules/staff/commands/leave-requests.js.map +2 -2
- package/dist/modules/staff/commands/tag-assignments.js +33 -0
- package/dist/modules/staff/commands/tag-assignments.js.map +2 -2
- package/dist/modules/staff/commands/team-members.js +43 -0
- package/dist/modules/staff/commands/team-members.js.map +2 -2
- package/dist/modules/staff/commands/team-roles.js +23 -0
- package/dist/modules/staff/commands/team-roles.js.map +2 -2
- package/dist/modules/staff/commands/teams.js +23 -0
- package/dist/modules/staff/commands/teams.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-entries.js +31 -1
- package/dist/modules/staff/commands/timesheets-entries.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-projects.js +56 -2
- package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
- package/dist/modules/staff/components/LeaveRequestForm.js +2 -0
- package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
- package/dist/modules/staff/components/TeamForm.js +2 -1
- package/dist/modules/staff/components/TeamForm.js.map +2 -2
- package/dist/modules/staff/components/TeamMemberForm.js +35 -4
- package/dist/modules/staff/components/TeamMemberForm.js.map +3 -3
- package/dist/modules/staff/components/TeamRoleForm.js +4 -3
- package/dist/modules/staff/components/TeamRoleForm.js.map +2 -2
- package/dist/modules/staff/components/detail/JobHistorySection.js +20 -7
- package/dist/modules/staff/components/detail/JobHistorySection.js.map +2 -2
- package/dist/modules/staff/data/validators.js +7 -1
- package/dist/modules/staff/data/validators.js.map +2 -2
- package/dist/modules/staff/lib/leaveRequestHelpers.js +2 -1
- package/dist/modules/staff/lib/leaveRequestHelpers.js.map +2 -2
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js +9 -1
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
- package/dist/modules/translations/components/TranslationManager.js +12 -8
- package/dist/modules/translations/components/TranslationManager.js.map +2 -2
- package/dist/modules/workflows/acl.js +102 -17
- package/dist/modules/workflows/acl.js.map +2 -2
- package/dist/modules/workflows/api/definitions/[id]/route.js +106 -0
- package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.js +11 -3
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/page.js +33 -13
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +29 -16
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialog.js +3 -1
- package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowGraphImpl.js +4 -2
- package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
- package/dist/modules/workflows/components/formConfig.js +26 -13
- package/dist/modules/workflows/components/formConfig.js.map +2 -2
- package/dist/modules/workflows/components/nodes/ParallelForkNode.js +49 -0
- package/dist/modules/workflows/components/nodes/ParallelForkNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/ParallelJoinNode.js +49 -0
- package/dist/modules/workflows/components/nodes/ParallelJoinNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/index.js +4 -0
- package/dist/modules/workflows/components/nodes/index.js.map +2 -2
- package/dist/modules/workflows/data/entities.js +81 -0
- package/dist/modules/workflows/data/entities.js.map +2 -2
- package/dist/modules/workflows/data/validators.js +146 -1
- package/dist/modules/workflows/data/validators.js.map +2 -2
- package/dist/modules/workflows/di.js +12 -0
- package/dist/modules/workflows/di.js.map +2 -2
- package/dist/modules/workflows/events.js +7 -1
- package/dist/modules/workflows/events.js.map +2 -2
- package/dist/modules/workflows/lib/activity-executor.js +4 -2
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/dist/modules/workflows/lib/activity-queue-types.js.map +2 -2
- package/dist/modules/workflows/lib/event-logger.js +2 -0
- package/dist/modules/workflows/lib/event-logger.js.map +2 -2
- package/dist/modules/workflows/lib/execution-token.js +98 -0
- package/dist/modules/workflows/lib/execution-token.js.map +7 -0
- package/dist/modules/workflows/lib/node-type-icons.js +14 -5
- package/dist/modules/workflows/lib/node-type-icons.js.map +2 -2
- package/dist/modules/workflows/lib/parallel-handler.js +364 -0
- package/dist/modules/workflows/lib/parallel-handler.js.map +7 -0
- package/dist/modules/workflows/lib/signal-handler.js +63 -1
- package/dist/modules/workflows/lib/signal-handler.js.map +2 -2
- package/dist/modules/workflows/lib/step-handler.js +74 -30
- package/dist/modules/workflows/lib/step-handler.js.map +2 -2
- package/dist/modules/workflows/lib/task-handler.js +26 -0
- package/dist/modules/workflows/lib/task-handler.js.map +2 -2
- package/dist/modules/workflows/lib/timer-handler.js +26 -1
- package/dist/modules/workflows/lib/timer-handler.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +33 -21
- package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
- package/dist/modules/workflows/lib/workflow-executor.js +54 -1
- package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
- package/dist/modules/workflows/migrations/Migration20260602120000.js +24 -0
- package/dist/modules/workflows/migrations/Migration20260602120000.js.map +7 -0
- package/dist/modules/workflows/workers/workflow-activities.worker.js +8 -4
- package/dist/modules/workflows/workers/workflow-activities.worker.js.map +2 -2
- package/generated/entities/channel_ingest_dead_letter/index.ts +11 -0
- package/generated/entities/channel_thread_mapping/index.ts +11 -0
- package/generated/entities/channel_thread_token/index.ts +7 -0
- package/generated/entities/communication_channel/index.ts +20 -0
- package/generated/entities/customer_interaction/index.ts +2 -0
- package/generated/entities/customer_settings/index.ts +1 -0
- package/generated/entities/dictionary/index.ts +1 -0
- package/generated/entities/external_conversation/index.ts +11 -0
- package/generated/entities/external_message/index.ts +11 -0
- package/generated/entities/inbox_settings/index.ts +1 -0
- package/generated/entities/integration_credentials/index.ts +1 -0
- package/generated/entities/message/index.ts +1 -0
- package/generated/entities/message_channel_link/index.ts +15 -0
- package/generated/entities/message_reaction/index.ts +11 -0
- package/generated/entities/role/index.ts +1 -0
- package/generated/entities/step_instance/index.ts +1 -0
- package/generated/entities/user/index.ts +1 -0
- package/generated/entities/user_task/index.ts +1 -0
- package/generated/entities/workflow_branch_instance/index.ts +18 -0
- package/generated/entities/workflow_event/index.ts +1 -0
- package/generated/entities/workflow_instance/index.ts +1 -0
- package/generated/entities.ids.generated.ts +12 -0
- package/generated/entity-fields-registry.ts +146 -0
- package/jest.config.cjs +4 -0
- package/jest.mocks/entities.ids.generated.js +9 -0
- package/jest.setup.ts +17 -0
- package/package.json +17 -15
- package/src/helpers/integration/api.ts +15 -2
- package/src/helpers/integration/authFixtures.ts +4 -1
- package/src/helpers/integration/communicationChannelsFixtures.ts +130 -0
- package/src/helpers/integration/crudFormFields.ts +48 -0
- package/src/helpers/integration/crudFormPersistence.ts +178 -0
- package/src/helpers/integration/currenciesFixtures.ts +60 -0
- package/src/helpers/integration/customerAccountsFixtures.ts +256 -0
- package/src/helpers/integration/dbFixtures.ts +15 -1
- package/src/helpers/integration/inboxFixtures.ts +36 -0
- package/src/helpers/integration/optimisticLockUi.ts +172 -0
- package/src/helpers/integration/salesFixtures.ts +29 -0
- package/src/helpers/integration/salesUi.ts +19 -12
- package/src/helpers/integration/standaloneEnv.ts +62 -0
- package/src/helpers/integration/undoHarness.ts +243 -0
- package/src/helpers/integration/workflowsFixtures.ts +231 -0
- package/src/modules/api_keys/backend/api-keys/page.tsx +18 -5
- package/src/modules/api_keys/data/validators.ts +3 -1
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +19 -9
- package/src/modules/attachments/lib/ocrQueue.ts +9 -1
- package/src/modules/attachments/lib/security.ts +1 -1
- package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +3 -1
- package/src/modules/audit_logs/api/audit-logs/actions/undo/route.ts +13 -2
- package/src/modules/audit_logs/data/entities.ts +1 -1
- package/src/modules/audit_logs/services/actionLogService.ts +18 -0
- package/src/modules/auth/api/logout.ts +0 -12
- package/src/modules/auth/api/roles/acl/route.ts +37 -11
- package/src/modules/auth/api/roles/route.ts +56 -2
- package/src/modules/auth/api/sidebar/preferences/route.ts +83 -3
- package/src/modules/auth/api/users/acl/route.ts +94 -33
- package/src/modules/auth/api/users/consents/route.ts +20 -0
- package/src/modules/auth/api/users/resend-invite/route.ts +20 -0
- package/src/modules/auth/api/users/route.ts +42 -1
- package/src/modules/auth/backend/roles/[id]/edit/page.tsx +29 -4
- package/src/modules/auth/backend/roles/page.tsx +17 -4
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +92 -6
- package/src/modules/auth/backend/users/page.tsx +15 -2
- package/src/modules/auth/cli.ts +20 -21
- package/src/modules/auth/commands/roles.ts +81 -1
- package/src/modules/auth/commands/users.ts +117 -6
- package/src/modules/auth/components/AclEditor.tsx +10 -1
- package/src/modules/auth/data/entities.ts +7 -1
- package/src/modules/auth/frontend/reset/[token]/page.tsx +7 -2
- package/src/modules/auth/lib/consentIntegrity.ts +18 -2
- package/src/modules/auth/lib/emailHash.ts +5 -1
- package/src/modules/auth/lib/grantChecks.ts +55 -1
- package/src/modules/auth/lib/sessionIntegrity.ts +18 -1
- package/src/modules/auth/services/authService.ts +10 -19
- package/src/modules/auth/services/sidebarPreferencesService.ts +38 -4
- package/src/modules/business_rules/api/rules/route.ts +30 -0
- package/src/modules/business_rules/api/sets/route.ts +30 -0
- package/src/modules/business_rules/backend/rules/[id]/page.tsx +16 -4
- package/src/modules/business_rules/backend/rules/page.tsx +29 -12
- package/src/modules/business_rules/backend/sets/[id]/page.tsx +16 -4
- package/src/modules/business_rules/backend/sets/page.tsx +28 -11
- package/src/modules/catalog/AGENTS.md +10 -0
- package/src/modules/catalog/api/categories/route.ts +3 -0
- package/src/modules/catalog/api/products/route.ts +4 -0
- package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +5 -0
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +174 -91
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +121 -34
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/create/page.tsx +22 -5
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +5 -28
- package/src/modules/catalog/backend/catalog/products/optionSchemaClient.ts +2 -0
- package/src/modules/catalog/commands/categories.ts +42 -0
- package/src/modules/catalog/commands/offers.ts +44 -0
- package/src/modules/catalog/commands/optionSchemas.ts +10 -0
- package/src/modules/catalog/commands/priceKinds.ts +5 -0
- package/src/modules/catalog/commands/prices.ts +50 -0
- package/src/modules/catalog/commands/productUnitConversions.ts +32 -0
- package/src/modules/catalog/commands/products.ts +87 -0
- package/src/modules/catalog/commands/variants.ts +118 -32
- package/src/modules/catalog/components/PriceKindSettings.tsx +21 -7
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +9 -0
- package/src/modules/catalog/components/products/ProductMediaManager.tsx +2 -0
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +16 -4
- package/src/modules/catalog/components/products/VariantBuilder.tsx +48 -9
- package/src/modules/catalog/components/products/productForm.ts +41 -0
- package/src/modules/catalog/components/products/variantForm.ts +10 -0
- package/src/modules/catalog/lib/pricing.ts +8 -0
- package/src/modules/communication_channels/acl.ts +43 -0
- package/src/modules/communication_channels/api/delete/channels/[id]/route.ts +163 -0
- package/src/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.ts +143 -0
- package/src/modules/communication_channels/api/get/channels/[id]/health/route.ts +173 -0
- package/src/modules/communication_channels/api/get/channels/[id]/route.ts +111 -0
- package/src/modules/communication_channels/api/get/channels/route.ts +109 -0
- package/src/modules/communication_channels/api/get/me/channels/route.ts +100 -0
- package/src/modules/communication_channels/api/get/oauth/[provider]/callback/route.ts +355 -0
- package/src/modules/communication_channels/api/post/channels/[id]/import-history/route.ts +206 -0
- package/src/modules/communication_channels/api/post/channels/[id]/poll-now/route.ts +174 -0
- package/src/modules/communication_channels/api/post/channels/[id]/push/register/route.ts +158 -0
- package/src/modules/communication_channels/api/post/channels/[id]/set-primary/route.ts +114 -0
- package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +241 -0
- package/src/modules/communication_channels/api/post/channels/connect/credentials/route.ts +134 -0
- package/src/modules/communication_channels/api/post/messages/[messageId]/reactions/route.ts +143 -0
- package/src/modules/communication_channels/api/post/oauth/[provider]/initiate/route.ts +192 -0
- package/src/modules/communication_channels/api/post/send-as-user/route.ts +125 -0
- package/src/modules/communication_channels/api/post/test-seed/route.ts +294 -0
- package/src/modules/communication_channels/api/post/webhook/[provider]/route.ts +227 -0
- package/src/modules/communication_channels/api/post/webhooks/gmail/route.ts +161 -0
- package/src/modules/communication_channels/api/put/threads/[threadId]/assign/route.ts +132 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.ts +34 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/[id]/page.tsx +250 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/page.meta.ts +36 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +137 -0
- package/src/modules/communication_channels/backend/profile/communication-channels/page.meta.ts +36 -0
- package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +912 -0
- package/src/modules/communication_channels/commands/connect-credential-channel.ts +243 -0
- package/src/modules/communication_channels/commands/delete-channel.ts +193 -0
- package/src/modules/communication_channels/commands/deliver-outbound-message.ts +579 -0
- package/src/modules/communication_channels/commands/disconnect-channel.ts +241 -0
- package/src/modules/communication_channels/commands/ingest-inbound-message.ts +602 -0
- package/src/modules/communication_channels/commands/interceptors.ts +104 -0
- package/src/modules/communication_channels/commands/process-inbound-reaction.ts +265 -0
- package/src/modules/communication_channels/commands/push-register.ts +203 -0
- package/src/modules/communication_channels/commands/push-renew.ts +49 -0
- package/src/modules/communication_channels/commands/push-unregister.ts +168 -0
- package/src/modules/communication_channels/commands/queue-import-history.ts +180 -0
- package/src/modules/communication_channels/commands/reassign-conversation.ts +273 -0
- package/src/modules/communication_channels/commands/set-primary-channel.ts +157 -0
- package/src/modules/communication_channels/commands/toggle-outbound-reaction.ts +347 -0
- package/src/modules/communication_channels/data/enrichers.ts +413 -0
- package/src/modules/communication_channels/data/entities.ts +546 -0
- package/src/modules/communication_channels/data/extensions.ts +76 -0
- package/src/modules/communication_channels/data/validators.ts +138 -0
- package/src/modules/communication_channels/di.ts +40 -0
- package/src/modules/communication_channels/encryption.ts +44 -0
- package/src/modules/communication_channels/events.ts +122 -0
- package/src/modules/communication_channels/i18n/de.json +138 -0
- package/src/modules/communication_channels/i18n/en.json +138 -0
- package/src/modules/communication_channels/i18n/es.json +138 -0
- package/src/modules/communication_channels/i18n/pl.json +138 -0
- package/src/modules/communication_channels/index.ts +19 -0
- package/src/modules/communication_channels/lib/access-control.ts +110 -0
- package/src/modules/communication_channels/lib/adapter-compat.ts +57 -0
- package/src/modules/communication_channels/lib/adapter-registry-singleton.ts +35 -0
- package/src/modules/communication_channels/lib/adapter.ts +605 -0
- package/src/modules/communication_channels/lib/connect-channel.ts +163 -0
- package/src/modules/communication_channels/lib/contact-resolver.ts +162 -0
- package/src/modules/communication_channels/lib/credential-refresh.ts +197 -0
- package/src/modules/communication_channels/lib/dead-letter.ts +87 -0
- package/src/modules/communication_channels/lib/email-capabilities.ts +60 -0
- package/src/modules/communication_channels/lib/email-contact.ts +17 -0
- package/src/modules/communication_channels/lib/email-mime.ts +501 -0
- package/src/modules/communication_channels/lib/error-classification.ts +144 -0
- package/src/modules/communication_channels/lib/gmail-pubsub-jwt.ts +278 -0
- package/src/modules/communication_channels/lib/mutation-guards.ts +215 -0
- package/src/modules/communication_channels/lib/oauth-client-config.ts +79 -0
- package/src/modules/communication_channels/lib/oauth-state.ts +228 -0
- package/src/modules/communication_channels/lib/oauth-token.ts +81 -0
- package/src/modules/communication_channels/lib/pg-errors.ts +12 -0
- package/src/modules/communication_channels/lib/provider-health.ts +47 -0
- package/src/modules/communication_channels/lib/push-state.ts +38 -0
- package/src/modules/communication_channels/lib/queue.ts +66 -0
- package/src/modules/communication_channels/lib/reaction-processor-types.ts +51 -0
- package/src/modules/communication_channels/lib/reaction-semantics.ts +48 -0
- package/src/modules/communication_channels/lib/registry.ts +99 -0
- package/src/modules/communication_channels/lib/route-mutation-guard.ts +68 -0
- package/src/modules/communication_channels/lib/sanitize-channel-html.ts +129 -0
- package/src/modules/communication_channels/lib/send-as-user.ts +284 -0
- package/src/modules/communication_channels/lib/system-user.ts +74 -0
- package/src/modules/communication_channels/lib/test-seed.ts +140 -0
- package/src/modules/communication_channels/lib/thread-matcher.ts +430 -0
- package/src/modules/communication_channels/lib/thread-token.ts +355 -0
- package/src/modules/communication_channels/lib/use-connect-channel.ts +73 -0
- package/src/modules/communication_channels/migrations/.snapshot-open-mercato.json +2142 -0
- package/src/modules/communication_channels/migrations/Migration20260526134719_communication_channels.ts +55 -0
- package/src/modules/communication_channels/migrations/Migration20260527195446_communication_channels.ts +20 -0
- package/src/modules/communication_channels/migrations/Migration20260529231848_communication_channels.ts +13 -0
- package/src/modules/communication_channels/migrations/Migration20260531120000_communication_channels.ts +24 -0
- package/src/modules/communication_channels/notifications.client.ts +50 -0
- package/src/modules/communication_channels/notifications.handlers.ts +86 -0
- package/src/modules/communication_channels/notifications.ts +52 -0
- package/src/modules/communication_channels/setup.ts +158 -0
- package/src/modules/communication_channels/subscribers/channel-requires-reauth-notification.ts +118 -0
- package/src/modules/communication_channels/subscribers/outbound-bridge.ts +175 -0
- package/src/modules/communication_channels/subscribers/user-deleted-cascade.ts +100 -0
- package/src/modules/communication_channels/widgets/components.ts +36 -0
- package/src/modules/communication_channels/widgets/injection/channel-badge/widget.client.tsx +38 -0
- package/src/modules/communication_channels/widgets/injection/channel-badge/widget.ts +51 -0
- package/src/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.tsx +278 -0
- package/src/modules/communication_channels/widgets/injection/channel-info-panel/widget.ts +24 -0
- package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.tsx +63 -0
- package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.ts +29 -0
- package/src/modules/communication_channels/widgets/injection/profile-channels-menu/widget.ts +34 -0
- package/src/modules/communication_channels/widgets/injection/reaction-bar/widget.client.tsx +177 -0
- package/src/modules/communication_channels/widgets/injection/reaction-bar/widget.ts +26 -0
- package/src/modules/communication_channels/widgets/injection-table.ts +47 -0
- package/src/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.tsx +48 -0
- package/src/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.tsx +45 -0
- package/src/modules/communication_channels/widgets/notifications/index.ts +2 -0
- package/src/modules/communication_channels/workers/channel-import-history.ts +252 -0
- package/src/modules/communication_channels/workers/gmail-history-sync.ts +223 -0
- package/src/modules/communication_channels/workers/gmail-renew-watch.ts +141 -0
- package/src/modules/communication_channels/workers/inbound-processor.ts +114 -0
- package/src/modules/communication_channels/workers/outbound-delivery.ts +155 -0
- package/src/modules/communication_channels/workers/poll-channel.ts +391 -0
- package/src/modules/communication_channels/workers/poll-tick.ts +210 -0
- package/src/modules/communication_channels/workers/reaction-processor.ts +264 -0
- package/src/modules/configs/api/openapi.ts +12 -2
- package/src/modules/currencies/backend/currencies/[id]/page.tsx +13 -6
- package/src/modules/currencies/backend/currencies/page.tsx +26 -11
- package/src/modules/currencies/backend/exchange-rates/[id]/page.tsx +3 -0
- package/src/modules/currencies/backend/exchange-rates/page.tsx +21 -12
- package/src/modules/currencies/commands/currencies.ts +42 -18
- package/src/modules/currencies/commands/exchange-rates.ts +18 -8
- package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +31 -21
- package/src/modules/currencies/i18n/de.json +1 -0
- package/src/modules/currencies/i18n/en.json +1 -0
- package/src/modules/currencies/i18n/es.json +1 -0
- package/src/modules/currencies/i18n/pl.json +1 -0
- package/src/modules/customer_accounts/api/admin/roles/[id].ts +35 -5
- package/src/modules/customer_accounts/api/admin/roles.ts +2 -0
- package/src/modules/customer_accounts/api/admin/users/[id].ts +57 -5
- package/src/modules/customer_accounts/api/admin/users-invite.ts +17 -0
- package/src/modules/customer_accounts/api/admin/users.ts +74 -23
- package/src/modules/customer_accounts/api/login.ts +21 -4
- package/src/modules/customer_accounts/api/portal/users-invite.ts +17 -0
- package/src/modules/customer_accounts/api/signup.ts +3 -1
- package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +34 -20
- package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +20 -6
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +11 -4
- package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +28 -17
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +27 -11
- package/src/modules/customer_accounts/data/validators.ts +1 -0
- package/src/modules/customer_accounts/lib/customerEntityOwnership.ts +39 -0
- package/src/modules/customer_accounts/lib/rateLimiter.ts +14 -0
- package/src/modules/customer_accounts/lib/resolveTenantContext.ts +61 -4
- package/src/modules/customer_accounts/services/customerInvitationService.ts +35 -2
- package/src/modules/customer_accounts/services/customerUserService.ts +13 -7
- package/src/modules/customer_accounts/subscribers/autoLinkCrmReverse.ts +3 -3
- package/src/modules/customers/AGENTS.md +8 -2
- package/src/modules/customers/acl.ts +18 -0
- package/src/modules/customers/agentic/standalone-guide.md +1 -1
- package/src/modules/customers/api/activities/route.ts +42 -21
- package/src/modules/customers/api/addresses/route.ts +2 -0
- package/src/modules/customers/api/companies/[id]/route.ts +26 -3
- package/src/modules/customers/api/companies/route.ts +18 -5
- package/src/modules/customers/api/deals/route.ts +3 -0
- package/src/modules/customers/api/dictionaries/[kind]/route.ts +21 -46
- package/src/modules/customers/api/dictionaries/cache.ts +3 -1
- package/src/modules/customers/api/dictionaries/context.ts +1 -1
- package/src/modules/customers/api/interactions/[id]/visibility/route.ts +179 -0
- package/src/modules/customers/api/interactions/counts/route.ts +10 -0
- package/src/modules/customers/api/interactions/route.ts +58 -11
- package/src/modules/customers/api/people/[id]/email-threads/route.ts +92 -0
- package/src/modules/customers/api/people/[id]/emails/route.ts +184 -0
- package/src/modules/customers/api/people/[id]/route.ts +26 -8
- package/src/modules/customers/api/people/route.ts +16 -5
- package/src/modules/customers/api/pipeline-stages/route.ts +0 -14
- package/src/modules/customers/api/settings/dictionary-sort-modes/route.ts +258 -0
- package/src/modules/customers/api/todos/route.ts +29 -11
- package/src/modules/customers/backend/config/customers/deals/page.tsx +1 -0
- package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +36 -21
- package/src/modules/customers/backend/customers/companies/[id]/page.tsx +52 -27
- package/src/modules/customers/backend/customers/companies/page.tsx +11 -1
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +27 -5
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +39 -7
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +1 -0
- package/src/modules/customers/backend/customers/deals/page.tsx +27 -7
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +64 -39
- package/src/modules/customers/backend/customers/people/[id]/page.tsx +46 -26
- package/src/modules/customers/backend/customers/people/page.tsx +11 -1
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +95 -25
- package/src/modules/customers/commands/activities.ts +28 -0
- package/src/modules/customers/commands/addresses.ts +100 -14
- package/src/modules/customers/commands/comments.ts +30 -0
- package/src/modules/customers/commands/companies.ts +121 -1
- package/src/modules/customers/commands/deals.ts +241 -101
- package/src/modules/customers/commands/dictionaries.ts +45 -0
- package/src/modules/customers/commands/entity-roles.ts +49 -0
- package/src/modules/customers/commands/interactions.ts +264 -8
- package/src/modules/customers/commands/labels.ts +85 -0
- package/src/modules/customers/commands/people.ts +208 -13
- package/src/modules/customers/commands/personCompanyLinks.ts +148 -70
- package/src/modules/customers/commands/pipeline-stages.ts +16 -16
- package/src/modules/customers/commands/settings.ts +41 -0
- package/src/modules/customers/commands/tags.ts +59 -0
- package/src/modules/customers/commands/todos.ts +28 -0
- package/src/modules/customers/components/AddressFormatSettings.tsx +1 -0
- package/src/modules/customers/components/CustomersConfigurationSections.tsx +3 -0
- package/src/modules/customers/components/DictionarySettings.tsx +18 -13
- package/src/modules/customers/components/DictionarySortSettings.tsx +268 -0
- package/src/modules/customers/components/PipelineSettings.tsx +42 -21
- package/src/modules/customers/components/detail/ActivityCard.tsx +48 -0
- package/src/modules/customers/components/detail/ActivityForm.tsx +1 -0
- package/src/modules/customers/components/detail/ActivityTimeline.tsx +3 -3
- package/src/modules/customers/components/detail/AddressesSection.tsx +4 -0
- package/src/modules/customers/components/detail/AnnualRevenueField.tsx +1 -0
- package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +2 -0
- package/src/modules/customers/components/detail/ComposeEmailDialog.tsx +329 -0
- package/src/modules/customers/components/detail/DealForm.tsx +3 -1
- package/src/modules/customers/components/detail/DealsSection.tsx +30 -0
- package/src/modules/customers/components/detail/EmailCardActions.tsx +263 -0
- package/src/modules/customers/components/detail/EmailReplyForwardActions.tsx +53 -0
- package/src/modules/customers/components/detail/EntityTagsDialog.tsx +7 -0
- package/src/modules/customers/components/detail/ManageTagsDialog.tsx +4 -0
- package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +4 -0
- package/src/modules/customers/components/detail/PersonDetailTabs.tsx +8 -1
- package/src/modules/customers/components/detail/PersonEmailThreadsTab.tsx +448 -0
- package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +2 -0
- package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +23 -7
- package/src/modules/customers/components/detail/create/DealCurrencyField.tsx +1 -0
- package/src/modules/customers/components/detail/hooks/useCustomerDictionary.ts +1 -0
- package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +25 -15
- package/src/modules/customers/components/detail/hooks/useInteractions.ts +76 -35
- package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +30 -17
- package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +2 -0
- package/src/modules/customers/components/detail/types.ts +1 -0
- package/src/modules/customers/components/formConfig.tsx +134 -30
- package/src/modules/customers/data/enrichers.ts +252 -1
- package/src/modules/customers/data/entities.ts +51 -2
- package/src/modules/customers/data/extensions.ts +26 -0
- package/src/modules/customers/data/guards.ts +67 -0
- package/src/modules/customers/data/validators.ts +46 -13
- package/src/modules/customers/di.ts +66 -0
- package/src/modules/customers/encryption.ts +11 -0
- package/src/modules/customers/events.ts +4 -0
- package/src/modules/customers/i18n/de.json +50 -0
- package/src/modules/customers/i18n/en.json +50 -0
- package/src/modules/customers/i18n/es.json +50 -0
- package/src/modules/customers/i18n/pl.json +50 -0
- package/src/modules/customers/lib/detailTenantScope.ts +36 -0
- package/src/modules/customers/lib/findPeopleByAddresses.ts +107 -0
- package/src/modules/customers/lib/kysely.ts +16 -0
- package/src/modules/customers/lib/link-channel-message-handler.ts +571 -0
- package/src/modules/customers/lib/personCompanyLinkTable.ts +39 -0
- package/src/modules/customers/lib/personEmailThreads.ts +325 -0
- package/src/modules/customers/lib/todoCompatibility.ts +14 -0
- package/src/modules/customers/lib/visibilityFilter.ts +152 -0
- package/src/modules/customers/migrations/.snapshot-open-mercato.json +392 -0
- package/src/modules/customers/migrations/Migration20260527012240_customers.ts +23 -0
- package/src/modules/customers/migrations/Migration20260602202147_customers.ts +13 -0
- package/src/modules/customers/search.ts +6 -0
- package/src/modules/customers/setup.ts +1 -0
- package/src/modules/customers/subscribers/link-channel-message-received.ts +21 -0
- package/src/modules/customers/subscribers/link-channel-message-sent.ts +21 -0
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +2 -0
- package/src/modules/data_sync/api/options.ts +7 -4
- package/src/modules/data_sync/api/schedules/route.ts +9 -1
- package/src/modules/data_sync/backend/data-sync/page.tsx +18 -5
- package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +46 -19
- 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/pl.json +1 -0
- package/src/modules/data_sync/lib/sync-schedule-service.ts +11 -0
- package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +8 -1
- package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +12 -5
- package/src/modules/dictionaries/api/[dictionaryId]/route.ts +31 -0
- package/src/modules/dictionaries/api/openapi.ts +2 -1
- package/src/modules/dictionaries/api/route.ts +7 -0
- package/src/modules/dictionaries/commands/entry-operations.ts +19 -0
- package/src/modules/dictionaries/components/DictionariesManager.tsx +125 -14
- package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +31 -18
- package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +56 -9
- package/src/modules/dictionaries/components/DictionarySelectControl.tsx +9 -0
- package/src/modules/dictionaries/components/dictionaryAppearance.tsx +5 -1
- package/src/modules/dictionaries/components/hooks/useDictionaryEntries.ts +1 -0
- package/src/modules/dictionaries/data/entities.ts +6 -0
- package/src/modules/dictionaries/data/validators.ts +2 -0
- package/src/modules/dictionaries/fields/dictionary.tsx +2 -2
- package/src/modules/dictionaries/i18n/de.json +9 -0
- package/src/modules/dictionaries/i18n/en.json +9 -0
- package/src/modules/dictionaries/i18n/es.json +9 -0
- package/src/modules/dictionaries/i18n/pl.json +9 -0
- package/src/modules/dictionaries/lib/entrySort.ts +73 -0
- package/src/modules/dictionaries/migrations/.snapshot-open-mercato.json +44 -0
- package/src/modules/dictionaries/migrations/Migration20260602202147_dictionaries.ts +13 -0
- package/src/modules/directory/api/get/organizations/lookup.ts +0 -8
- package/src/modules/directory/api/organizations/route.ts +40 -16
- package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +8 -0
- package/src/modules/directory/backend/directory/organizations/page.tsx +18 -5
- package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +16 -5
- package/src/modules/directory/backend/directory/tenants/page.tsx +16 -4
- package/src/modules/directory/commands/organizations.ts +74 -4
- package/src/modules/directory/commands/tenants.ts +14 -1
- package/src/modules/entities/api/records.ts +141 -6
- package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +7 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +8 -4
- package/src/modules/entities/components/UserEntitiesTable.tsx +8 -0
- package/src/modules/entities/lib/entityAcl.ts +108 -0
- package/src/modules/entities/lib/helpers.ts +40 -5
- package/src/modules/feature_toggles/api/global/[id]/override/route.ts +18 -13
- package/src/modules/feature_toggles/api/global/[id]/route.ts +1 -0
- package/src/modules/feature_toggles/api/overrides/route.ts +26 -9
- package/src/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.tsx +42 -15
- package/src/modules/feature_toggles/commands/global.ts +135 -10
- package/src/modules/feature_toggles/commands/overrides.ts +8 -6
- package/src/modules/feature_toggles/components/FeatureToggleOverrideCard.tsx +22 -12
- package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +15 -2
- package/src/modules/feature_toggles/components/formConfig.tsx +2 -1
- package/src/modules/feature_toggles/components/overrideFormConfig.tsx +10 -1
- package/src/modules/feature_toggles/data/validators.ts +11 -3
- package/src/modules/feature_toggles/lib/queries.ts +5 -5
- package/src/modules/feature_toggles/lib/utils.ts +3 -3
- package/src/modules/inbox_ops/api/proposals/[id]/replies/[replyId]/send/route.ts +10 -1
- package/src/modules/inbox_ops/api/settings/route.ts +25 -0
- package/src/modules/inbox_ops/api/webhook/inbound.ts +99 -18
- package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +15 -10
- package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +9 -4
- package/src/modules/inbox_ops/data/entities.ts +7 -0
- package/src/modules/inbox_ops/data/validators.ts +4 -0
- package/src/modules/inbox_ops/encryption.ts +9 -0
- package/src/modules/inbox_ops/i18n/de.json +2 -0
- package/src/modules/inbox_ops/i18n/en.json +2 -0
- package/src/modules/inbox_ops/i18n/es.json +2 -0
- package/src/modules/inbox_ops/i18n/pl.json +2 -0
- package/src/modules/inbox_ops/lib/executionEngine.ts +6 -1
- package/src/modules/inbox_ops/lib/executionHelpers.ts +8 -7
- package/src/modules/inbox_ops/lib/priceValidator.ts +82 -7
- package/src/modules/inbox_ops/lib/rateLimiter.ts +84 -28
- package/src/modules/inbox_ops/lib/translationProvider.ts +37 -5
- package/src/modules/inbox_ops/migrations/.snapshot-open-mercato.json +16 -0
- package/src/modules/inbox_ops/migrations/.snapshot-openmercato.json +16 -0
- package/src/modules/inbox_ops/migrations/Migration20260607205834.ts +13 -0
- package/src/modules/inbox_ops/subscribers/extractionWorker.ts +5 -2
- package/src/modules/integrations/AGENTS.md +9 -0
- package/src/modules/integrations/api/[id]/credentials/route.ts +12 -0
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +13 -0
- package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +20 -11
- package/src/modules/integrations/backend/integrations/page.tsx +13 -8
- package/src/modules/integrations/data/entities.ts +21 -1
- package/src/modules/integrations/i18n/de.json +3 -0
- package/src/modules/integrations/i18n/en.json +3 -0
- package/src/modules/integrations/i18n/es.json +3 -0
- package/src/modules/integrations/i18n/pl.json +3 -0
- package/src/modules/integrations/lib/credentials-field-validation.ts +53 -0
- package/src/modules/integrations/lib/credentials-service.ts +49 -13
- package/src/modules/integrations/migrations/.snapshot-open-mercato.json +26 -1
- package/src/modules/integrations/migrations/Migration20260526154136_integrations.ts +15 -0
- package/src/modules/messages/api/route.ts +2 -2
- package/src/modules/messages/api/token/[token]/route.ts +1 -3
- package/src/modules/messages/commands/actions.ts +8 -6
- package/src/modules/messages/commands/messages.ts +128 -23
- package/src/modules/messages/commands/tokens.ts +1 -3
- package/src/modules/messages/components/ComposeMessagePageClient.tsx +17 -0
- package/src/modules/messages/components/MessageDetailPageClient.tsx +43 -0
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +12 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsActions.ts +6 -2
- package/src/modules/messages/components/message-detail/utils.ts +18 -0
- package/src/modules/messages/data/entities.ts +11 -0
- package/src/modules/messages/data/validators.ts +8 -1
- package/src/modules/messages/lib/actions.ts +9 -3
- package/src/modules/messages/migrations/.snapshot-open-mercato.json +18 -0
- package/src/modules/messages/migrations/Migration20260531130000.ts +15 -0
- package/src/modules/messages/widgets/injection-table.ts +29 -0
- package/src/modules/notifications/api/[id]/action/route.ts +13 -2
- package/src/modules/notifications/api/route.ts +17 -4
- package/src/modules/notifications/lib/notificationService.ts +31 -21
- package/src/modules/notifications/lib/routeHelpers.ts +49 -8
- package/src/modules/payment_gateways/api/status/route.ts +6 -0
- package/src/modules/perspectives/api/[tableId]/route.ts +11 -2
- package/src/modules/perspectives/services/perspectiveService.ts +13 -1
- package/src/modules/planner/backend/planner/availability-rulesets/[id]/page.tsx +16 -14
- package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +6 -3
- package/src/modules/planner/commands/availability-rule-sets.ts +19 -0
- package/src/modules/planner/commands/availability.ts +9 -0
- package/src/modules/planner/components/AvailabilityRuleSetForm.tsx +4 -1
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +74 -17
- package/src/modules/planner/components/AvailabilitySchedule.tsx +22 -7
- package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +15 -16
- package/src/modules/portal/frontend/[orgSlug]/portal/page.tsx +11 -31
- package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +8 -3
- package/src/modules/portal/frontend/[orgSlug]/portal/signup/page.tsx +12 -9
- package/src/modules/progress/api/jobs/[id]/route.ts +7 -0
- package/src/modules/query_index/api/openapi.ts +2 -1
- package/src/modules/query_index/api/reindex.ts +4 -0
- package/src/modules/query_index/data/entities.ts +10 -0
- package/src/modules/query_index/lib/engine.ts +66 -6
- package/src/modules/query_index/lib/indexer.ts +71 -24
- package/src/modules/query_index/lib/jobs.ts +57 -0
- package/src/modules/query_index/lib/reindexer.ts +41 -15
- package/src/modules/query_index/lib/search-tokens.ts +4 -4
- package/src/modules/query_index/migrations/.snapshot-open-mercato.json +9 -0
- package/src/modules/query_index/migrations/Migration20260606205453_query_index.ts +39 -0
- package/src/modules/query_index/subscribers/delete_one.ts +36 -16
- package/src/modules/query_index/subscribers/upsert_one.ts +44 -15
- package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +28 -3
- package/src/modules/resources/backend/resources/resource-types/page.tsx +6 -3
- package/src/modules/resources/backend/resources/resources/[id]/page.tsx +62 -4
- package/src/modules/resources/backend/resources/resources/page.tsx +23 -4
- package/src/modules/resources/commands/activities.ts +67 -0
- package/src/modules/resources/commands/comments.ts +20 -0
- package/src/modules/resources/commands/resource-types.ts +21 -0
- package/src/modules/resources/commands/resources.ts +89 -0
- package/src/modules/resources/commands/tag-assignments.ts +55 -0
- package/src/modules/resources/components/ResourceCrudForm.tsx +103 -56
- package/src/modules/resources/components/ResourceTypeCrudForm.tsx +3 -1
- package/src/modules/resources/i18n/de.json +1 -0
- package/src/modules/resources/i18n/en.json +1 -0
- package/src/modules/resources/i18n/es.json +1 -0
- package/src/modules/resources/i18n/pl.json +1 -0
- package/src/modules/sales/api/documents/factory.ts +13 -1
- package/src/modules/sales/api/shipping-methods/route.ts +4 -0
- package/src/modules/sales/api/tax-rates/route.ts +4 -0
- package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +6 -0
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +10 -4
- package/src/modules/sales/backend/sales/channels/page.tsx +19 -4
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +75 -20
- package/src/modules/sales/backend/sales/documents/create/page.tsx +2 -0
- package/src/modules/sales/commands/configuration.ts +108 -2
- package/src/modules/sales/commands/documentAddresses.ts +226 -4
- package/src/modules/sales/commands/documents.ts +41 -9
- package/src/modules/sales/commands/notes.ts +39 -0
- package/src/modules/sales/commands/payments.ts +160 -14
- package/src/modules/sales/commands/returns.ts +194 -3
- package/src/modules/sales/commands/shared.ts +36 -0
- package/src/modules/sales/commands/shipments.ts +63 -6
- package/src/modules/sales/components/AdjustmentKindSettings.tsx +20 -11
- package/src/modules/sales/components/DocumentNumberSettings.tsx +1 -0
- package/src/modules/sales/components/OrderEditingSettings.tsx +1 -0
- package/src/modules/sales/components/PaymentMethodsSettings.tsx +12 -4
- package/src/modules/sales/components/ShippingMethodsSettings.tsx +12 -4
- package/src/modules/sales/components/StatusSettings.tsx +20 -11
- package/src/modules/sales/components/TaxRatesSettings.tsx +12 -5
- package/src/modules/sales/components/channels/ChannelOfferForm.tsx +85 -20
- package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +10 -4
- package/src/modules/sales/components/documents/AddressesSection.tsx +116 -48
- package/src/modules/sales/components/documents/AdjustmentDialog.tsx +61 -18
- package/src/modules/sales/components/documents/AdjustmentsSection.tsx +50 -25
- package/src/modules/sales/components/documents/ItemsSection.tsx +25 -14
- package/src/modules/sales/components/documents/LineItemDialog.tsx +107 -36
- package/src/modules/sales/components/documents/PaymentDialog.tsx +33 -14
- package/src/modules/sales/components/documents/PaymentsSection.tsx +22 -10
- package/src/modules/sales/components/documents/ReturnDialog.tsx +28 -17
- package/src/modules/sales/components/documents/ReturnsSection.tsx +4 -1
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +1 -0
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +12 -5
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +132 -22
- package/src/modules/sales/components/documents/ShipmentsSection.tsx +20 -10
- package/src/modules/sales/components/documents/optimisticLock.ts +34 -0
- package/src/modules/sales/components/documents/shipmentTypes.ts +1 -0
- package/src/modules/sales/di.ts +35 -0
- package/src/modules/sales/frontend/quote/[token]/page.tsx +8 -1
- package/src/modules/sales/i18n/de.json +4 -0
- package/src/modules/sales/i18n/en.json +4 -0
- package/src/modules/sales/i18n/es.json +4 -0
- package/src/modules/sales/i18n/pl.json +4 -0
- package/src/modules/sales/lib/calculations.ts +32 -4
- package/src/modules/sales/lib/dictionaries.ts +3 -2
- package/src/modules/sales/lib/makeStatusDictionaryRoute.ts +2 -0
- package/src/modules/shipping_carriers/api/cancel/route.ts +2 -2
- package/src/modules/shipping_carriers/lib/status-sync.ts +19 -0
- package/src/modules/staff/api/job-histories.ts +12 -2
- package/src/modules/staff/api/timesheets/time-entries/route.ts +16 -4
- package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +12 -7
- package/src/modules/staff/backend/staff/leave-requests/page.tsx +8 -1
- package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +2 -0
- package/src/modules/staff/backend/staff/profile/create/page.tsx +1 -1
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +16 -5
- package/src/modules/staff/backend/staff/team-members/page.tsx +18 -25
- package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +61 -6
- package/src/modules/staff/backend/staff/team-roles/page.tsx +22 -34
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +13 -3
- package/src/modules/staff/backend/staff/teams/page.tsx +24 -15
- package/src/modules/staff/backend/staff/timesheets/page.tsx +10 -1
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.tsx +22 -3
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +37 -7
- package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +9 -3
- package/src/modules/staff/commands/activities.ts +56 -0
- package/src/modules/staff/commands/addresses.ts +72 -0
- package/src/modules/staff/commands/comments.ts +25 -0
- package/src/modules/staff/commands/job-histories.ts +92 -3
- package/src/modules/staff/commands/leave-requests.ts +40 -0
- package/src/modules/staff/commands/tag-assignments.ts +35 -0
- package/src/modules/staff/commands/team-members.ts +45 -0
- package/src/modules/staff/commands/team-roles.ts +24 -0
- package/src/modules/staff/commands/teams.ts +24 -0
- package/src/modules/staff/commands/timesheets-entries.ts +31 -0
- package/src/modules/staff/commands/timesheets-projects.ts +56 -0
- package/src/modules/staff/components/LeaveRequestForm.tsx +3 -0
- package/src/modules/staff/components/TeamForm.tsx +3 -1
- package/src/modules/staff/components/TeamMemberForm.tsx +36 -3
- package/src/modules/staff/components/TeamRoleForm.tsx +5 -3
- package/src/modules/staff/components/detail/JobHistorySection.tsx +28 -6
- package/src/modules/staff/data/validators.ts +6 -0
- package/src/modules/staff/i18n/de.json +2 -0
- package/src/modules/staff/i18n/en.json +2 -0
- package/src/modules/staff/i18n/es.json +2 -0
- package/src/modules/staff/i18n/pl.json +2 -0
- package/src/modules/staff/lib/leaveRequestHelpers.ts +4 -0
- package/src/modules/translations/api/[entityType]/[entityId]/route.ts +9 -1
- package/src/modules/translations/components/TranslationManager.tsx +13 -8
- package/src/modules/workflows/acl.ts +102 -17
- package/src/modules/workflows/api/definitions/[id]/route.ts +112 -0
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +20 -4
- package/src/modules/workflows/backend/definitions/page.tsx +34 -15
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +29 -16
- package/src/modules/workflows/components/NodeEditDialog.tsx +2 -0
- package/src/modules/workflows/components/WorkflowGraphImpl.tsx +3 -1
- package/src/modules/workflows/components/formConfig.tsx +37 -17
- package/src/modules/workflows/components/nodes/ParallelForkNode.tsx +66 -0
- package/src/modules/workflows/components/nodes/ParallelJoinNode.tsx +66 -0
- package/src/modules/workflows/components/nodes/index.ts +6 -0
- package/src/modules/workflows/data/entities.ts +109 -0
- package/src/modules/workflows/data/validators.ts +223 -0
- package/src/modules/workflows/di.ts +20 -0
- package/src/modules/workflows/events.ts +7 -0
- package/src/modules/workflows/i18n/de.json +13 -0
- package/src/modules/workflows/i18n/en.json +13 -0
- package/src/modules/workflows/i18n/es.json +13 -0
- package/src/modules/workflows/i18n/pl.json +13 -0
- package/src/modules/workflows/lib/activity-executor.ts +8 -2
- package/src/modules/workflows/lib/activity-queue-types.ts +3 -0
- package/src/modules/workflows/lib/event-logger.ts +3 -0
- package/src/modules/workflows/lib/execution-token.ts +166 -0
- package/src/modules/workflows/lib/node-type-icons.ts +11 -2
- package/src/modules/workflows/lib/parallel-handler.ts +575 -0
- package/src/modules/workflows/lib/signal-handler.ts +72 -1
- package/src/modules/workflows/lib/step-handler.ts +94 -34
- package/src/modules/workflows/lib/task-handler.ts +32 -0
- package/src/modules/workflows/lib/timer-handler.ts +30 -1
- package/src/modules/workflows/lib/transition-handler.ts +56 -24
- package/src/modules/workflows/lib/workflow-executor.ts +70 -1
- package/src/modules/workflows/migrations/.snapshot-open-mercato.json +263 -0
- package/src/modules/workflows/migrations/Migration20260602120000.ts +25 -0
- package/src/modules/workflows/workers/workflow-activities.worker.ts +9 -4
|
@@ -11,7 +11,11 @@ import { loadCustomFieldValues } from "@open-mercato/shared/lib/crud/custom-fiel
|
|
|
11
11
|
import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
12
12
|
import { roleCrudEvents, roleCrudIndexer } from "@open-mercato/core/modules/auth/commands/roles";
|
|
13
13
|
import { escapeLikePattern } from "@open-mercato/shared/lib/db/escapeLikePattern";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
assertActorCanAccessRoleTarget,
|
|
16
|
+
assertActorCanModifySuperAdminRoleTarget
|
|
17
|
+
} from "@open-mercato/core/modules/auth/lib/grantChecks";
|
|
18
|
+
import { enforceTenantSelection } from "@open-mercato/core/modules/auth/lib/tenantAccess";
|
|
15
19
|
const querySchema = z.object({
|
|
16
20
|
id: z.string().uuid().optional(),
|
|
17
21
|
page: z.coerce.number().min(1).default(1),
|
|
@@ -34,7 +38,8 @@ const roleListItemSchema = z.object({
|
|
|
34
38
|
usersCount: z.number().int().nonnegative(),
|
|
35
39
|
tenantId: z.string().uuid().nullable(),
|
|
36
40
|
tenantIds: z.array(z.string().uuid()).optional(),
|
|
37
|
-
tenantName: z.string().nullable()
|
|
41
|
+
tenantName: z.string().nullable(),
|
|
42
|
+
updatedAt: z.string().nullable().optional()
|
|
38
43
|
});
|
|
39
44
|
const roleListResponseSchema = z.object({
|
|
40
45
|
items: z.array(roleListItemSchema),
|
|
@@ -67,7 +72,16 @@ const crud = makeCrudRoute({
|
|
|
67
72
|
create: {
|
|
68
73
|
commandId: "auth.roles.create",
|
|
69
74
|
schema: rawBodySchema,
|
|
70
|
-
mapInput: ({ parsed }) =>
|
|
75
|
+
mapInput: async ({ parsed, ctx }) => {
|
|
76
|
+
if (parsed.tenantId === null) return parsed;
|
|
77
|
+
const requestedTenantId = typeof parsed.tenantId === "string" ? parsed.tenantId : void 0;
|
|
78
|
+
const resolvedTenantId = await enforceTenantSelection(
|
|
79
|
+
{ auth: ctx.auth, container: ctx.container },
|
|
80
|
+
requestedTenantId
|
|
81
|
+
);
|
|
82
|
+
if (resolvedTenantId) parsed.tenantId = resolvedTenantId;
|
|
83
|
+
return parsed;
|
|
84
|
+
},
|
|
71
85
|
response: ({ result }) => ({ id: String(result.id) }),
|
|
72
86
|
status: 201
|
|
73
87
|
},
|
|
@@ -77,6 +91,7 @@ const crud = makeCrudRoute({
|
|
|
77
91
|
mapInput: async ({ parsed, ctx }) => {
|
|
78
92
|
if (ctx.request && typeof parsed.id === "string" && parsed.id.length) {
|
|
79
93
|
await assertCanModifySuperAdminRole(ctx.request, parsed.id);
|
|
94
|
+
await assertCanAccessRoleTarget(ctx.request, parsed.id);
|
|
80
95
|
}
|
|
81
96
|
return parsed;
|
|
82
97
|
},
|
|
@@ -84,6 +99,14 @@ const crud = makeCrudRoute({
|
|
|
84
99
|
},
|
|
85
100
|
delete: {
|
|
86
101
|
commandId: "auth.roles.delete",
|
|
102
|
+
mapInput: async ({ parsed, raw, ctx }) => {
|
|
103
|
+
const targetId = resolveDeleteTargetId(parsed, raw);
|
|
104
|
+
if (ctx.request && targetId) {
|
|
105
|
+
await assertCanModifySuperAdminRole(ctx.request, targetId);
|
|
106
|
+
await assertCanAccessRoleTarget(ctx.request, targetId);
|
|
107
|
+
}
|
|
108
|
+
return parsed;
|
|
109
|
+
},
|
|
87
110
|
response: () => ({ ok: true })
|
|
88
111
|
}
|
|
89
112
|
}
|
|
@@ -200,6 +223,7 @@ async function GET(req) {
|
|
|
200
223
|
tenantId: tenantId ?? null,
|
|
201
224
|
tenantIds: exposeTenant && tenantId ? [tenantId] : [],
|
|
202
225
|
tenantName: exposeTenant ? tenantName : null,
|
|
226
|
+
updatedAt: r.updatedAt instanceof Date ? r.updatedAt.toISOString() : null,
|
|
203
227
|
...cfByRole[idStr] || {}
|
|
204
228
|
};
|
|
205
229
|
});
|
|
@@ -225,6 +249,7 @@ const DELETE = async (req) => {
|
|
|
225
249
|
if (targetId) {
|
|
226
250
|
try {
|
|
227
251
|
await assertCanModifySuperAdminRole(req, targetId);
|
|
252
|
+
await assertCanAccessRoleTarget(req, targetId);
|
|
228
253
|
} catch (err) {
|
|
229
254
|
if (err instanceof CrudHttpError) {
|
|
230
255
|
return NextResponse.json(err.body, { status: err.status });
|
|
@@ -248,6 +273,30 @@ async function assertCanModifySuperAdminRole(req, targetRoleId) {
|
|
|
248
273
|
targetRoleId
|
|
249
274
|
});
|
|
250
275
|
}
|
|
276
|
+
async function assertCanAccessRoleTarget(req, targetRoleId) {
|
|
277
|
+
const auth = await getAuthFromRequest(req);
|
|
278
|
+
if (!auth?.sub) throw new CrudHttpError(401, { error: "Unauthorized" });
|
|
279
|
+
const container = await createRequestContainer();
|
|
280
|
+
const em = container.resolve("em");
|
|
281
|
+
await assertActorCanAccessRoleTarget({
|
|
282
|
+
em,
|
|
283
|
+
rbacService: container.resolve("rbacService"),
|
|
284
|
+
actorUserId: auth.sub,
|
|
285
|
+
tenantId: auth.tenantId ?? null,
|
|
286
|
+
organizationId: auth.orgId ?? null,
|
|
287
|
+
targetRoleId
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
function resolveDeleteTargetId(parsed, raw) {
|
|
291
|
+
const fromParsed = readId(parsed);
|
|
292
|
+
if (fromParsed) return fromParsed;
|
|
293
|
+
const rawRecord = raw;
|
|
294
|
+
return readId(rawRecord?.query) ?? readId(rawRecord?.body);
|
|
295
|
+
}
|
|
296
|
+
function readId(record) {
|
|
297
|
+
const value = record?.id;
|
|
298
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
299
|
+
}
|
|
251
300
|
const openApi = {
|
|
252
301
|
tag: "Authentication & Accounts",
|
|
253
302
|
summary: "Role management",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/auth/api/roles/route.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { logCrudAccess, makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { Role, RoleAcl, UserRole } from '@open-mercato/core/modules/auth/data/entities'\nimport { Tenant } from '@open-mercato/core/modules/directory/data/entities'\nimport { E } from '#generated/entities.ids.generated'\nimport { loadCustomFieldValues } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { roleCrudEvents, roleCrudIndexer } from '@open-mercato/core/modules/auth/commands/roles'\nimport { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'\nimport { assertActorCanModifySuperAdminRoleTarget } from '@open-mercato/core/modules/auth/lib/grantChecks'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\n\nconst querySchema = z.object({\n id: z.string().uuid().optional(),\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(100).default(50),\n search: z.string().optional(),\n tenantId: z.string().uuid().optional(),\n}).passthrough()\n\nconst roleCreateSchema = z.object({\n name: z.string().min(2).max(100),\n tenantId: z.string().uuid().optional(),\n})\n\nconst roleUpdateSchema = z.object({\n id: z.string().uuid(),\n name: z.string().min(2).max(100).optional(),\n tenantId: z.string().uuid().optional(),\n})\n\nconst roleListItemSchema = z.object({\n id: z.string().uuid(),\n name: z.string(),\n usersCount: z.number().int().nonnegative(),\n tenantId: z.string().uuid().nullable(),\n tenantIds: z.array(z.string().uuid()).optional(),\n tenantName: z.string().nullable(),\n})\n\nconst roleListResponseSchema = z.object({\n items: z.array(roleListItemSchema),\n total: z.number().int().nonnegative(),\n totalPages: z.number().int().positive(),\n isSuperAdmin: z.boolean().optional(),\n})\n\nconst okResponseSchema = z.object({ ok: z.literal(true) })\n\nconst errorResponseSchema = z.object({ error: z.string() })\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['auth.roles.list'] },\n POST: { requireAuth: true, requireFeatures: ['auth.roles.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['auth.roles.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['auth.roles.manage'] },\n}\n\nexport const metadata = routeMetadata\n\nconst rawBodySchema = z.object({}).passthrough()\ntype CrudInput = Record<string, unknown>\n\nconst crud = makeCrudRoute<CrudInput, CrudInput, Record<string, unknown>>({\n metadata: routeMetadata,\n orm: {\n entity: Role,\n idField: 'id',\n orgField: null,\n tenantField: null,\n softDeleteField: 'deletedAt',\n },\n events: roleCrudEvents,\n indexer: roleCrudIndexer,\n actions: {\n create: {\n commandId: 'auth.roles.create',\n schema: rawBodySchema,\n mapInput: ({ parsed }) => parsed,\n response: ({ result }) => ({ id: String(result.id) }),\n status: 201,\n },\n update: {\n commandId: 'auth.roles.update',\n schema: rawBodySchema,\n mapInput: async ({ parsed, ctx }) => {\n if (ctx.request && typeof parsed.id === 'string' && parsed.id.length) {\n await assertCanModifySuperAdminRole(ctx.request, parsed.id)\n }\n return parsed\n },\n response: () => ({ ok: true }),\n },\n delete: {\n commandId: 'auth.roles.delete',\n response: () => ({ ok: true }),\n },\n },\n})\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ items: [], total: 0, totalPages: 1 })\n const url = new URL(req.url)\n const parsed = querySchema.safeParse({\n id: url.searchParams.get('id') || undefined,\n page: url.searchParams.get('page') || undefined,\n pageSize: url.searchParams.get('pageSize') || undefined,\n search: url.searchParams.get('search') || undefined,\n tenantId: url.searchParams.get('tenantId') || undefined,\n })\n if (!parsed.success) return NextResponse.json({ items: [], total: 0, totalPages: 1 })\n const container = await createRequestContainer()\n const em = (container.resolve('em') as EntityManager)\n let isSuperAdmin = false\n try {\n if (auth.sub) {\n const rbacService = container.resolve('rbacService') as any\n const acl = await rbacService.loadAcl(auth.sub, { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null })\n isSuperAdmin = !!acl?.isSuperAdmin\n }\n } catch (err) {\n console.error('roles: failed to resolve rbac', err)\n }\n const actorTenantId = auth.tenantId ? String(auth.tenantId) : null\n if (!isSuperAdmin && !actorTenantId) {\n return NextResponse.json({ items: [], total: 0, totalPages: 1, isSuperAdmin })\n }\n let superAdminRoleIds: Set<string> | null = null\n if (!isSuperAdmin && actorTenantId) {\n const superAdminAcls = await findWithDecryption(em, RoleAcl, { tenantId: actorTenantId, isSuperAdmin: true }, {}, { tenantId: actorTenantId, organizationId: null })\n if (superAdminAcls.length) {\n superAdminRoleIds = new Set(\n superAdminAcls\n .map((acl) => {\n const roleRef = acl.role\n const idValue = roleRef?.id\n return idValue ? String(idValue) : null\n })\n .filter((id): id is string => !!id),\n )\n } else {\n superAdminRoleIds = new Set()\n }\n }\n const { id, page, pageSize, search, tenantId: requestedTenantId } = parsed.data\n const tenantFilter = isSuperAdmin && requestedTenantId ? String(requestedTenantId) : null\n const filters: any[] = [{ deletedAt: null }]\n if (id) filters.push({ id })\n if (search) filters.push({ name: { $ilike: `%${escapeLikePattern(search)}%` } })\n if (!isSuperAdmin && actorTenantId) {\n filters.push({ tenantId: actorTenantId })\n filters.push({ name: { $ne: 'superadmin' } })\n if (superAdminRoleIds && superAdminRoleIds.size) {\n filters.push({ id: { $nin: Array.from(superAdminRoleIds) } })\n }\n } else if (tenantFilter) {\n filters.push({ tenantId: tenantFilter })\n }\n const where = filters.length > 1 ? { $and: filters } : filters[0]\n const [rows, count] = await em.findAndCount(Role, where, { limit: pageSize, offset: (page - 1) * pageSize })\n const roleIds = rows.map((r: any) => String(r.id))\n const counts: Record<string, number> = {}\n if (roleIds.length) {\n const userRoleFilter: FilterQuery<UserRole> = { role: { $in: roleIds }, deletedAt: null }\n const links = await findWithDecryption(em, UserRole, userRoleFilter, {}, { tenantId: null, organizationId: null })\n for (const l of links) {\n const rid = String((l as any).role?.id || (l as any).role)\n counts[rid] = (counts[rid] || 0) + 1\n }\n }\n const roleTenantIds = rows\n .map((role: any) => (role.tenantId ? String(role.tenantId) : null))\n .filter((tenantId): tenantId is string => typeof tenantId === 'string' && tenantId.length > 0)\n const uniqueTenantIds = Array.from(new Set(roleTenantIds))\n let tenantMap: Record<string, string> = {}\n if (uniqueTenantIds.length) {\n const tenants = await findWithDecryption(em, Tenant, { id: { $in: uniqueTenantIds as any }, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n tenantMap = tenants.reduce<Record<string, string>>((acc, tenant) => {\n const tid = tenant?.id ? String(tenant.id) : null\n if (!tid) return acc\n const rawName = (tenant as any)?.name\n const name = typeof rawName === 'string' && rawName.length > 0 ? rawName : tid\n acc[tid] = name\n return acc\n }, {})\n }\n const tenantByRole: Record<string, string | null> = {}\n for (const role of rows) {\n const rid = String(role.id)\n tenantByRole[rid] = role.tenantId ? String(role.tenantId) : null\n }\n const tenantFallbacks = Array.from(new Set<string | null>([\n auth.tenantId ?? null,\n tenantFilter ?? null,\n ...Object.values(tenantByRole),\n ]))\n const cfByRole = roleIds.length\n ? await loadCustomFieldValues({\n em,\n entityId: E.auth.role,\n recordIds: roleIds,\n tenantIdByRecord: tenantByRole,\n tenantFallbacks,\n })\n : {}\n const items = rows.map((r: any) => {\n const idStr = String(r.id)\n const tenantId = tenantByRole[idStr]\n const tenantName = tenantId ? tenantMap[tenantId] ?? tenantId : null\n const exposeTenant = isSuperAdmin || (tenantId && auth.tenantId && tenantId === auth.tenantId)\n return {\n id: idStr,\n name: String(r.name),\n usersCount: counts[idStr] || 0,\n tenantId: tenantId ?? null,\n tenantIds: exposeTenant && tenantId ? [tenantId] : [],\n tenantName: exposeTenant ? tenantName : null,\n ...(cfByRole[idStr] || {}),\n }\n })\n const totalPages = Math.max(1, Math.ceil(count / pageSize))\n await logCrudAccess({\n container,\n auth,\n request: req,\n items,\n idField: 'id',\n resourceKind: 'auth.role',\n organizationId: null,\n tenantId: auth.tenantId ?? null,\n query: parsed.data,\n accessType: id ? 'read:item' : undefined,\n })\n return NextResponse.json({ items, total: count, totalPages, isSuperAdmin })\n}\n\nexport const POST = crud.POST\nexport const PUT = crud.PUT\nexport const DELETE = async (req: Request) => {\n const targetId = new URL(req.url).searchParams.get('id')\n if (targetId) {\n try {\n await assertCanModifySuperAdminRole(req, targetId)\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return NextResponse.json(err.body, { status: err.status })\n }\n throw err\n }\n }\n return crud.DELETE(req)\n}\n\nasync function assertCanModifySuperAdminRole(req: Request, targetRoleId: string) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.sub) throw new CrudHttpError(401, { error: 'Unauthorized' })\n const container = await createRequestContainer()\n const em = container.resolve('em') as EntityManager\n await assertActorCanModifySuperAdminRoleTarget({\n em,\n rbacService: container.resolve('rbacService') as RbacService,\n actorUserId: auth.sub,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n targetRoleId,\n })\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Authentication & Accounts',\n summary: 'Role management',\n methods: {\n GET: {\n summary: 'List roles',\n description:\n 'Returns available roles within the current tenant. Super administrators receive visibility across tenants.',\n query: querySchema,\n responses: [\n { status: 200, description: 'Role collection', schema: roleListResponseSchema },\n ],\n },\n POST: {\n summary: 'Create role',\n description: 'Creates a new role for the current tenant or globally when `tenantId` is omitted.',\n requestBody: {\n contentType: 'application/json',\n schema: roleCreateSchema,\n },\n responses: [\n {\n status: 201,\n description: 'Role created',\n schema: z.object({ id: z.string().uuid() }),\n },\n ],\n errors: [\n { status: 400, description: 'Invalid payload', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n ],\n },\n PUT: {\n summary: 'Update role',\n description: 'Updates mutable fields on an existing role.',\n requestBody: {\n contentType: 'application/json',\n schema: roleUpdateSchema,\n },\n responses: [\n {\n status: 200,\n description: 'Role updated',\n schema: okResponseSchema,\n },\n ],\n errors: [\n { status: 400, description: 'Invalid payload', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n { status: 404, description: 'Role not found', schema: errorResponseSchema },\n ],\n },\n DELETE: {\n summary: 'Delete role',\n description: 'Deletes a role by identifier. Fails when users remain assigned.',\n query: z.object({ id: z.string().uuid().describe('Role identifier') }),\n responses: [\n { status: 200, description: 'Role deleted', schema: okResponseSchema },\n ],\n errors: [\n { status: 400, description: 'Role cannot be deleted', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n { status: 404, description: 'Role not found', schema: errorResponseSchema },\n ],\n },\n },\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { logCrudAccess, makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { Role, RoleAcl, UserRole } from '@open-mercato/core/modules/auth/data/entities'\nimport { Tenant } from '@open-mercato/core/modules/directory/data/entities'\nimport { E } from '#generated/entities.ids.generated'\nimport { loadCustomFieldValues } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { roleCrudEvents, roleCrudIndexer } from '@open-mercato/core/modules/auth/commands/roles'\nimport { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'\nimport {\n assertActorCanAccessRoleTarget,\n assertActorCanModifySuperAdminRoleTarget,\n} from '@open-mercato/core/modules/auth/lib/grantChecks'\nimport { enforceTenantSelection } from '@open-mercato/core/modules/auth/lib/tenantAccess'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\n\nconst querySchema = z.object({\n id: z.string().uuid().optional(),\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(100).default(50),\n search: z.string().optional(),\n tenantId: z.string().uuid().optional(),\n}).passthrough()\n\nconst roleCreateSchema = z.object({\n name: z.string().min(2).max(100),\n tenantId: z.string().uuid().optional(),\n})\n\nconst roleUpdateSchema = z.object({\n id: z.string().uuid(),\n name: z.string().min(2).max(100).optional(),\n tenantId: z.string().uuid().optional(),\n})\n\nconst roleListItemSchema = z.object({\n id: z.string().uuid(),\n name: z.string(),\n usersCount: z.number().int().nonnegative(),\n tenantId: z.string().uuid().nullable(),\n tenantIds: z.array(z.string().uuid()).optional(),\n tenantName: z.string().nullable(),\n updatedAt: z.string().nullable().optional(),\n})\n\nconst roleListResponseSchema = z.object({\n items: z.array(roleListItemSchema),\n total: z.number().int().nonnegative(),\n totalPages: z.number().int().positive(),\n isSuperAdmin: z.boolean().optional(),\n})\n\nconst okResponseSchema = z.object({ ok: z.literal(true) })\n\nconst errorResponseSchema = z.object({ error: z.string() })\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['auth.roles.list'] },\n POST: { requireAuth: true, requireFeatures: ['auth.roles.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['auth.roles.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['auth.roles.manage'] },\n}\n\nexport const metadata = routeMetadata\n\nconst rawBodySchema = z.object({}).passthrough()\ntype CrudInput = Record<string, unknown>\n\nconst crud = makeCrudRoute<CrudInput, CrudInput, Record<string, unknown>>({\n metadata: routeMetadata,\n orm: {\n entity: Role,\n idField: 'id',\n orgField: null,\n tenantField: null,\n softDeleteField: 'deletedAt',\n },\n events: roleCrudEvents,\n indexer: roleCrudIndexer,\n actions: {\n create: {\n commandId: 'auth.roles.create',\n schema: rawBodySchema,\n mapInput: async ({ parsed, ctx }) => {\n // Preserve an explicit null so the create command rejects it (400 \u2014 global\n // roles are unsupported); only resolve string/omitted tenantId against the actor.\n if (parsed.tenantId === null) return parsed\n const requestedTenantId = typeof parsed.tenantId === 'string' ? parsed.tenantId : undefined\n const resolvedTenantId = await enforceTenantSelection(\n { auth: ctx.auth, container: ctx.container },\n requestedTenantId,\n )\n if (resolvedTenantId) parsed.tenantId = resolvedTenantId\n return parsed\n },\n response: ({ result }) => ({ id: String(result.id) }),\n status: 201,\n },\n update: {\n commandId: 'auth.roles.update',\n schema: rawBodySchema,\n mapInput: async ({ parsed, ctx }) => {\n if (ctx.request && typeof parsed.id === 'string' && parsed.id.length) {\n await assertCanModifySuperAdminRole(ctx.request, parsed.id)\n await assertCanAccessRoleTarget(ctx.request, parsed.id)\n }\n return parsed\n },\n response: () => ({ ok: true }),\n },\n delete: {\n commandId: 'auth.roles.delete',\n mapInput: async ({ parsed, raw, ctx }) => {\n const targetId = resolveDeleteTargetId(parsed, raw)\n if (ctx.request && targetId) {\n await assertCanModifySuperAdminRole(ctx.request, targetId)\n await assertCanAccessRoleTarget(ctx.request, targetId)\n }\n return parsed\n },\n response: () => ({ ok: true }),\n },\n },\n})\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ items: [], total: 0, totalPages: 1 })\n const url = new URL(req.url)\n const parsed = querySchema.safeParse({\n id: url.searchParams.get('id') || undefined,\n page: url.searchParams.get('page') || undefined,\n pageSize: url.searchParams.get('pageSize') || undefined,\n search: url.searchParams.get('search') || undefined,\n tenantId: url.searchParams.get('tenantId') || undefined,\n })\n if (!parsed.success) return NextResponse.json({ items: [], total: 0, totalPages: 1 })\n const container = await createRequestContainer()\n const em = (container.resolve('em') as EntityManager)\n let isSuperAdmin = false\n try {\n if (auth.sub) {\n const rbacService = container.resolve('rbacService') as any\n const acl = await rbacService.loadAcl(auth.sub, { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null })\n isSuperAdmin = !!acl?.isSuperAdmin\n }\n } catch (err) {\n console.error('roles: failed to resolve rbac', err)\n }\n const actorTenantId = auth.tenantId ? String(auth.tenantId) : null\n if (!isSuperAdmin && !actorTenantId) {\n return NextResponse.json({ items: [], total: 0, totalPages: 1, isSuperAdmin })\n }\n let superAdminRoleIds: Set<string> | null = null\n if (!isSuperAdmin && actorTenantId) {\n const superAdminAcls = await findWithDecryption(em, RoleAcl, { tenantId: actorTenantId, isSuperAdmin: true }, {}, { tenantId: actorTenantId, organizationId: null })\n if (superAdminAcls.length) {\n superAdminRoleIds = new Set(\n superAdminAcls\n .map((acl) => {\n const roleRef = acl.role\n const idValue = roleRef?.id\n return idValue ? String(idValue) : null\n })\n .filter((id): id is string => !!id),\n )\n } else {\n superAdminRoleIds = new Set()\n }\n }\n const { id, page, pageSize, search, tenantId: requestedTenantId } = parsed.data\n const tenantFilter = isSuperAdmin && requestedTenantId ? String(requestedTenantId) : null\n const filters: any[] = [{ deletedAt: null }]\n if (id) filters.push({ id })\n if (search) filters.push({ name: { $ilike: `%${escapeLikePattern(search)}%` } })\n if (!isSuperAdmin && actorTenantId) {\n filters.push({ tenantId: actorTenantId })\n filters.push({ name: { $ne: 'superadmin' } })\n if (superAdminRoleIds && superAdminRoleIds.size) {\n filters.push({ id: { $nin: Array.from(superAdminRoleIds) } })\n }\n } else if (tenantFilter) {\n filters.push({ tenantId: tenantFilter })\n }\n const where = filters.length > 1 ? { $and: filters } : filters[0]\n const [rows, count] = await em.findAndCount(Role, where, { limit: pageSize, offset: (page - 1) * pageSize })\n const roleIds = rows.map((r: any) => String(r.id))\n const counts: Record<string, number> = {}\n if (roleIds.length) {\n const userRoleFilter: FilterQuery<UserRole> = { role: { $in: roleIds }, deletedAt: null }\n const links = await findWithDecryption(em, UserRole, userRoleFilter, {}, { tenantId: null, organizationId: null })\n for (const l of links) {\n const rid = String((l as any).role?.id || (l as any).role)\n counts[rid] = (counts[rid] || 0) + 1\n }\n }\n const roleTenantIds = rows\n .map((role: any) => (role.tenantId ? String(role.tenantId) : null))\n .filter((tenantId): tenantId is string => typeof tenantId === 'string' && tenantId.length > 0)\n const uniqueTenantIds = Array.from(new Set(roleTenantIds))\n let tenantMap: Record<string, string> = {}\n if (uniqueTenantIds.length) {\n const tenants = await findWithDecryption(em, Tenant, { id: { $in: uniqueTenantIds as any }, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n tenantMap = tenants.reduce<Record<string, string>>((acc, tenant) => {\n const tid = tenant?.id ? String(tenant.id) : null\n if (!tid) return acc\n const rawName = (tenant as any)?.name\n const name = typeof rawName === 'string' && rawName.length > 0 ? rawName : tid\n acc[tid] = name\n return acc\n }, {})\n }\n const tenantByRole: Record<string, string | null> = {}\n for (const role of rows) {\n const rid = String(role.id)\n tenantByRole[rid] = role.tenantId ? String(role.tenantId) : null\n }\n const tenantFallbacks = Array.from(new Set<string | null>([\n auth.tenantId ?? null,\n tenantFilter ?? null,\n ...Object.values(tenantByRole),\n ]))\n const cfByRole = roleIds.length\n ? await loadCustomFieldValues({\n em,\n entityId: E.auth.role,\n recordIds: roleIds,\n tenantIdByRecord: tenantByRole,\n tenantFallbacks,\n })\n : {}\n const items = rows.map((r: any) => {\n const idStr = String(r.id)\n const tenantId = tenantByRole[idStr]\n const tenantName = tenantId ? tenantMap[tenantId] ?? tenantId : null\n const exposeTenant = isSuperAdmin || (tenantId && auth.tenantId && tenantId === auth.tenantId)\n return {\n id: idStr,\n name: String(r.name),\n usersCount: counts[idStr] || 0,\n tenantId: tenantId ?? null,\n tenantIds: exposeTenant && tenantId ? [tenantId] : [],\n tenantName: exposeTenant ? tenantName : null,\n updatedAt: r.updatedAt instanceof Date ? r.updatedAt.toISOString() : null,\n ...(cfByRole[idStr] || {}),\n }\n })\n const totalPages = Math.max(1, Math.ceil(count / pageSize))\n await logCrudAccess({\n container,\n auth,\n request: req,\n items,\n idField: 'id',\n resourceKind: 'auth.role',\n organizationId: null,\n tenantId: auth.tenantId ?? null,\n query: parsed.data,\n accessType: id ? 'read:item' : undefined,\n })\n return NextResponse.json({ items, total: count, totalPages, isSuperAdmin })\n}\n\nexport const POST = crud.POST\nexport const PUT = crud.PUT\nexport const DELETE = async (req: Request) => {\n const targetId = new URL(req.url).searchParams.get('id')\n if (targetId) {\n try {\n await assertCanModifySuperAdminRole(req, targetId)\n await assertCanAccessRoleTarget(req, targetId)\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return NextResponse.json(err.body, { status: err.status })\n }\n throw err\n }\n }\n return crud.DELETE(req)\n}\n\nasync function assertCanModifySuperAdminRole(req: Request, targetRoleId: string) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.sub) throw new CrudHttpError(401, { error: 'Unauthorized' })\n const container = await createRequestContainer()\n const em = container.resolve('em') as EntityManager\n await assertActorCanModifySuperAdminRoleTarget({\n em,\n rbacService: container.resolve('rbacService') as RbacService,\n actorUserId: auth.sub,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n targetRoleId,\n })\n}\n\nasync function assertCanAccessRoleTarget(req: Request, targetRoleId: string) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.sub) throw new CrudHttpError(401, { error: 'Unauthorized' })\n const container = await createRequestContainer()\n const em = container.resolve('em') as EntityManager\n await assertActorCanAccessRoleTarget({\n em,\n rbacService: container.resolve('rbacService') as RbacService,\n actorUserId: auth.sub,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n targetRoleId,\n })\n}\n\nfunction resolveDeleteTargetId(parsed: unknown, raw: unknown): string | null {\n const fromParsed = readId(parsed as Record<string, unknown> | null | undefined)\n if (fromParsed) return fromParsed\n const rawRecord = raw as { body?: Record<string, unknown>; query?: Record<string, unknown> } | null | undefined\n return readId(rawRecord?.query) ?? readId(rawRecord?.body)\n}\n\nfunction readId(record: Record<string, unknown> | null | undefined): string | null {\n const value = record?.id\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Authentication & Accounts',\n summary: 'Role management',\n methods: {\n GET: {\n summary: 'List roles',\n description:\n 'Returns available roles within the current tenant. Super administrators receive visibility across tenants.',\n query: querySchema,\n responses: [\n { status: 200, description: 'Role collection', schema: roleListResponseSchema },\n ],\n },\n POST: {\n summary: 'Create role',\n description: 'Creates a new role for the current tenant or globally when `tenantId` is omitted.',\n requestBody: {\n contentType: 'application/json',\n schema: roleCreateSchema,\n },\n responses: [\n {\n status: 201,\n description: 'Role created',\n schema: z.object({ id: z.string().uuid() }),\n },\n ],\n errors: [\n { status: 400, description: 'Invalid payload', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n ],\n },\n PUT: {\n summary: 'Update role',\n description: 'Updates mutable fields on an existing role.',\n requestBody: {\n contentType: 'application/json',\n schema: roleUpdateSchema,\n },\n responses: [\n {\n status: 200,\n description: 'Role updated',\n schema: okResponseSchema,\n },\n ],\n errors: [\n { status: 400, description: 'Invalid payload', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n { status: 404, description: 'Role not found', schema: errorResponseSchema },\n ],\n },\n DELETE: {\n summary: 'Delete role',\n description: 'Deletes a role by identifier. Fails when users remain assigned.',\n query: z.object({ id: z.string().uuid().describe('Role identifier') }),\n responses: [\n { status: 200, description: 'Role deleted', schema: okResponseSchema },\n ],\n errors: [\n { status: 400, description: 'Role cannot be deleted', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n { status: 404, description: 'Role not found', schema: errorResponseSchema },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["id"]
|
|
7
7
|
}
|
|
@@ -8,13 +8,17 @@ import {
|
|
|
8
8
|
sidebarPreferencesScopeSchema
|
|
9
9
|
} from "../../../data/validators.js";
|
|
10
10
|
import {
|
|
11
|
+
loadRoleSidebarPreferenceUpdatedAt,
|
|
11
12
|
loadRoleSidebarPreferences,
|
|
12
13
|
loadSidebarPreference,
|
|
14
|
+
loadSidebarPreferenceUpdatedAt,
|
|
13
15
|
saveRoleSidebarPreference,
|
|
14
16
|
saveSidebarPreference
|
|
15
17
|
} from "../../../services/sidebarPreferencesService.js";
|
|
16
18
|
import { SIDEBAR_PREFERENCES_VERSION } from "@open-mercato/shared/modules/navigation/sidebarPreferences";
|
|
17
19
|
import { withAtomicFlush } from "@open-mercato/shared/lib/commands/flush";
|
|
20
|
+
import { enforceCommandOptimisticLock } from "@open-mercato/shared/lib/crud/optimistic-lock-command";
|
|
21
|
+
import { isCrudHttpError } from "@open-mercato/shared/lib/crud/errors";
|
|
18
22
|
import { Role, RoleSidebarPreference } from "../../../data/entities.js";
|
|
19
23
|
import { z } from "zod";
|
|
20
24
|
const metadata = {
|
|
@@ -40,7 +44,8 @@ const sidebarPreferencesResponseSchema = z.object({
|
|
|
40
44
|
settings: sidebarSettingsSchema,
|
|
41
45
|
canApplyToRoles: z.boolean(),
|
|
42
46
|
roles: z.array(sidebarRoleEntrySchema),
|
|
43
|
-
scope: sidebarPreferencesScopeSchema
|
|
47
|
+
scope: sidebarPreferencesScopeSchema,
|
|
48
|
+
updatedAt: z.string().datetime().nullable()
|
|
44
49
|
});
|
|
45
50
|
const sidebarPreferencesUpdateResponseSchema = sidebarPreferencesResponseSchema.extend({
|
|
46
51
|
appliedRoles: z.array(z.string().uuid()),
|
|
@@ -86,10 +91,11 @@ async function loadRolesPayload(em, options) {
|
|
|
86
91
|
}));
|
|
87
92
|
}
|
|
88
93
|
async function findRoleInScope(em, options) {
|
|
94
|
+
const roleScope = options.tenantId ? { id: options.roleId, $or: [{ tenantId: options.tenantId }, { tenantId: null }] } : { id: options.roleId, tenantId: null };
|
|
89
95
|
const role = await findOneWithDecryption(
|
|
90
96
|
em,
|
|
91
97
|
Role,
|
|
92
|
-
|
|
98
|
+
roleScope,
|
|
93
99
|
void 0,
|
|
94
100
|
{ tenantId: options.tenantId, organizationId: null }
|
|
95
101
|
);
|
|
@@ -127,6 +133,11 @@ async function GET(req) {
|
|
|
127
133
|
});
|
|
128
134
|
const pref = rolePrefs.get(role.id) ?? null;
|
|
129
135
|
const rolesPayload2 = await loadRolesPayload(em, { tenantId: auth.tenantId ?? null, locale });
|
|
136
|
+
const roleVersion = await loadRoleSidebarPreferenceUpdatedAt(em, {
|
|
137
|
+
roleId: role.id,
|
|
138
|
+
tenantId: auth.tenantId ?? null,
|
|
139
|
+
locale
|
|
140
|
+
});
|
|
130
141
|
return NextResponse.json({
|
|
131
142
|
locale,
|
|
132
143
|
settings: pref ? {
|
|
@@ -139,7 +150,8 @@ async function GET(req) {
|
|
|
139
150
|
} : emptySettings(),
|
|
140
151
|
canApplyToRoles,
|
|
141
152
|
roles: rolesPayload2,
|
|
142
|
-
scope: { type: "role", roleId: role.id }
|
|
153
|
+
scope: { type: "role", roleId: role.id },
|
|
154
|
+
updatedAt: roleVersion?.updatedAt ? roleVersion.updatedAt.toISOString() : null
|
|
143
155
|
});
|
|
144
156
|
}
|
|
145
157
|
const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub;
|
|
@@ -150,6 +162,12 @@ async function GET(req) {
|
|
|
150
162
|
locale
|
|
151
163
|
}) : null;
|
|
152
164
|
const rolesPayload = canApplyToRoles ? await loadRolesPayload(em, { tenantId: auth.tenantId ?? null, locale }) : [];
|
|
165
|
+
const userVersion = effectiveUserId ? await loadSidebarPreferenceUpdatedAt(em, {
|
|
166
|
+
userId: effectiveUserId,
|
|
167
|
+
tenantId: auth.tenantId ?? null,
|
|
168
|
+
organizationId: auth.orgId ?? null,
|
|
169
|
+
locale
|
|
170
|
+
}) : null;
|
|
153
171
|
return NextResponse.json({
|
|
154
172
|
locale,
|
|
155
173
|
settings: {
|
|
@@ -162,7 +180,8 @@ async function GET(req) {
|
|
|
162
180
|
},
|
|
163
181
|
canApplyToRoles,
|
|
164
182
|
roles: rolesPayload,
|
|
165
|
-
scope: { type: "user" }
|
|
183
|
+
scope: { type: "user" },
|
|
184
|
+
updatedAt: userVersion?.updatedAt ? userVersion.updatedAt.toISOString() : null
|
|
166
185
|
});
|
|
167
186
|
}
|
|
168
187
|
async function PUT(req) {
|
|
@@ -257,11 +276,34 @@ async function PUT(req) {
|
|
|
257
276
|
if (!role) {
|
|
258
277
|
return NextResponse.json({ error: "Role not found" }, { status: 404 });
|
|
259
278
|
}
|
|
279
|
+
const existingRolePref = await loadRoleSidebarPreferenceUpdatedAt(em, {
|
|
280
|
+
roleId: role.id,
|
|
281
|
+
tenantId: auth.tenantId ?? null,
|
|
282
|
+
locale
|
|
283
|
+
});
|
|
284
|
+
if (existingRolePref) {
|
|
285
|
+
try {
|
|
286
|
+
enforceCommandOptimisticLock({
|
|
287
|
+
resourceKind: "auth.role_sidebar_preference",
|
|
288
|
+
resourceId: existingRolePref.id,
|
|
289
|
+
current: existingRolePref.updatedAt ?? null,
|
|
290
|
+
request: req
|
|
291
|
+
});
|
|
292
|
+
} catch (err) {
|
|
293
|
+
if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status });
|
|
294
|
+
throw err;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
260
297
|
const saved = await saveRoleSidebarPreference(em, {
|
|
261
298
|
roleId: role.id,
|
|
262
299
|
tenantId: auth.tenantId ?? null,
|
|
263
300
|
locale
|
|
264
301
|
}, payload);
|
|
302
|
+
const savedRoleVersion = await loadRoleSidebarPreferenceUpdatedAt(em, {
|
|
303
|
+
roleId: role.id,
|
|
304
|
+
tenantId: auth.tenantId ?? null,
|
|
305
|
+
locale
|
|
306
|
+
});
|
|
265
307
|
if (cache?.deleteByTags) {
|
|
266
308
|
try {
|
|
267
309
|
await cache.deleteByTags([`nav:sidebar:role:${role.id}`]);
|
|
@@ -282,6 +324,7 @@ async function PUT(req) {
|
|
|
282
324
|
canApplyToRoles,
|
|
283
325
|
roles: rolesPayload2,
|
|
284
326
|
scope: { type: "role", roleId: role.id },
|
|
327
|
+
updatedAt: savedRoleVersion?.updatedAt ? savedRoleVersion.updatedAt.toISOString() : null,
|
|
285
328
|
appliedRoles: [],
|
|
286
329
|
clearedRoles: []
|
|
287
330
|
});
|
|
@@ -293,6 +336,25 @@ async function PUT(req) {
|
|
|
293
336
|
if ((applyToRoles.length > 0 || clearRoleIds.length > 0) && !canApplyToRoles) {
|
|
294
337
|
return NextResponse.json({ error: "Forbidden", requiredFeatures: [FEATURE_MANAGE] }, { status: 403 });
|
|
295
338
|
}
|
|
339
|
+
const existingUserPref = await loadSidebarPreferenceUpdatedAt(em, {
|
|
340
|
+
userId: effectiveUserId,
|
|
341
|
+
tenantId: auth.tenantId ?? null,
|
|
342
|
+
organizationId: auth.orgId ?? null,
|
|
343
|
+
locale
|
|
344
|
+
});
|
|
345
|
+
if (existingUserPref) {
|
|
346
|
+
try {
|
|
347
|
+
enforceCommandOptimisticLock({
|
|
348
|
+
resourceKind: "auth.sidebar_preference",
|
|
349
|
+
resourceId: existingUserPref.id,
|
|
350
|
+
current: existingUserPref.updatedAt ?? null,
|
|
351
|
+
request: req
|
|
352
|
+
});
|
|
353
|
+
} catch (err) {
|
|
354
|
+
if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status });
|
|
355
|
+
throw err;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
296
358
|
const settings = await saveSidebarPreference(em, {
|
|
297
359
|
userId: effectiveUserId,
|
|
298
360
|
tenantId: auth.tenantId ?? null,
|
|
@@ -367,12 +429,19 @@ async function PUT(req) {
|
|
|
367
429
|
hasPreference: rolePrefs.has(role.id)
|
|
368
430
|
}));
|
|
369
431
|
}
|
|
432
|
+
const savedUserVersion = await loadSidebarPreferenceUpdatedAt(em, {
|
|
433
|
+
userId: effectiveUserId,
|
|
434
|
+
tenantId: auth.tenantId ?? null,
|
|
435
|
+
organizationId: auth.orgId ?? null,
|
|
436
|
+
locale
|
|
437
|
+
});
|
|
370
438
|
return NextResponse.json({
|
|
371
439
|
locale,
|
|
372
440
|
settings,
|
|
373
441
|
canApplyToRoles,
|
|
374
442
|
roles: rolesPayload,
|
|
375
443
|
scope: { type: "user" },
|
|
444
|
+
updatedAt: savedUserVersion?.updatedAt ? savedUserVersion.updatedAt.toISOString() : null,
|
|
376
445
|
appliedRoles: updatedRoleIds,
|
|
377
446
|
clearedRoles: filteredClearRoleIds
|
|
378
447
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/modules/auth/api/sidebar/preferences/route.ts"],
|
|
4
|
-
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport {\n sidebarPreferencesInputSchema,\n sidebarPreferencesScopeSchema,\n} from '../../../data/validators'\nimport {\n loadRoleSidebarPreferences,\n loadSidebarPreference,\n saveRoleSidebarPreference,\n saveSidebarPreference,\n} from '../../../services/sidebarPreferencesService'\nimport { SIDEBAR_PREFERENCES_VERSION } from '@open-mercato/shared/modules/navigation/sidebarPreferences'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport { Role, RoleSidebarPreference } from '../../../data/entities'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { z } from 'zod'\n\nexport const metadata = {\n GET: { requireAuth: true },\n PUT: { requireAuth: true, requireFeatures: ['auth.sidebar.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['auth.sidebar.manage'] },\n}\n\nconst sidebarSettingsSchema = z.object({\n version: z.number().int().positive(),\n groupOrder: z.array(z.string()),\n groupLabels: z.record(z.string(), z.string()),\n itemLabels: z.record(z.string(), z.string()),\n hiddenItems: z.array(z.string()),\n itemOrder: z.record(z.string(), z.array(z.string())),\n})\n\nconst sidebarRoleEntrySchema = z.object({\n id: z.string().uuid(),\n name: z.string(),\n hasPreference: z.boolean(),\n})\n\nconst sidebarPreferencesResponseSchema = z.object({\n locale: z.string(),\n settings: sidebarSettingsSchema,\n canApplyToRoles: z.boolean(),\n roles: z.array(sidebarRoleEntrySchema),\n scope: sidebarPreferencesScopeSchema,\n})\n\nconst sidebarPreferencesUpdateResponseSchema = sidebarPreferencesResponseSchema.extend({\n appliedRoles: z.array(z.string().uuid()),\n clearedRoles: z.array(z.string().uuid()),\n})\n\nconst sidebarPreferencesDeleteResponseSchema = z.object({\n ok: z.literal(true),\n scope: sidebarPreferencesScopeSchema,\n})\n\nconst sidebarErrorSchema = z.object({\n error: z.string(),\n})\n\nconst FEATURE_MANAGE = 'auth.sidebar.manage'\n\ntype EmptySettings = {\n version: number\n groupOrder: string[]\n groupLabels: Record<string, string>\n itemLabels: Record<string, string>\n hiddenItems: string[]\n itemOrder: Record<string, string[]>\n}\n\nfunction emptySettings(): EmptySettings {\n return {\n version: SIDEBAR_PREFERENCES_VERSION,\n groupOrder: [],\n groupLabels: {},\n itemLabels: {},\n hiddenItems: [],\n itemOrder: {},\n }\n}\n\nasync function loadRolesPayload(\n em: EntityManager,\n options: { tenantId: string | null; locale: string },\n): Promise<Array<{ id: string; name: string; hasPreference: boolean }>> {\n const roleScope: FilterQuery<Role> = options.tenantId\n ? { $or: [{ tenantId: options.tenantId }, { tenantId: null }] }\n : { tenantId: null }\n const roles = await findWithDecryption(\n em,\n Role,\n roleScope,\n { orderBy: { name: 'asc' } },\n { tenantId: options.tenantId, organizationId: null },\n )\n if (roles.length === 0) return []\n const rolePrefs = await loadRoleSidebarPreferences(em, {\n roleIds: roles.map((r: Role) => r.id),\n tenantId: options.tenantId,\n locale: options.locale,\n })\n return roles.map((role: Role) => ({\n id: role.id,\n name: role.name,\n hasPreference: rolePrefs.has(role.id),\n }))\n}\n\nasync function findRoleInScope(\n em: EntityManager,\n options: { roleId: string; tenantId: string | null },\n): Promise<Role | null> {\n const role = await findOneWithDecryption(\n em,\n Role,\n { id: options.roleId },\n undefined,\n { tenantId: options.tenantId, organizationId: null },\n )\n if (!role) return null\n // Cross-tenant guard: a role belongs to either the auth tenant or the global (null tenant) pool.\n // Reject the lookup otherwise so a multi-tenant deployment can't leak across tenants.\n if (role.tenantId && options.tenantId && role.tenantId !== options.tenantId) return null\n if (role.tenantId && !options.tenantId) return null\n return role\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n\n const url = new URL(req.url)\n const roleIdParam = url.searchParams.get('roleId')\n\n const { locale } = await resolveTranslations()\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as EntityManager\n const rbac = resolve('rbacService') as any\n\n const canApplyToRoles = await rbac.userHasAllFeatures?.(\n auth.sub,\n [FEATURE_MANAGE],\n { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null },\n ) ?? false\n\n // Role-scoped read: requires `auth.sidebar.manage`.\n if (roleIdParam) {\n if (!canApplyToRoles) {\n return NextResponse.json({ error: 'Forbidden', requiredFeatures: [FEATURE_MANAGE] }, { status: 403 })\n }\n const role = await findRoleInScope(em, { roleId: roleIdParam, tenantId: auth.tenantId ?? null })\n if (!role) {\n return NextResponse.json({ error: 'Role not found' }, { status: 404 })\n }\n const rolePrefs = await loadRoleSidebarPreferences(em, {\n roleIds: [role.id],\n tenantId: auth.tenantId ?? null,\n locale,\n })\n const pref = rolePrefs.get(role.id) ?? null\n const rolesPayload = await loadRolesPayload(em, { tenantId: auth.tenantId ?? null, locale })\n return NextResponse.json({\n locale,\n settings: pref\n ? {\n version: pref.version ?? SIDEBAR_PREFERENCES_VERSION,\n groupOrder: pref.groupOrder ?? [],\n groupLabels: pref.groupLabels ?? {},\n itemLabels: pref.itemLabels ?? {},\n hiddenItems: pref.hiddenItems ?? [],\n itemOrder: pref.itemOrder ?? {},\n }\n : emptySettings(),\n canApplyToRoles,\n roles: rolesPayload,\n scope: { type: 'role', roleId: role.id },\n })\n }\n\n // For API key auth, use userId (the actual user) if available\n const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub\n const settings = effectiveUserId\n ? await loadSidebarPreference(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n })\n : null\n\n const rolesPayload = canApplyToRoles\n ? await loadRolesPayload(em, { tenantId: auth.tenantId ?? null, locale })\n : []\n\n return NextResponse.json({\n locale,\n settings: {\n version: settings?.version ?? SIDEBAR_PREFERENCES_VERSION,\n groupOrder: settings?.groupOrder ?? [],\n groupLabels: settings?.groupLabels ?? {},\n itemLabels: settings?.itemLabels ?? {},\n hiddenItems: settings?.hiddenItems ?? [],\n itemOrder: settings?.itemOrder ?? {},\n },\n canApplyToRoles,\n roles: rolesPayload,\n scope: { type: 'user' },\n })\n}\n\nexport async function PUT(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n // For API key auth, use userId (the actual user) if available\n const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub\n if (!effectiveUserId) {\n return NextResponse.json({ error: 'Cannot save preferences: no user associated with this API key' }, { status: 403 })\n }\n\n let parsedBody: unknown\n try {\n parsedBody = await req.json()\n } catch {\n return NextResponse.json({ error: 'Invalid JSON' }, { status: 400 })\n }\n\n const parsed = sidebarPreferencesInputSchema.safeParse(parsedBody)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 400 })\n }\n\n const sanitizeRecord = (record?: Record<string, string>) => {\n if (!record) return {}\n const result: Record<string, string> = {}\n for (const [key, value] of Object.entries(record)) {\n const trimmedKey = key.trim()\n const trimmedValue = value.trim()\n if (!trimmedKey || !trimmedValue) continue\n result[trimmedKey] = trimmedValue\n }\n return result\n }\n\n const groupOrderSource = parsed.data.groupOrder ?? []\n const seen = new Set<string>()\n const groupOrder: string[] = []\n for (const id of groupOrderSource) {\n const trimmed = id.trim()\n if (!trimmed || seen.has(trimmed)) continue\n seen.add(trimmed)\n groupOrder.push(trimmed)\n }\n\n const payload = {\n version: parsed.data.version ?? SIDEBAR_PREFERENCES_VERSION,\n groupOrder,\n groupLabels: sanitizeRecord(parsed.data.groupLabels),\n itemLabels: sanitizeRecord(parsed.data.itemLabels),\n hiddenItems: (() => {\n const source = parsed.data.hiddenItems ?? []\n const seenHidden = new Set<string>()\n const values: string[] = []\n for (const href of source) {\n const trimmed = href.trim()\n if (!trimmed || seenHidden.has(trimmed)) continue\n seenHidden.add(trimmed)\n values.push(trimmed)\n }\n return values\n })(),\n itemOrder: (() => {\n const source = parsed.data.itemOrder ?? {}\n const out: Record<string, string[]> = {}\n for (const [groupKey, list] of Object.entries(source)) {\n const trimmedGroup = groupKey.trim()\n if (!trimmedGroup) continue\n const seenItem = new Set<string>()\n const values: string[] = []\n for (const itemKey of list) {\n const trimmedItem = itemKey.trim()\n if (!trimmedItem || seenItem.has(trimmedItem)) continue\n seenItem.add(trimmedItem)\n values.push(trimmedItem)\n }\n if (values.length > 0) out[trimmedGroup] = values\n }\n return out\n })(),\n }\n\n const { locale } = await resolveTranslations()\n const container = await createRequestContainer()\n const em = container.resolve('em') as EntityManager\n const rbac = container.resolve('rbacService') as any\n const cache = container.resolve('cache') as { deleteByTags?: (tags: string[]) => Promise<unknown> } | undefined\n\n const canApplyToRoles = await rbac.userHasAllFeatures?.(\n auth.sub,\n [FEATURE_MANAGE],\n { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null },\n ) ?? false\n\n const scope = parsed.data.scope ?? { type: 'user' as const }\n\n // Role-scoped write: requires `auth.sidebar.manage` and a role visible to this tenant.\n // applyToRoles/clearRoleIds are forbidden in role scope (validator already rejects them).\n if (scope.type === 'role') {\n if (!canApplyToRoles) {\n return NextResponse.json({ error: 'Forbidden', requiredFeatures: [FEATURE_MANAGE] }, { status: 403 })\n }\n const role = await findRoleInScope(em, { roleId: scope.roleId, tenantId: auth.tenantId ?? null })\n if (!role) {\n return NextResponse.json({ error: 'Role not found' }, { status: 404 })\n }\n const saved = await saveRoleSidebarPreference(em, {\n roleId: role.id,\n tenantId: auth.tenantId ?? null,\n locale,\n }, payload)\n if (cache?.deleteByTags) {\n try {\n await cache.deleteByTags([`nav:sidebar:role:${role.id}`])\n } catch {}\n }\n const rolesPayload = await loadRolesPayload(em, { tenantId: auth.tenantId ?? null, locale })\n return NextResponse.json({\n locale,\n settings: {\n version: saved?.version ?? payload.version,\n groupOrder: saved?.groupOrder ?? payload.groupOrder,\n groupLabels: saved?.groupLabels ?? payload.groupLabels,\n itemLabels: saved?.itemLabels ?? payload.itemLabels,\n hiddenItems: saved?.hiddenItems ?? payload.hiddenItems,\n itemOrder: saved?.itemOrder ?? payload.itemOrder,\n },\n canApplyToRoles,\n roles: rolesPayload,\n scope: { type: 'role', roleId: role.id },\n appliedRoles: [],\n clearedRoles: [],\n })\n }\n\n const applyToRolesSource = parsed.data.applyToRoles ?? []\n const applyToRoles = Array.from(new Set(applyToRolesSource.map((id) => id.trim()).filter((id) => id.length > 0)))\n const clearRoleIdsSource = parsed.data.clearRoleIds ?? []\n const clearRoleIds = Array.from(new Set(clearRoleIdsSource.map((id) => id.trim()).filter((id) => id.length > 0)))\n\n if ((applyToRoles.length > 0 || clearRoleIds.length > 0) && !canApplyToRoles) {\n return NextResponse.json({ error: 'Forbidden', requiredFeatures: [FEATURE_MANAGE] }, { status: 403 })\n }\n\n const settings = await saveSidebarPreference(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n }, payload)\n\n const roleScope: FilterQuery<Role> = auth.tenantId\n ? { $or: [{ tenantId: auth.tenantId }, { tenantId: null }] }\n : { tenantId: null }\n const availableRoles = canApplyToRoles\n ? await findWithDecryption(\n em,\n Role,\n roleScope,\n { orderBy: { name: 'asc' } },\n { tenantId: auth.tenantId ?? null, organizationId: null },\n )\n : []\n const roleMap = new Map<string, Role>(availableRoles.map((role: Role) => [String(role.id), role]))\n\n if (applyToRoles.length > 0) {\n const missing = applyToRoles.filter((id) => !roleMap.has(id))\n if (missing.length) {\n return NextResponse.json({ error: 'Invalid roles', missing }, { status: 400 })\n }\n }\n\n const updatedRoleIds: string[] = []\n const filteredClearRoleIds: string[] = []\n await withAtomicFlush(em, [\n async () => {\n for (const roleId of applyToRoles) {\n const role = roleMap.get(roleId)!\n await saveRoleSidebarPreference(em, {\n roleId: role.id,\n tenantId: auth.tenantId ?? null,\n locale,\n }, payload)\n updatedRoleIds.push(role.id)\n }\n\n const clearTargets = clearRoleIds.filter((id) => !updatedRoleIds.includes(id) && !applyToRoles.includes(id))\n filteredClearRoleIds.push(...clearTargets)\n\n if (filteredClearRoleIds.length > 0) {\n // Cross-locale: role preferences are unique per (role, tenantId); keep the delete\n // filter aligned with save/load helpers so a clear from one locale does not leave\n // a row created under another locale orphaned.\n await em.nativeDelete(RoleSidebarPreference, {\n role: { $in: filteredClearRoleIds },\n tenantId: auth.tenantId ?? null,\n })\n }\n },\n ], { transaction: true })\n\n if (filteredClearRoleIds.length > 0 && cache?.deleteByTags) {\n try {\n await cache.deleteByTags(filteredClearRoleIds.map((roleId) => `nav:sidebar:role:${roleId}`))\n } catch {}\n }\n\n if (cache?.deleteByTags) {\n const tags = [\n `nav:sidebar:user:${auth.sub}`,\n `nav:sidebar:scope:${auth.sub}:${auth.tenantId ?? 'null'}:${auth.orgId ?? 'null'}:${locale}`,\n ...updatedRoleIds.map((roleId) => `nav:sidebar:role:${roleId}`),\n ]\n try {\n await cache.deleteByTags(tags)\n } catch {}\n }\n\n let rolesPayload: Array<{ id: string; name: string; hasPreference: boolean }> = []\n if (canApplyToRoles) {\n const rolePrefs = await loadRoleSidebarPreferences(em, {\n roleIds: availableRoles.map((role: Role) => role.id),\n tenantId: auth.tenantId ?? null,\n locale,\n })\n rolesPayload = availableRoles.map((role: Role) => ({\n id: role.id,\n name: role.name,\n hasPreference: rolePrefs.has(role.id),\n }))\n }\n\n return NextResponse.json({\n locale,\n settings,\n canApplyToRoles,\n roles: rolesPayload,\n scope: { type: 'user' },\n appliedRoles: updatedRoleIds,\n clearedRoles: filteredClearRoleIds,\n })\n}\n\nexport async function DELETE(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n\n const url = new URL(req.url)\n const roleIdParam = url.searchParams.get('roleId')\n if (!roleIdParam) {\n return NextResponse.json({ error: 'roleId query parameter is required' }, { status: 400 })\n }\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as EntityManager\n const rbac = container.resolve('rbacService') as any\n const cache = container.resolve('cache') as { deleteByTags?: (tags: string[]) => Promise<unknown> } | undefined\n\n const canApplyToRoles = await rbac.userHasAllFeatures?.(\n auth.sub,\n [FEATURE_MANAGE],\n { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null },\n ) ?? false\n if (!canApplyToRoles) {\n return NextResponse.json({ error: 'Forbidden', requiredFeatures: [FEATURE_MANAGE] }, { status: 403 })\n }\n\n const role = await findRoleInScope(em, { roleId: roleIdParam, tenantId: auth.tenantId ?? null })\n if (!role) {\n return NextResponse.json({ error: 'Role not found' }, { status: 404 })\n }\n\n // Cross-locale: keep the delete filter aligned with save/load helpers (no locale).\n await em.nativeDelete(RoleSidebarPreference, {\n role: role.id,\n tenantId: auth.tenantId ?? null,\n })\n\n if (cache?.deleteByTags) {\n try {\n await cache.deleteByTags([`nav:sidebar:role:${role.id}`])\n } catch {}\n }\n\n return NextResponse.json({ ok: true, scope: { type: 'role', roleId: role.id } })\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Authentication & Accounts',\n summary: 'Sidebar preferences',\n methods: {\n GET: {\n summary: 'Get sidebar preferences',\n description: 'Returns sidebar customization for the current user (default) or the specified role (`?roleId=\u2026`, requires `auth.sidebar.manage`).',\n responses: [\n { status: 200, description: 'Current sidebar configuration', schema: sidebarPreferencesResponseSchema },\n { status: 401, description: 'Unauthorized', schema: sidebarErrorSchema },\n { status: 403, description: 'Missing features for role-scope read', schema: sidebarErrorSchema },\n { status: 404, description: 'Role not found in current tenant scope', schema: sidebarErrorSchema },\n ],\n },\n PUT: {\n summary: 'Update sidebar preferences',\n description: 'Updates sidebar configuration. With `scope.type === \"user\"` (default) writes the calling user\\'s personal preferences and may optionally apply the same settings to selected roles via `applyToRoles[]`. With `scope.type === \"role\"` writes the named role variant directly (requires `auth.sidebar.manage`); `applyToRoles[]` and `clearRoleIds[]` are rejected in this mode.',\n requestBody: {\n contentType: 'application/json',\n schema: sidebarPreferencesInputSchema,\n },\n responses: [\n { status: 200, description: 'Preferences saved', schema: sidebarPreferencesUpdateResponseSchema },\n { status: 400, description: 'Invalid payload', schema: sidebarErrorSchema },\n { status: 401, description: 'Unauthorized', schema: sidebarErrorSchema },\n { status: 403, description: 'Missing features for role-wide updates', schema: sidebarErrorSchema },\n { status: 404, description: 'Role not found in current tenant scope', schema: sidebarErrorSchema },\n ],\n },\n DELETE: {\n summary: 'Delete a role sidebar variant',\n description: 'Removes the role variant for the current tenant + locale. Idempotent. Requires `auth.sidebar.manage`.',\n responses: [\n { status: 200, description: 'Variant deleted (or never existed)', schema: sidebarPreferencesDeleteResponseSchema },\n { status: 400, description: 'Missing roleId query parameter', schema: sidebarErrorSchema },\n { status: 401, description: 'Unauthorized', schema: sidebarErrorSchema },\n { status: 403, description: 'Missing features', schema: sidebarErrorSchema },\n { status: 404, description: 'Role not found in current tenant scope', schema: sidebarErrorSchema },\n ],\n },\n },\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport {\n sidebarPreferencesInputSchema,\n sidebarPreferencesScopeSchema,\n} from '../../../data/validators'\nimport {\n loadRoleSidebarPreferenceUpdatedAt,\n loadRoleSidebarPreferences,\n loadSidebarPreference,\n loadSidebarPreferenceUpdatedAt,\n saveRoleSidebarPreference,\n saveSidebarPreference,\n} from '../../../services/sidebarPreferencesService'\nimport { SIDEBAR_PREFERENCES_VERSION } from '@open-mercato/shared/modules/navigation/sidebarPreferences'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport { enforceCommandOptimisticLock } from '@open-mercato/shared/lib/crud/optimistic-lock-command'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { Role, RoleSidebarPreference } from '../../../data/entities'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { z } from 'zod'\n\nexport const metadata = {\n GET: { requireAuth: true },\n PUT: { requireAuth: true, requireFeatures: ['auth.sidebar.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['auth.sidebar.manage'] },\n}\n\nconst sidebarSettingsSchema = z.object({\n version: z.number().int().positive(),\n groupOrder: z.array(z.string()),\n groupLabels: z.record(z.string(), z.string()),\n itemLabels: z.record(z.string(), z.string()),\n hiddenItems: z.array(z.string()),\n itemOrder: z.record(z.string(), z.array(z.string())),\n})\n\nconst sidebarRoleEntrySchema = z.object({\n id: z.string().uuid(),\n name: z.string(),\n hasPreference: z.boolean(),\n})\n\nconst sidebarPreferencesResponseSchema = z.object({\n locale: z.string(),\n settings: sidebarSettingsSchema,\n canApplyToRoles: z.boolean(),\n roles: z.array(sidebarRoleEntrySchema),\n scope: sidebarPreferencesScopeSchema,\n updatedAt: z.string().datetime().nullable(),\n})\n\nconst sidebarPreferencesUpdateResponseSchema = sidebarPreferencesResponseSchema.extend({\n appliedRoles: z.array(z.string().uuid()),\n clearedRoles: z.array(z.string().uuid()),\n})\n\nconst sidebarPreferencesDeleteResponseSchema = z.object({\n ok: z.literal(true),\n scope: sidebarPreferencesScopeSchema,\n})\n\nconst sidebarErrorSchema = z.object({\n error: z.string(),\n})\n\nconst FEATURE_MANAGE = 'auth.sidebar.manage'\n\ntype EmptySettings = {\n version: number\n groupOrder: string[]\n groupLabels: Record<string, string>\n itemLabels: Record<string, string>\n hiddenItems: string[]\n itemOrder: Record<string, string[]>\n}\n\nfunction emptySettings(): EmptySettings {\n return {\n version: SIDEBAR_PREFERENCES_VERSION,\n groupOrder: [],\n groupLabels: {},\n itemLabels: {},\n hiddenItems: [],\n itemOrder: {},\n }\n}\n\nasync function loadRolesPayload(\n em: EntityManager,\n options: { tenantId: string | null; locale: string },\n): Promise<Array<{ id: string; name: string; hasPreference: boolean }>> {\n const roleScope: FilterQuery<Role> = options.tenantId\n ? { $or: [{ tenantId: options.tenantId }, { tenantId: null }] }\n : { tenantId: null }\n const roles = await findWithDecryption(\n em,\n Role,\n roleScope,\n { orderBy: { name: 'asc' } },\n { tenantId: options.tenantId, organizationId: null },\n )\n if (roles.length === 0) return []\n const rolePrefs = await loadRoleSidebarPreferences(em, {\n roleIds: roles.map((r: Role) => r.id),\n tenantId: options.tenantId,\n locale: options.locale,\n })\n return roles.map((role: Role) => ({\n id: role.id,\n name: role.name,\n hasPreference: rolePrefs.has(role.id),\n }))\n}\n\nasync function findRoleInScope(\n em: EntityManager,\n options: { roleId: string; tenantId: string | null },\n): Promise<Role | null> {\n // Scope the DB query so MikroORM only fetches in-scope rows: a role belongs to either\n // the auth tenant or the global (null tenant) pool. Mirrors loadRolesPayload()'s scoping\n // so cross-tenant role rows are never loaded or decrypted into memory in the first place.\n const roleScope: FilterQuery<Role> = options.tenantId\n ? { id: options.roleId, $or: [{ tenantId: options.tenantId }, { tenantId: null }] }\n : { id: options.roleId, tenantId: null }\n const role = await findOneWithDecryption(\n em,\n Role,\n roleScope,\n undefined,\n { tenantId: options.tenantId, organizationId: null },\n )\n if (!role) return null\n // Cross-tenant guard (defense-in-depth): a role belongs to either the auth tenant or the\n // global (null tenant) pool. Reject the lookup otherwise so a multi-tenant deployment can't\n // leak across tenants even if the query above is later changed.\n if (role.tenantId && options.tenantId && role.tenantId !== options.tenantId) return null\n if (role.tenantId && !options.tenantId) return null\n return role\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n\n const url = new URL(req.url)\n const roleIdParam = url.searchParams.get('roleId')\n\n const { locale } = await resolveTranslations()\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as EntityManager\n const rbac = resolve('rbacService') as any\n\n const canApplyToRoles = await rbac.userHasAllFeatures?.(\n auth.sub,\n [FEATURE_MANAGE],\n { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null },\n ) ?? false\n\n // Role-scoped read: requires `auth.sidebar.manage`.\n if (roleIdParam) {\n if (!canApplyToRoles) {\n return NextResponse.json({ error: 'Forbidden', requiredFeatures: [FEATURE_MANAGE] }, { status: 403 })\n }\n const role = await findRoleInScope(em, { roleId: roleIdParam, tenantId: auth.tenantId ?? null })\n if (!role) {\n return NextResponse.json({ error: 'Role not found' }, { status: 404 })\n }\n const rolePrefs = await loadRoleSidebarPreferences(em, {\n roleIds: [role.id],\n tenantId: auth.tenantId ?? null,\n locale,\n })\n const pref = rolePrefs.get(role.id) ?? null\n const rolesPayload = await loadRolesPayload(em, { tenantId: auth.tenantId ?? null, locale })\n const roleVersion = await loadRoleSidebarPreferenceUpdatedAt(em, {\n roleId: role.id,\n tenantId: auth.tenantId ?? null,\n locale,\n })\n return NextResponse.json({\n locale,\n settings: pref\n ? {\n version: pref.version ?? SIDEBAR_PREFERENCES_VERSION,\n groupOrder: pref.groupOrder ?? [],\n groupLabels: pref.groupLabels ?? {},\n itemLabels: pref.itemLabels ?? {},\n hiddenItems: pref.hiddenItems ?? [],\n itemOrder: pref.itemOrder ?? {},\n }\n : emptySettings(),\n canApplyToRoles,\n roles: rolesPayload,\n scope: { type: 'role', roleId: role.id },\n updatedAt: roleVersion?.updatedAt ? roleVersion.updatedAt.toISOString() : null,\n })\n }\n\n // For API key auth, use userId (the actual user) if available\n const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub\n const settings = effectiveUserId\n ? await loadSidebarPreference(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n })\n : null\n\n const rolesPayload = canApplyToRoles\n ? await loadRolesPayload(em, { tenantId: auth.tenantId ?? null, locale })\n : []\n\n const userVersion = effectiveUserId\n ? await loadSidebarPreferenceUpdatedAt(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n })\n : null\n\n return NextResponse.json({\n locale,\n settings: {\n version: settings?.version ?? SIDEBAR_PREFERENCES_VERSION,\n groupOrder: settings?.groupOrder ?? [],\n groupLabels: settings?.groupLabels ?? {},\n itemLabels: settings?.itemLabels ?? {},\n hiddenItems: settings?.hiddenItems ?? [],\n itemOrder: settings?.itemOrder ?? {},\n },\n canApplyToRoles,\n roles: rolesPayload,\n scope: { type: 'user' },\n updatedAt: userVersion?.updatedAt ? userVersion.updatedAt.toISOString() : null,\n })\n}\n\nexport async function PUT(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n // For API key auth, use userId (the actual user) if available\n const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub\n if (!effectiveUserId) {\n return NextResponse.json({ error: 'Cannot save preferences: no user associated with this API key' }, { status: 403 })\n }\n\n let parsedBody: unknown\n try {\n parsedBody = await req.json()\n } catch {\n return NextResponse.json({ error: 'Invalid JSON' }, { status: 400 })\n }\n\n const parsed = sidebarPreferencesInputSchema.safeParse(parsedBody)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 400 })\n }\n\n const sanitizeRecord = (record?: Record<string, string>) => {\n if (!record) return {}\n const result: Record<string, string> = {}\n for (const [key, value] of Object.entries(record)) {\n const trimmedKey = key.trim()\n const trimmedValue = value.trim()\n if (!trimmedKey || !trimmedValue) continue\n result[trimmedKey] = trimmedValue\n }\n return result\n }\n\n const groupOrderSource = parsed.data.groupOrder ?? []\n const seen = new Set<string>()\n const groupOrder: string[] = []\n for (const id of groupOrderSource) {\n const trimmed = id.trim()\n if (!trimmed || seen.has(trimmed)) continue\n seen.add(trimmed)\n groupOrder.push(trimmed)\n }\n\n const payload = {\n version: parsed.data.version ?? SIDEBAR_PREFERENCES_VERSION,\n groupOrder,\n groupLabels: sanitizeRecord(parsed.data.groupLabels),\n itemLabels: sanitizeRecord(parsed.data.itemLabels),\n hiddenItems: (() => {\n const source = parsed.data.hiddenItems ?? []\n const seenHidden = new Set<string>()\n const values: string[] = []\n for (const href of source) {\n const trimmed = href.trim()\n if (!trimmed || seenHidden.has(trimmed)) continue\n seenHidden.add(trimmed)\n values.push(trimmed)\n }\n return values\n })(),\n itemOrder: (() => {\n const source = parsed.data.itemOrder ?? {}\n const out: Record<string, string[]> = {}\n for (const [groupKey, list] of Object.entries(source)) {\n const trimmedGroup = groupKey.trim()\n if (!trimmedGroup) continue\n const seenItem = new Set<string>()\n const values: string[] = []\n for (const itemKey of list) {\n const trimmedItem = itemKey.trim()\n if (!trimmedItem || seenItem.has(trimmedItem)) continue\n seenItem.add(trimmedItem)\n values.push(trimmedItem)\n }\n if (values.length > 0) out[trimmedGroup] = values\n }\n return out\n })(),\n }\n\n const { locale } = await resolveTranslations()\n const container = await createRequestContainer()\n const em = container.resolve('em') as EntityManager\n const rbac = container.resolve('rbacService') as any\n const cache = container.resolve('cache') as { deleteByTags?: (tags: string[]) => Promise<unknown> } | undefined\n\n const canApplyToRoles = await rbac.userHasAllFeatures?.(\n auth.sub,\n [FEATURE_MANAGE],\n { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null },\n ) ?? false\n\n const scope = parsed.data.scope ?? { type: 'user' as const }\n\n // Role-scoped write: requires `auth.sidebar.manage` and a role visible to this tenant.\n // applyToRoles/clearRoleIds are forbidden in role scope (validator already rejects them).\n if (scope.type === 'role') {\n if (!canApplyToRoles) {\n return NextResponse.json({ error: 'Forbidden', requiredFeatures: [FEATURE_MANAGE] }, { status: 403 })\n }\n const role = await findRoleInScope(em, { roleId: scope.roleId, tenantId: auth.tenantId ?? null })\n if (!role) {\n return NextResponse.json({ error: 'Role not found' }, { status: 404 })\n }\n const existingRolePref = await loadRoleSidebarPreferenceUpdatedAt(em, {\n roleId: role.id,\n tenantId: auth.tenantId ?? null,\n locale,\n })\n if (existingRolePref) {\n try {\n enforceCommandOptimisticLock({\n resourceKind: 'auth.role_sidebar_preference',\n resourceId: existingRolePref.id,\n current: existingRolePref.updatedAt ?? null,\n request: req,\n })\n } catch (err) {\n if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })\n throw err\n }\n }\n const saved = await saveRoleSidebarPreference(em, {\n roleId: role.id,\n tenantId: auth.tenantId ?? null,\n locale,\n }, payload)\n const savedRoleVersion = await loadRoleSidebarPreferenceUpdatedAt(em, {\n roleId: role.id,\n tenantId: auth.tenantId ?? null,\n locale,\n })\n if (cache?.deleteByTags) {\n try {\n await cache.deleteByTags([`nav:sidebar:role:${role.id}`])\n } catch {}\n }\n const rolesPayload = await loadRolesPayload(em, { tenantId: auth.tenantId ?? null, locale })\n return NextResponse.json({\n locale,\n settings: {\n version: saved?.version ?? payload.version,\n groupOrder: saved?.groupOrder ?? payload.groupOrder,\n groupLabels: saved?.groupLabels ?? payload.groupLabels,\n itemLabels: saved?.itemLabels ?? payload.itemLabels,\n hiddenItems: saved?.hiddenItems ?? payload.hiddenItems,\n itemOrder: saved?.itemOrder ?? payload.itemOrder,\n },\n canApplyToRoles,\n roles: rolesPayload,\n scope: { type: 'role', roleId: role.id },\n updatedAt: savedRoleVersion?.updatedAt ? savedRoleVersion.updatedAt.toISOString() : null,\n appliedRoles: [],\n clearedRoles: [],\n })\n }\n\n const applyToRolesSource = parsed.data.applyToRoles ?? []\n const applyToRoles = Array.from(new Set(applyToRolesSource.map((id) => id.trim()).filter((id) => id.length > 0)))\n const clearRoleIdsSource = parsed.data.clearRoleIds ?? []\n const clearRoleIds = Array.from(new Set(clearRoleIdsSource.map((id) => id.trim()).filter((id) => id.length > 0)))\n\n if ((applyToRoles.length > 0 || clearRoleIds.length > 0) && !canApplyToRoles) {\n return NextResponse.json({ error: 'Forbidden', requiredFeatures: [FEATURE_MANAGE] }, { status: 403 })\n }\n\n const existingUserPref = await loadSidebarPreferenceUpdatedAt(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n })\n if (existingUserPref) {\n try {\n enforceCommandOptimisticLock({\n resourceKind: 'auth.sidebar_preference',\n resourceId: existingUserPref.id,\n current: existingUserPref.updatedAt ?? null,\n request: req,\n })\n } catch (err) {\n if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })\n throw err\n }\n }\n\n const settings = await saveSidebarPreference(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n }, payload)\n\n const roleScope: FilterQuery<Role> = auth.tenantId\n ? { $or: [{ tenantId: auth.tenantId }, { tenantId: null }] }\n : { tenantId: null }\n const availableRoles = canApplyToRoles\n ? await findWithDecryption(\n em,\n Role,\n roleScope,\n { orderBy: { name: 'asc' } },\n { tenantId: auth.tenantId ?? null, organizationId: null },\n )\n : []\n const roleMap = new Map<string, Role>(availableRoles.map((role: Role) => [String(role.id), role]))\n\n if (applyToRoles.length > 0) {\n const missing = applyToRoles.filter((id) => !roleMap.has(id))\n if (missing.length) {\n return NextResponse.json({ error: 'Invalid roles', missing }, { status: 400 })\n }\n }\n\n const updatedRoleIds: string[] = []\n const filteredClearRoleIds: string[] = []\n await withAtomicFlush(em, [\n async () => {\n for (const roleId of applyToRoles) {\n const role = roleMap.get(roleId)!\n await saveRoleSidebarPreference(em, {\n roleId: role.id,\n tenantId: auth.tenantId ?? null,\n locale,\n }, payload)\n updatedRoleIds.push(role.id)\n }\n\n const clearTargets = clearRoleIds.filter((id) => !updatedRoleIds.includes(id) && !applyToRoles.includes(id))\n filteredClearRoleIds.push(...clearTargets)\n\n if (filteredClearRoleIds.length > 0) {\n // Cross-locale: role preferences are unique per (role, tenantId); keep the delete\n // filter aligned with save/load helpers so a clear from one locale does not leave\n // a row created under another locale orphaned.\n await em.nativeDelete(RoleSidebarPreference, {\n role: { $in: filteredClearRoleIds },\n tenantId: auth.tenantId ?? null,\n })\n }\n },\n ], { transaction: true })\n\n if (filteredClearRoleIds.length > 0 && cache?.deleteByTags) {\n try {\n await cache.deleteByTags(filteredClearRoleIds.map((roleId) => `nav:sidebar:role:${roleId}`))\n } catch {}\n }\n\n if (cache?.deleteByTags) {\n const tags = [\n `nav:sidebar:user:${auth.sub}`,\n `nav:sidebar:scope:${auth.sub}:${auth.tenantId ?? 'null'}:${auth.orgId ?? 'null'}:${locale}`,\n ...updatedRoleIds.map((roleId) => `nav:sidebar:role:${roleId}`),\n ]\n try {\n await cache.deleteByTags(tags)\n } catch {}\n }\n\n let rolesPayload: Array<{ id: string; name: string; hasPreference: boolean }> = []\n if (canApplyToRoles) {\n const rolePrefs = await loadRoleSidebarPreferences(em, {\n roleIds: availableRoles.map((role: Role) => role.id),\n tenantId: auth.tenantId ?? null,\n locale,\n })\n rolesPayload = availableRoles.map((role: Role) => ({\n id: role.id,\n name: role.name,\n hasPreference: rolePrefs.has(role.id),\n }))\n }\n\n const savedUserVersion = await loadSidebarPreferenceUpdatedAt(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n })\n\n return NextResponse.json({\n locale,\n settings,\n canApplyToRoles,\n roles: rolesPayload,\n scope: { type: 'user' },\n updatedAt: savedUserVersion?.updatedAt ? savedUserVersion.updatedAt.toISOString() : null,\n appliedRoles: updatedRoleIds,\n clearedRoles: filteredClearRoleIds,\n })\n}\n\nexport async function DELETE(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n\n const url = new URL(req.url)\n const roleIdParam = url.searchParams.get('roleId')\n if (!roleIdParam) {\n return NextResponse.json({ error: 'roleId query parameter is required' }, { status: 400 })\n }\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as EntityManager\n const rbac = container.resolve('rbacService') as any\n const cache = container.resolve('cache') as { deleteByTags?: (tags: string[]) => Promise<unknown> } | undefined\n\n const canApplyToRoles = await rbac.userHasAllFeatures?.(\n auth.sub,\n [FEATURE_MANAGE],\n { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null },\n ) ?? false\n if (!canApplyToRoles) {\n return NextResponse.json({ error: 'Forbidden', requiredFeatures: [FEATURE_MANAGE] }, { status: 403 })\n }\n\n const role = await findRoleInScope(em, { roleId: roleIdParam, tenantId: auth.tenantId ?? null })\n if (!role) {\n return NextResponse.json({ error: 'Role not found' }, { status: 404 })\n }\n\n // Cross-locale: keep the delete filter aligned with save/load helpers (no locale).\n await em.nativeDelete(RoleSidebarPreference, {\n role: role.id,\n tenantId: auth.tenantId ?? null,\n })\n\n if (cache?.deleteByTags) {\n try {\n await cache.deleteByTags([`nav:sidebar:role:${role.id}`])\n } catch {}\n }\n\n return NextResponse.json({ ok: true, scope: { type: 'role', roleId: role.id } })\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Authentication & Accounts',\n summary: 'Sidebar preferences',\n methods: {\n GET: {\n summary: 'Get sidebar preferences',\n description: 'Returns sidebar customization for the current user (default) or the specified role (`?roleId=\u2026`, requires `auth.sidebar.manage`).',\n responses: [\n { status: 200, description: 'Current sidebar configuration', schema: sidebarPreferencesResponseSchema },\n { status: 401, description: 'Unauthorized', schema: sidebarErrorSchema },\n { status: 403, description: 'Missing features for role-scope read', schema: sidebarErrorSchema },\n { status: 404, description: 'Role not found in current tenant scope', schema: sidebarErrorSchema },\n ],\n },\n PUT: {\n summary: 'Update sidebar preferences',\n description: 'Updates sidebar configuration. With `scope.type === \"user\"` (default) writes the calling user\\'s personal preferences and may optionally apply the same settings to selected roles via `applyToRoles[]`. With `scope.type === \"role\"` writes the named role variant directly (requires `auth.sidebar.manage`); `applyToRoles[]` and `clearRoleIds[]` are rejected in this mode.',\n requestBody: {\n contentType: 'application/json',\n schema: sidebarPreferencesInputSchema,\n },\n responses: [\n { status: 200, description: 'Preferences saved', schema: sidebarPreferencesUpdateResponseSchema },\n { status: 400, description: 'Invalid payload', schema: sidebarErrorSchema },\n { status: 401, description: 'Unauthorized', schema: sidebarErrorSchema },\n { status: 403, description: 'Missing features for role-wide updates', schema: sidebarErrorSchema },\n { status: 404, description: 'Role not found in current tenant scope', schema: sidebarErrorSchema },\n ],\n },\n DELETE: {\n summary: 'Delete a role sidebar variant',\n description: 'Removes the role variant for the current tenant + locale. Idempotent. Requires `auth.sidebar.manage`.',\n responses: [\n { status: 200, description: 'Variant deleted (or never existed)', schema: sidebarPreferencesDeleteResponseSchema },\n { status: 400, description: 'Missing roleId query parameter', schema: sidebarErrorSchema },\n { status: 401, description: 'Unauthorized', schema: sidebarErrorSchema },\n { status: 403, description: 'Missing features', schema: sidebarErrorSchema },\n { status: 404, description: 'Role not found in current tenant scope', schema: sidebarErrorSchema },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["rolesPayload"]
|
|
7
7
|
}
|