@open-mercato/core 0.4.5-develop-5191db4ef3 → 0.4.5-develop-9f9549ebc8
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/dist/generated/entities/message/index.js +65 -0
- package/dist/generated/entities/message/index.js.map +7 -0
- package/dist/generated/entities/message_access_token/index.js +19 -0
- package/dist/generated/entities/message_access_token/index.js.map +7 -0
- package/dist/generated/entities/message_confirmation/index.js +21 -0
- package/dist/generated/entities/message_confirmation/index.js.map +7 -0
- package/dist/generated/entities/message_object/index.js +23 -0
- package/dist/generated/entities/message_object/index.js.map +7 -0
- package/dist/generated/entities/message_recipient/index.js +31 -0
- package/dist/generated/entities/message_recipient/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +8 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +10 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +27 -8
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/lib/messageObjectPreviews.js +131 -0
- package/dist/modules/customers/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/customers/message-objects.js +71 -0
- package/dist/modules/customers/message-objects.js.map +7 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js +51 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js.map +7 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js +35 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js.map +7 -0
- package/dist/modules/customers/widgets/messages/index.js +7 -0
- package/dist/modules/customers/widgets/messages/index.js.map +7 -0
- package/dist/modules/messages/acl.js +15 -0
- package/dist/modules/messages/acl.js.map +7 -0
- package/dist/modules/messages/api/[id]/actions/[actionId]/route.js +92 -0
- package/dist/modules/messages/api/[id]/actions/[actionId]/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/archive/route.js +120 -0
- package/dist/modules/messages/api/[id]/archive/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/attachments/route.js +195 -0
- package/dist/modules/messages/api/[id]/attachments/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/confirmation/route.js +67 -0
- package/dist/modules/messages/api/[id]/confirmation/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/conversation/archive/route.js +68 -0
- package/dist/modules/messages/api/[id]/conversation/archive/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/conversation/read/route.js +68 -0
- package/dist/modules/messages/api/[id]/conversation/read/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/conversation/route.js +68 -0
- package/dist/modules/messages/api/[id]/conversation/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/forward/route.js +85 -0
- package/dist/modules/messages/api/[id]/forward/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/forward-preview/route.js +70 -0
- package/dist/modules/messages/api/[id]/forward-preview/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/read/route.js +120 -0
- package/dist/modules/messages/api/[id]/read/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/reply/route.js +87 -0
- package/dist/modules/messages/api/[id]/reply/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/route.js +350 -0
- package/dist/modules/messages/api/[id]/route.js.map +7 -0
- package/dist/modules/messages/api/object-types/route.js +54 -0
- package/dist/modules/messages/api/object-types/route.js.map +7 -0
- package/dist/modules/messages/api/openapi.js +261 -0
- package/dist/modules/messages/api/openapi.js.map +7 -0
- package/dist/modules/messages/api/route.js +262 -0
- package/dist/modules/messages/api/route.js.map +7 -0
- package/dist/modules/messages/api/token/[token]/route.js +99 -0
- package/dist/modules/messages/api/token/[token]/route.js.map +7 -0
- package/dist/modules/messages/api/types/route.js +40 -0
- package/dist/modules/messages/api/types/route.js.map +7 -0
- package/dist/modules/messages/api/unread-count/route.js +43 -0
- package/dist/modules/messages/api/unread-count/route.js.map +7 -0
- package/dist/modules/messages/backend/messages/[id]/page.js +10 -0
- package/dist/modules/messages/backend/messages/[id]/page.js.map +7 -0
- package/dist/modules/messages/backend/messages/[id]/page.meta.js +16 -0
- package/dist/modules/messages/backend/messages/[id]/page.meta.js.map +7 -0
- package/dist/modules/messages/backend/messages/compose/page.js +10 -0
- package/dist/modules/messages/backend/messages/compose/page.js.map +7 -0
- package/dist/modules/messages/backend/messages/compose/page.meta.js +17 -0
- package/dist/modules/messages/backend/messages/compose/page.meta.js.map +7 -0
- package/dist/modules/messages/backend/page.js +10 -0
- package/dist/modules/messages/backend/page.js.map +7 -0
- package/dist/modules/messages/backend/page.meta.js +33 -0
- package/dist/modules/messages/backend/page.meta.js.map +7 -0
- package/dist/modules/messages/commands/actions.js +265 -0
- package/dist/modules/messages/commands/actions.js.map +7 -0
- package/dist/modules/messages/commands/attachments.js +217 -0
- package/dist/modules/messages/commands/attachments.js.map +7 -0
- package/dist/modules/messages/commands/confirmations.js +151 -0
- package/dist/modules/messages/commands/confirmations.js.map +7 -0
- package/dist/modules/messages/commands/conversation.js +240 -0
- package/dist/modules/messages/commands/conversation.js.map +7 -0
- package/dist/modules/messages/commands/messages.js +748 -0
- package/dist/modules/messages/commands/messages.js.map +7 -0
- package/dist/modules/messages/commands/recipients.js +259 -0
- package/dist/modules/messages/commands/recipients.js.map +7 -0
- package/dist/modules/messages/commands/shared.js +258 -0
- package/dist/modules/messages/commands/shared.js.map +7 -0
- package/dist/modules/messages/commands/tokens.js +69 -0
- package/dist/modules/messages/commands/tokens.js.map +7 -0
- package/dist/modules/messages/components/ComposeMessagePageClient.js +24 -0
- package/dist/modules/messages/components/ComposeMessagePageClient.js.map +7 -0
- package/dist/modules/messages/components/MessageDetailPageClient.js +261 -0
- package/dist/modules/messages/components/MessageDetailPageClient.js.map +7 -0
- package/dist/modules/messages/components/MessagesInboxPageClient.js +390 -0
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +7 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationActions.js +31 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationActions.js.map +7 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationContent.js +69 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationContent.js.map +7 -0
- package/dist/modules/messages/components/defaults/DefaultMessageActions.js +31 -0
- package/dist/modules/messages/components/defaults/DefaultMessageActions.js.map +7 -0
- package/dist/modules/messages/components/defaults/DefaultMessageContent.js +19 -0
- package/dist/modules/messages/components/defaults/DefaultMessageContent.js.map +7 -0
- package/dist/modules/messages/components/defaults/DefaultMessageListItem.js +90 -0
- package/dist/modules/messages/components/defaults/DefaultMessageListItem.js.map +7 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js +86 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js.map +7 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js +61 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js.map +7 -0
- package/dist/modules/messages/components/message-detail/detail-panels.js +27 -0
- package/dist/modules/messages/components/message-detail/detail-panels.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js +52 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js +289 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +103 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js +78 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js +94 -0
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +110 -0
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js +58 -0
- package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/actions-panel.js +51 -0
- package/dist/modules/messages/components/message-detail/panels/actions-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/attachments-panel.js +66 -0
- package/dist/modules/messages/components/message-detail/panels/attachments-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/body-panel.js +20 -0
- package/dist/modules/messages/components/message-detail/panels/body-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/composer-dialogs.js +36 -0
- package/dist/modules/messages/components/message-detail/panels/composer-dialogs.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/dialogs.js +96 -0
- package/dist/modules/messages/components/message-detail/panels/dialogs.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/index.js +25 -0
- package/dist/modules/messages/components/message-detail/panels/index.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/meta-panel.js +14 -0
- package/dist/modules/messages/components/message-detail/panels/meta-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/objects-panel.js +51 -0
- package/dist/modules/messages/components/message-detail/panels/objects-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js +54 -0
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/types.js +1 -0
- package/dist/modules/messages/components/message-detail/types.js.map +7 -0
- package/dist/modules/messages/components/message-detail/utils.js +54 -0
- package/dist/modules/messages/components/message-detail/utils.js.map +7 -0
- package/dist/modules/messages/components/utils/PriorityBadge.js +52 -0
- package/dist/modules/messages/components/utils/PriorityBadge.js.map +7 -0
- package/dist/modules/messages/components/utils/typeUiRegistry.js +77 -0
- package/dist/modules/messages/components/utils/typeUiRegistry.js.map +7 -0
- package/dist/modules/messages/data/entities.js +309 -0
- package/dist/modules/messages/data/entities.js.map +7 -0
- package/dist/modules/messages/data/validators.js +272 -0
- package/dist/modules/messages/data/validators.js.map +7 -0
- package/dist/modules/messages/emails/MessageEmail.js +108 -0
- package/dist/modules/messages/emails/MessageEmail.js.map +7 -0
- package/dist/modules/messages/events.js +24 -0
- package/dist/modules/messages/events.js.map +7 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.js +247 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.js.map +7 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.meta.js +9 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.meta.js.map +7 -0
- package/dist/modules/messages/index.js +21 -0
- package/dist/modules/messages/index.js.map +7 -0
- package/dist/modules/messages/lib/actions.js +141 -0
- package/dist/modules/messages/lib/actions.js.map +7 -0
- package/dist/modules/messages/lib/attachments.js +131 -0
- package/dist/modules/messages/lib/attachments.js.map +7 -0
- package/dist/modules/messages/lib/constants.js +7 -0
- package/dist/modules/messages/lib/constants.js.map +7 -0
- package/dist/modules/messages/lib/email-sender.js +201 -0
- package/dist/modules/messages/lib/email-sender.js.map +7 -0
- package/dist/modules/messages/lib/forwarding.js +179 -0
- package/dist/modules/messages/lib/forwarding.js.map +7 -0
- package/dist/modules/messages/lib/message-objects-registry.js +49 -0
- package/dist/modules/messages/lib/message-objects-registry.js.map +7 -0
- package/dist/modules/messages/lib/message-types-registry.js +41 -0
- package/dist/modules/messages/lib/message-types-registry.js.map +7 -0
- package/dist/modules/messages/lib/object-validation.js +20 -0
- package/dist/modules/messages/lib/object-validation.js.map +7 -0
- package/dist/modules/messages/lib/operationMetadata.js +21 -0
- package/dist/modules/messages/lib/operationMetadata.js.map +7 -0
- package/dist/modules/messages/lib/priorityUtils.js +61 -0
- package/dist/modules/messages/lib/priorityUtils.js.map +7 -0
- package/dist/modules/messages/lib/routeHelpers.js +44 -0
- package/dist/modules/messages/lib/routeHelpers.js.map +7 -0
- package/dist/modules/messages/message-objects.js +7 -0
- package/dist/modules/messages/message-objects.js.map +7 -0
- package/dist/modules/messages/message-types.js +67 -0
- package/dist/modules/messages/message-types.js.map +7 -0
- package/dist/modules/messages/migrations/Migration20260213181243.js +31 -0
- package/dist/modules/messages/migrations/Migration20260213181243.js.map +7 -0
- package/dist/modules/messages/migrations/Migration20260215165126.js +16 -0
- package/dist/modules/messages/migrations/Migration20260215165126.js.map +7 -0
- package/dist/modules/messages/notifications.js +27 -0
- package/dist/modules/messages/notifications.js.map +7 -0
- package/dist/modules/messages/setup.js +21 -0
- package/dist/modules/messages/setup.js.map +7 -0
- package/dist/modules/messages/subscribers/message-notification.js +108 -0
- package/dist/modules/messages/subscribers/message-notification.js.map +7 -0
- package/dist/modules/messages/workers/send-email.worker.js +253 -0
- package/dist/modules/messages/workers/send-email.worker.js.map +7 -0
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +30 -11
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +12 -6
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/lib/messageObjectPreviews.js +114 -0
- package/dist/modules/sales/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/sales/message-objects.js +57 -0
- package/dist/modules/sales/message-objects.js.map +7 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js +51 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js.map +7 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js +36 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js.map +7 -0
- package/dist/modules/sales/widgets/messages/index.js +7 -0
- package/dist/modules/sales/widgets/messages/index.js.map +7 -0
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +55 -1
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +60 -1
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +2 -19
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/components/LeaveRequestDetail.js +112 -0
- package/dist/modules/staff/components/LeaveRequestDetail.js.map +7 -0
- package/dist/modules/staff/components/LeaveRequestForm.js +3 -1
- package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
- package/dist/modules/staff/components/LeaveRequestPreview.js +43 -0
- package/dist/modules/staff/components/LeaveRequestPreview.js.map +7 -0
- package/dist/modules/staff/lib/messageObjectPreviews.js +148 -0
- package/dist/modules/staff/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/staff/message-objects.js +104 -0
- package/dist/modules/staff/message-objects.js.map +7 -0
- package/dist/modules/staff/message-types.js +23 -0
- package/dist/modules/staff/message-types.js.map +7 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js +51 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js.map +7 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js +34 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js.map +7 -0
- package/dist/modules/staff/widgets/messages/index.js +7 -0
- package/dist/modules/staff/widgets/messages/index.js.map +7 -0
- package/generated/entities/message/index.ts +31 -0
- package/generated/entities/message_access_token/index.ts +8 -0
- package/generated/entities/message_confirmation/index.ts +9 -0
- package/generated/entities/message_object/index.ts +10 -0
- package/generated/entities/message_recipient/index.ts +14 -0
- package/generated/entities.ids.generated.ts +8 -0
- package/generated/entity-fields-registry.ts +10 -0
- package/jest.setup.ts +5 -0
- package/package.json +2 -2
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +20 -4
- package/src/modules/customers/i18n/de.json +4 -0
- package/src/modules/customers/i18n/en.json +4 -0
- package/src/modules/customers/i18n/es.json +4 -0
- package/src/modules/customers/i18n/pl.json +4 -0
- package/src/modules/customers/lib/messageObjectPreviews.ts +154 -0
- package/src/modules/customers/message-objects.ts +70 -0
- package/src/modules/customers/widgets/messages/CustomerMessageObjectDetail.tsx +57 -0
- package/src/modules/customers/widgets/messages/CustomerMessageObjectPreview.tsx +49 -0
- package/src/modules/customers/widgets/messages/index.ts +2 -0
- package/src/modules/messages/acl.ts +11 -0
- package/src/modules/messages/api/[id]/actions/[actionId]/route.ts +103 -0
- package/src/modules/messages/api/[id]/archive/route.ts +138 -0
- package/src/modules/messages/api/[id]/attachments/route.ts +217 -0
- package/src/modules/messages/api/[id]/confirmation/route.ts +73 -0
- package/src/modules/messages/api/[id]/conversation/archive/route.ts +69 -0
- package/src/modules/messages/api/[id]/conversation/read/route.ts +69 -0
- package/src/modules/messages/api/[id]/conversation/route.ts +69 -0
- package/src/modules/messages/api/[id]/forward/route.ts +87 -0
- package/src/modules/messages/api/[id]/forward-preview/route.ts +75 -0
- package/src/modules/messages/api/[id]/read/route.ts +138 -0
- package/src/modules/messages/api/[id]/reply/route.ts +89 -0
- package/src/modules/messages/api/[id]/route.ts +401 -0
- package/src/modules/messages/api/object-types/route.ts +54 -0
- package/src/modules/messages/api/openapi.ts +261 -0
- package/src/modules/messages/api/route.ts +374 -0
- package/src/modules/messages/api/token/[token]/route.ts +103 -0
- package/src/modules/messages/api/types/route.ts +39 -0
- package/src/modules/messages/api/unread-count/route.ts +55 -0
- package/src/modules/messages/backend/messages/[id]/page.meta.ts +12 -0
- package/src/modules/messages/backend/messages/[id]/page.tsx +12 -0
- package/src/modules/messages/backend/messages/compose/page.meta.ts +13 -0
- package/src/modules/messages/backend/messages/compose/page.tsx +12 -0
- package/src/modules/messages/backend/page.meta.ts +31 -0
- package/src/modules/messages/backend/page.tsx +12 -0
- package/src/modules/messages/commands/actions.ts +307 -0
- package/src/modules/messages/commands/attachments.ts +227 -0
- package/src/modules/messages/commands/confirmations.ts +183 -0
- package/src/modules/messages/commands/conversation.ts +292 -0
- package/src/modules/messages/commands/messages.ts +845 -0
- package/src/modules/messages/commands/recipients.ts +281 -0
- package/src/modules/messages/commands/shared.ts +350 -0
- package/src/modules/messages/commands/tokens.ts +80 -0
- package/src/modules/messages/components/ComposeMessagePageClient.tsx +23 -0
- package/src/modules/messages/components/MessageDetailPageClient.tsx +287 -0
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +469 -0
- package/src/modules/messages/components/confirmation/MessageConfirmationActions.tsx +35 -0
- package/src/modules/messages/components/confirmation/MessageConfirmationContent.tsx +88 -0
- package/src/modules/messages/components/defaults/DefaultMessageActions.tsx +37 -0
- package/src/modules/messages/components/defaults/DefaultMessageContent.tsx +21 -0
- package/src/modules/messages/components/defaults/DefaultMessageListItem.tsx +102 -0
- package/src/modules/messages/components/defaults/MessageRecordObjectDetail.tsx +114 -0
- package/src/modules/messages/components/defaults/MessageRecordObjectPreview.tsx +74 -0
- package/src/modules/messages/components/message-detail/detail-panels.ts +13 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetails.ts +56 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsActions.ts +367 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +134 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.ts +102 -0
- package/src/modules/messages/components/message-detail/panels/MainMessageHeader.tsx +108 -0
- package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +144 -0
- package/src/modules/messages/components/message-detail/panels/MessageListComponent.tsx +63 -0
- package/src/modules/messages/components/message-detail/panels/actions-panel.tsx +66 -0
- package/src/modules/messages/components/message-detail/panels/attachments-panel.tsx +86 -0
- package/src/modules/messages/components/message-detail/panels/body-panel.tsx +32 -0
- package/src/modules/messages/components/message-detail/panels/composer-dialogs.tsx +42 -0
- package/src/modules/messages/components/message-detail/panels/dialogs.tsx +107 -0
- package/src/modules/messages/components/message-detail/panels/index.ts +11 -0
- package/src/modules/messages/components/message-detail/panels/meta-panel.tsx +19 -0
- package/src/modules/messages/components/message-detail/panels/objects-panel.tsx +65 -0
- package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +65 -0
- package/src/modules/messages/components/message-detail/types.ts +114 -0
- package/src/modules/messages/components/message-detail/utils.ts +62 -0
- package/src/modules/messages/components/utils/PriorityBadge.tsx +63 -0
- package/src/modules/messages/components/utils/typeUiRegistry.ts +106 -0
- package/src/modules/messages/data/entities.ts +284 -0
- package/src/modules/messages/data/validators.ts +297 -0
- package/src/modules/messages/emails/MessageEmail.tsx +143 -0
- package/src/modules/messages/events.ts +24 -0
- package/src/modules/messages/frontend/messages/view/[token]/page.meta.ts +5 -0
- package/src/modules/messages/frontend/messages/view/[token]/page.tsx +389 -0
- package/src/modules/messages/i18n/de.json +240 -0
- package/src/modules/messages/i18n/en.json +240 -0
- package/src/modules/messages/i18n/es.json +240 -0
- package/src/modules/messages/i18n/pl.json +240 -0
- package/src/modules/messages/index.ts +19 -0
- package/src/modules/messages/lib/actions.ts +204 -0
- package/src/modules/messages/lib/attachments.ts +197 -0
- package/src/modules/messages/lib/constants.ts +2 -0
- package/src/modules/messages/lib/email-sender.ts +255 -0
- package/src/modules/messages/lib/forwarding.ts +240 -0
- package/src/modules/messages/lib/message-objects-registry.ts +60 -0
- package/src/modules/messages/lib/message-types-registry.ts +48 -0
- package/src/modules/messages/lib/object-validation.ts +26 -0
- package/src/modules/messages/lib/operationMetadata.ts +43 -0
- package/src/modules/messages/lib/priorityUtils.ts +76 -0
- package/src/modules/messages/lib/routeHelpers.ts +65 -0
- package/src/modules/messages/message-objects.ts +5 -0
- package/src/modules/messages/message-types.ts +65 -0
- package/src/modules/messages/migrations/.snapshot-open-mercato.json +957 -0
- package/src/modules/messages/migrations/Migration20260213181243.ts +34 -0
- package/src/modules/messages/migrations/Migration20260215165126.ts +16 -0
- package/src/modules/messages/notifications.ts +25 -0
- package/src/modules/messages/setup.ts +19 -0
- package/src/modules/messages/subscribers/message-notification.ts +138 -0
- package/src/modules/messages/workers/send-email.worker.ts +321 -0
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +23 -7
- package/src/modules/sales/commands/payments.ts +12 -6
- package/src/modules/sales/i18n/de.json +3 -0
- package/src/modules/sales/i18n/en.json +3 -0
- package/src/modules/sales/i18n/es.json +3 -0
- package/src/modules/sales/i18n/pl.json +3 -0
- package/src/modules/sales/lib/messageObjectPreviews.ts +150 -0
- package/src/modules/sales/message-objects.ts +56 -0
- package/src/modules/sales/widgets/messages/SalesDocumentMessageDetail.tsx +57 -0
- package/src/modules/sales/widgets/messages/SalesDocumentMessagePreview.tsx +46 -0
- package/src/modules/sales/widgets/messages/index.ts +2 -0
- package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +54 -0
- package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +58 -0
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +2 -32
- package/src/modules/staff/components/LeaveRequestDetail.tsx +135 -0
- package/src/modules/staff/components/LeaveRequestForm.tsx +3 -0
- package/src/modules/staff/components/LeaveRequestPreview.tsx +74 -0
- package/src/modules/staff/i18n/de.json +8 -0
- package/src/modules/staff/i18n/en.json +8 -0
- package/src/modules/staff/i18n/es.json +8 -0
- package/src/modules/staff/i18n/pl.json +8 -0
- package/src/modules/staff/lib/messageObjectPreviews.ts +182 -0
- package/src/modules/staff/message-objects.ts +102 -0
- package/src/modules/staff/message-types.ts +21 -0
- package/src/modules/staff/widgets/messages/StaffMessageObjectDetail.tsx +57 -0
- package/src/modules/staff/widgets/messages/StaffMessageObjectPreview.tsx +44 -0
- package/src/modules/staff/widgets/messages/index.ts +2 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Migration } from "@mikro-orm/migrations";
|
|
2
|
+
class Migration20260213181243 extends Migration {
|
|
3
|
+
async up() {
|
|
4
|
+
this.addSql(`create table "messages" ("id" uuid not null default gen_random_uuid(), "type" text not null default 'default', "thread_id" uuid null, "parent_message_id" uuid null, "sender_user_id" uuid not null, "subject" text not null, "body" text not null, "body_format" text not null default 'text', "priority" text not null default 'normal', "status" text not null default 'draft', "is_draft" boolean not null default true, "sent_at" timestamptz null, "action_data" jsonb null, "action_result" jsonb null, "action_taken" text null, "action_taken_by_user_id" uuid null, "action_taken_at" timestamptz null, "send_via_email" boolean not null default false, "tenant_id" uuid not null, "organization_id" uuid null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, "visibility" text null, "source_entity_type" text null, "source_entity_id" uuid null, "external_email" text null, "external_name" text null, "external_email_sent_at" timestamptz null, "external_email_failed_at" timestamptz null, "external_email_error" text null, constraint "messages_pkey" primary key ("id"));`);
|
|
5
|
+
this.addSql(`create index "messages_tenant_idx" on "messages" ("tenant_id", "organization_id");`);
|
|
6
|
+
this.addSql(`create index "messages_type_idx" on "messages" ("type", "tenant_id");`);
|
|
7
|
+
this.addSql(`create index "messages_thread_idx" on "messages" ("thread_id");`);
|
|
8
|
+
this.addSql(`create index "messages_sender_idx" on "messages" ("sender_user_id", "sent_at");`);
|
|
9
|
+
this.addSql(`create table "message_access_tokens" ("id" uuid not null default gen_random_uuid(), "message_id" uuid not null, "recipient_user_id" uuid not null, "token" text not null, "expires_at" timestamptz not null, "used_at" timestamptz null, "use_count" int not null default 0, "created_at" timestamptz not null, constraint "message_access_tokens_pkey" primary key ("id"));`);
|
|
10
|
+
this.addSql(`alter table "message_access_tokens" add constraint "message_access_tokens_token_unique" unique ("token");`);
|
|
11
|
+
this.addSql(`create index "message_access_tokens_message_idx" on "message_access_tokens" ("message_id");`);
|
|
12
|
+
this.addSql(`create index "message_access_tokens_token_idx" on "message_access_tokens" ("token");`);
|
|
13
|
+
this.addSql(`create table "message_objects" ("id" uuid not null default gen_random_uuid(), "message_id" uuid not null, "entity_module" text not null, "entity_type" text not null, "entity_id" uuid not null, "action_required" boolean not null default false, "action_type" text null, "action_label" text null, "entity_snapshot" jsonb null, "created_at" timestamptz not null, constraint "message_objects_pkey" primary key ("id"));`);
|
|
14
|
+
this.addSql(`create index "message_objects_entity_idx" on "message_objects" ("entity_type", "entity_id");`);
|
|
15
|
+
this.addSql(`create index "message_objects_message_idx" on "message_objects" ("message_id");`);
|
|
16
|
+
this.addSql(`create table "message_recipients" ("id" uuid not null default gen_random_uuid(), "message_id" uuid not null, "recipient_user_id" uuid not null, "recipient_type" text not null default 'to', "status" text not null default 'unread', "read_at" timestamptz null, "archived_at" timestamptz null, "deleted_at" timestamptz null, "email_sent_at" timestamptz null, "email_delivered_at" timestamptz null, "email_opened_at" timestamptz null, "email_failed_at" timestamptz null, "email_error" text null, "created_at" timestamptz not null, constraint "message_recipients_pkey" primary key ("id"));`);
|
|
17
|
+
this.addSql(`alter table "message_recipients" add constraint "message_recipients_message_user_unique" unique ("message_id", "recipient_user_id");`);
|
|
18
|
+
this.addSql(`create index "message_recipients_message_idx" on "message_recipients" ("message_id");`);
|
|
19
|
+
this.addSql(`create index "message_recipients_user_idx" on "message_recipients" ("recipient_user_id", "status");`);
|
|
20
|
+
}
|
|
21
|
+
async down() {
|
|
22
|
+
this.addSql(`drop table if exists "message_recipients" cascade;`);
|
|
23
|
+
this.addSql(`drop table if exists "message_objects" cascade;`);
|
|
24
|
+
this.addSql(`drop table if exists "message_access_tokens" cascade;`);
|
|
25
|
+
this.addSql(`drop table if exists "messages" cascade;`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
Migration20260213181243
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=Migration20260213181243.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/messages/migrations/Migration20260213181243.ts"],
|
|
4
|
+
"sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260213181243 extends Migration {\n\n override async up(): Promise<void> {\n this.addSql(`create table \"messages\" (\"id\" uuid not null default gen_random_uuid(), \"type\" text not null default 'default', \"thread_id\" uuid null, \"parent_message_id\" uuid null, \"sender_user_id\" uuid not null, \"subject\" text not null, \"body\" text not null, \"body_format\" text not null default 'text', \"priority\" text not null default 'normal', \"status\" text not null default 'draft', \"is_draft\" boolean not null default true, \"sent_at\" timestamptz null, \"action_data\" jsonb null, \"action_result\" jsonb null, \"action_taken\" text null, \"action_taken_by_user_id\" uuid null, \"action_taken_at\" timestamptz null, \"send_via_email\" boolean not null default false, \"tenant_id\" uuid not null, \"organization_id\" uuid null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, \"deleted_at\" timestamptz null, \"visibility\" text null, \"source_entity_type\" text null, \"source_entity_id\" uuid null, \"external_email\" text null, \"external_name\" text null, \"external_email_sent_at\" timestamptz null, \"external_email_failed_at\" timestamptz null, \"external_email_error\" text null, constraint \"messages_pkey\" primary key (\"id\"));`);\n this.addSql(`create index \"messages_tenant_idx\" on \"messages\" (\"tenant_id\", \"organization_id\");`);\n this.addSql(`create index \"messages_type_idx\" on \"messages\" (\"type\", \"tenant_id\");`);\n this.addSql(`create index \"messages_thread_idx\" on \"messages\" (\"thread_id\");`);\n this.addSql(`create index \"messages_sender_idx\" on \"messages\" (\"sender_user_id\", \"sent_at\");`);\n\n this.addSql(`create table \"message_access_tokens\" (\"id\" uuid not null default gen_random_uuid(), \"message_id\" uuid not null, \"recipient_user_id\" uuid not null, \"token\" text not null, \"expires_at\" timestamptz not null, \"used_at\" timestamptz null, \"use_count\" int not null default 0, \"created_at\" timestamptz not null, constraint \"message_access_tokens_pkey\" primary key (\"id\"));`);\n this.addSql(`alter table \"message_access_tokens\" add constraint \"message_access_tokens_token_unique\" unique (\"token\");`);\n this.addSql(`create index \"message_access_tokens_message_idx\" on \"message_access_tokens\" (\"message_id\");`);\n this.addSql(`create index \"message_access_tokens_token_idx\" on \"message_access_tokens\" (\"token\");`);\n\n this.addSql(`create table \"message_objects\" (\"id\" uuid not null default gen_random_uuid(), \"message_id\" uuid not null, \"entity_module\" text not null, \"entity_type\" text not null, \"entity_id\" uuid not null, \"action_required\" boolean not null default false, \"action_type\" text null, \"action_label\" text null, \"entity_snapshot\" jsonb null, \"created_at\" timestamptz not null, constraint \"message_objects_pkey\" primary key (\"id\"));`);\n this.addSql(`create index \"message_objects_entity_idx\" on \"message_objects\" (\"entity_type\", \"entity_id\");`);\n this.addSql(`create index \"message_objects_message_idx\" on \"message_objects\" (\"message_id\");`);\n\n this.addSql(`create table \"message_recipients\" (\"id\" uuid not null default gen_random_uuid(), \"message_id\" uuid not null, \"recipient_user_id\" uuid not null, \"recipient_type\" text not null default 'to', \"status\" text not null default 'unread', \"read_at\" timestamptz null, \"archived_at\" timestamptz null, \"deleted_at\" timestamptz null, \"email_sent_at\" timestamptz null, \"email_delivered_at\" timestamptz null, \"email_opened_at\" timestamptz null, \"email_failed_at\" timestamptz null, \"email_error\" text null, \"created_at\" timestamptz not null, constraint \"message_recipients_pkey\" primary key (\"id\"));`);\n this.addSql(`alter table \"message_recipients\" add constraint \"message_recipients_message_user_unique\" unique (\"message_id\", \"recipient_user_id\");`);\n this.addSql(`create index \"message_recipients_message_idx\" on \"message_recipients\" (\"message_id\");`);\n this.addSql(`create index \"message_recipients_user_idx\" on \"message_recipients\" (\"recipient_user_id\", \"status\");`);\n }\n\n override async down(): Promise<void> {\n this.addSql(`drop table if exists \"message_recipients\" cascade;`);\n this.addSql(`drop table if exists \"message_objects\" cascade;`);\n this.addSql(`drop table if exists \"message_access_tokens\" cascade;`);\n this.addSql(`drop table if exists \"messages\" cascade;`);\n }\n\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,gCAAgC,UAAU;AAAA,EAErD,MAAe,KAAoB;AACjC,SAAK,OAAO,wlCAAwlC;AACpmC,SAAK,OAAO,oFAAoF;AAChG,SAAK,OAAO,uEAAuE;AACnF,SAAK,OAAO,iEAAiE;AAC7E,SAAK,OAAO,iFAAiF;AAE7F,SAAK,OAAO,8WAA8W;AAC1X,SAAK,OAAO,2GAA2G;AACvH,SAAK,OAAO,6FAA6F;AACzG,SAAK,OAAO,sFAAsF;AAElG,SAAK,OAAO,+ZAA+Z;AAC3a,SAAK,OAAO,8FAA8F;AAC1G,SAAK,OAAO,iFAAiF;AAE7F,SAAK,OAAO,ykBAAykB;AACrlB,SAAK,OAAO,sIAAsI;AAClJ,SAAK,OAAO,uFAAuF;AACnG,SAAK,OAAO,qGAAqG;AAAA,EACnH;AAAA,EAEA,MAAe,OAAsB;AACnC,SAAK,OAAO,oDAAoD;AAChE,SAAK,OAAO,iDAAiD;AAC7D,SAAK,OAAO,uDAAuD;AACnE,SAAK,OAAO,0CAA0C;AAAA,EACxD;AAEF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Migration } from "@mikro-orm/migrations";
|
|
2
|
+
class Migration20260215165126 extends Migration {
|
|
3
|
+
async up() {
|
|
4
|
+
this.addSql(`create table "message_confirmations" ("id" uuid not null default gen_random_uuid(), "message_id" uuid not null, "tenant_id" uuid not null, "organization_id" uuid null, "confirmed" boolean not null default true, "confirmed_by_user_id" uuid null, "confirmed_at" timestamptz null, "created_at" timestamptz not null, "updated_at" timestamptz not null, constraint "message_confirmations_pkey" primary key ("id"));`);
|
|
5
|
+
this.addSql(`create index "message_confirmations_scope_idx" on "message_confirmations" ("tenant_id", "organization_id");`);
|
|
6
|
+
this.addSql(`create index "message_confirmations_message_idx" on "message_confirmations" ("message_id");`);
|
|
7
|
+
this.addSql(`alter table "message_confirmations" add constraint "message_confirmations_message_unique" unique ("message_id");`);
|
|
8
|
+
}
|
|
9
|
+
async down() {
|
|
10
|
+
this.addSql(`drop table if exists "message_confirmations" cascade;`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
Migration20260215165126
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=Migration20260215165126.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/messages/migrations/Migration20260215165126.ts"],
|
|
4
|
+
"sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260215165126 extends Migration {\n\n override async up(): Promise<void> {\n this.addSql(`create table \"message_confirmations\" (\"id\" uuid not null default gen_random_uuid(), \"message_id\" uuid not null, \"tenant_id\" uuid not null, \"organization_id\" uuid null, \"confirmed\" boolean not null default true, \"confirmed_by_user_id\" uuid null, \"confirmed_at\" timestamptz null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, constraint \"message_confirmations_pkey\" primary key (\"id\"));`);\n this.addSql(`create index \"message_confirmations_scope_idx\" on \"message_confirmations\" (\"tenant_id\", \"organization_id\");`);\n this.addSql(`create index \"message_confirmations_message_idx\" on \"message_confirmations\" (\"message_id\");`);\n this.addSql(`alter table \"message_confirmations\" add constraint \"message_confirmations_message_unique\" unique (\"message_id\");`);\n }\n\n override async down(): Promise<void> {\n this.addSql(`drop table if exists \"message_confirmations\" cascade;`);\n }\n\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,gCAAgC,UAAU;AAAA,EAErD,MAAe,KAAoB;AACjC,SAAK,OAAO,0ZAA0Z;AACta,SAAK,OAAO,6GAA6G;AACzH,SAAK,OAAO,6FAA6F;AACzG,SAAK,OAAO,kHAAkH;AAAA,EAChI;AAAA,EAEA,MAAe,OAAsB;AACnC,SAAK,OAAO,uDAAuD;AAAA,EACrE;AAEF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const notificationTypes = [
|
|
2
|
+
{
|
|
3
|
+
type: "messages.new",
|
|
4
|
+
module: "messages",
|
|
5
|
+
titleKey: "messages.notifications.new.title",
|
|
6
|
+
bodyKey: "messages.notifications.new.body",
|
|
7
|
+
icon: "mail",
|
|
8
|
+
severity: "info",
|
|
9
|
+
actions: [
|
|
10
|
+
{
|
|
11
|
+
id: "view",
|
|
12
|
+
labelKey: "common.view",
|
|
13
|
+
variant: "outline",
|
|
14
|
+
href: "/backend/messages/{sourceEntityId}",
|
|
15
|
+
icon: "external-link"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
linkHref: "/backend/messages/{sourceEntityId}",
|
|
19
|
+
expiresAfterHours: 168
|
|
20
|
+
}
|
|
21
|
+
];
|
|
22
|
+
var notifications_default = notificationTypes;
|
|
23
|
+
export {
|
|
24
|
+
notifications_default as default,
|
|
25
|
+
notificationTypes
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=notifications.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/messages/notifications.ts"],
|
|
4
|
+
"sourcesContent": ["import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'\n\nexport const notificationTypes: NotificationTypeDefinition[] = [\n {\n type: 'messages.new',\n module: 'messages',\n titleKey: 'messages.notifications.new.title',\n bodyKey: 'messages.notifications.new.body',\n icon: 'mail',\n severity: 'info',\n actions: [\n {\n id: 'view',\n labelKey: 'common.view',\n variant: 'outline',\n href: '/backend/messages/{sourceEntityId}',\n icon: 'external-link',\n },\n ],\n linkHref: '/backend/messages/{sourceEntityId}',\n expiresAfterHours: 168,\n },\n]\n\nexport default notificationTypes\n"],
|
|
5
|
+
"mappings": "AAEO,MAAM,oBAAkD;AAAA,EAC7D;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP;AAAA,QACE,IAAI;AAAA,QACJ,UAAU;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,UAAU;AAAA,IACV,mBAAmB;AAAA,EACrB;AACF;AAEA,IAAO,wBAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const setup = {
|
|
2
|
+
defaultRoleFeatures: {
|
|
3
|
+
superadmin: ["messages.*"],
|
|
4
|
+
admin: [
|
|
5
|
+
"messages.*"
|
|
6
|
+
],
|
|
7
|
+
employee: [
|
|
8
|
+
"messages.view",
|
|
9
|
+
"messages.compose",
|
|
10
|
+
"messages.attach",
|
|
11
|
+
"messages.attach_files",
|
|
12
|
+
"messages.actions"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var setup_default = setup;
|
|
17
|
+
export {
|
|
18
|
+
setup_default as default,
|
|
19
|
+
setup
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/messages/setup.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ModuleSetupConfig } from '@open-mercato/shared/modules/setup'\n\nexport const setup: ModuleSetupConfig = {\n defaultRoleFeatures: {\n superadmin: ['messages.*'],\n admin: [\n 'messages.*',\n ],\n employee: [\n 'messages.view',\n 'messages.compose',\n 'messages.attach',\n 'messages.attach_files',\n 'messages.actions',\n ],\n },\n}\n\nexport default setup\n"],
|
|
5
|
+
"mappings": "AAEO,MAAM,QAA2B;AAAA,EACtC,qBAAqB;AAAA,IACnB,YAAY,CAAC,YAAY;AAAA,IACzB,OAAO;AAAA,MACL;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,gBAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
2
|
+
import { createQueue } from "@open-mercato/queue";
|
|
3
|
+
import { buildBatchNotificationFromType } from "../../notifications/lib/notificationBuilder.js";
|
|
4
|
+
import { resolveNotificationService } from "../../notifications/lib/notificationService.js";
|
|
5
|
+
import {
|
|
6
|
+
MESSAGES_EMAIL_QUEUE_NAME
|
|
7
|
+
} from "../workers/send-email.worker.js";
|
|
8
|
+
import { User } from "../../auth/data/entities.js";
|
|
9
|
+
import { Message } from "../data/entities.js";
|
|
10
|
+
import { notificationTypes } from "../notifications.js";
|
|
11
|
+
const metadata = {
|
|
12
|
+
event: "messages.message.sent",
|
|
13
|
+
persistent: true,
|
|
14
|
+
id: "messages:queue-email-delivery"
|
|
15
|
+
};
|
|
16
|
+
async function resolveNotificationVariables(payload, ctx) {
|
|
17
|
+
try {
|
|
18
|
+
const em = ctx.resolve("em")?.fork();
|
|
19
|
+
if (!em) return { title: "", from: "" };
|
|
20
|
+
const scope = {
|
|
21
|
+
tenantId: payload.tenantId,
|
|
22
|
+
organizationId: payload.organizationId ?? null
|
|
23
|
+
};
|
|
24
|
+
const whereUser = {
|
|
25
|
+
id: payload.senderUserId,
|
|
26
|
+
tenantId: payload.tenantId,
|
|
27
|
+
deletedAt: null
|
|
28
|
+
};
|
|
29
|
+
if (payload.organizationId !== void 0) {
|
|
30
|
+
whereUser.organizationId = payload.organizationId;
|
|
31
|
+
}
|
|
32
|
+
const [message, sender] = await Promise.all([
|
|
33
|
+
findOneWithDecryption(
|
|
34
|
+
em,
|
|
35
|
+
Message,
|
|
36
|
+
{
|
|
37
|
+
id: payload.messageId,
|
|
38
|
+
tenantId: payload.tenantId,
|
|
39
|
+
deletedAt: null
|
|
40
|
+
},
|
|
41
|
+
void 0,
|
|
42
|
+
scope
|
|
43
|
+
),
|
|
44
|
+
findOneWithDecryption(
|
|
45
|
+
em,
|
|
46
|
+
User,
|
|
47
|
+
whereUser,
|
|
48
|
+
void 0,
|
|
49
|
+
scope
|
|
50
|
+
)
|
|
51
|
+
]);
|
|
52
|
+
return {
|
|
53
|
+
title: typeof message?.subject === "string" ? message.subject : "",
|
|
54
|
+
from: typeof sender?.name === "string" && sender.name.trim().length > 0 ? sender.name : typeof sender?.email === "string" ? sender.email : ""
|
|
55
|
+
};
|
|
56
|
+
} catch {
|
|
57
|
+
return { title: "", from: "" };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function handle(payload, ctx) {
|
|
61
|
+
const uniqueRecipientUserIds = Array.from(new Set(payload.recipientUserIds));
|
|
62
|
+
const typeDef = notificationTypes.find((type) => type.type === "messages.new");
|
|
63
|
+
if (typeDef && uniqueRecipientUserIds.length > 0) {
|
|
64
|
+
const variables = await resolveNotificationVariables(payload, ctx);
|
|
65
|
+
const notificationService = resolveNotificationService(ctx);
|
|
66
|
+
const notificationInput = buildBatchNotificationFromType(typeDef, {
|
|
67
|
+
recipientUserIds: uniqueRecipientUserIds,
|
|
68
|
+
titleVariables: variables,
|
|
69
|
+
bodyVariables: variables,
|
|
70
|
+
sourceEntityType: "message",
|
|
71
|
+
sourceEntityId: payload.messageId,
|
|
72
|
+
linkHref: `/backend/messages/${payload.messageId}`
|
|
73
|
+
});
|
|
74
|
+
await notificationService.createBatch(notificationInput, {
|
|
75
|
+
tenantId: payload.tenantId,
|
|
76
|
+
organizationId: payload.organizationId ?? null
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (!payload.sendViaEmail) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const strategy = process.env.QUEUE_STRATEGY === "async" ? "async" : "local";
|
|
83
|
+
const emailQueue = createQueue(MESSAGES_EMAIL_QUEUE_NAME, strategy);
|
|
84
|
+
for (const recipientUserId of uniqueRecipientUserIds) {
|
|
85
|
+
await emailQueue.enqueue({
|
|
86
|
+
type: "recipient",
|
|
87
|
+
messageId: payload.messageId,
|
|
88
|
+
recipientUserId,
|
|
89
|
+
tenantId: payload.tenantId,
|
|
90
|
+
organizationId: payload.organizationId ?? null
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
const externalEmail = payload.externalEmail?.trim();
|
|
94
|
+
if (externalEmail) {
|
|
95
|
+
await emailQueue.enqueue({
|
|
96
|
+
type: "external",
|
|
97
|
+
messageId: payload.messageId,
|
|
98
|
+
email: externalEmail,
|
|
99
|
+
tenantId: payload.tenantId,
|
|
100
|
+
organizationId: payload.organizationId ?? null
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
handle as default,
|
|
106
|
+
metadata
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=message-notification.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/messages/subscribers/message-notification.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { createQueue } from '@open-mercato/queue'\nimport { buildBatchNotificationFromType } from '../../notifications/lib/notificationBuilder'\nimport { resolveNotificationService } from '../../notifications/lib/notificationService'\nimport {\n MESSAGES_EMAIL_QUEUE_NAME,\n type SendMessageEmailJob,\n} from '../workers/send-email.worker'\nimport { User } from '../../auth/data/entities'\nimport { Message } from '../data/entities'\nimport { notificationTypes } from '../notifications'\n\nexport const metadata = {\n event: 'messages.message.sent',\n persistent: true,\n id: 'messages:queue-email-delivery',\n}\n\ntype MessageSentPayload = {\n messageId: string\n senderUserId: string\n recipientUserIds: string[]\n sendViaEmail: boolean\n externalEmail?: string | null\n forwardedFrom?: string\n replyTo?: string\n tenantId: string\n organizationId?: string | null\n}\n\ntype ResolverContext = {\n resolve: <T = unknown>(name: string) => T\n}\n\nasync function resolveNotificationVariables(payload: MessageSentPayload, ctx: ResolverContext): Promise<{ title: string; from: string }> {\n try {\n const em = ctx.resolve<EntityManager>('em')?.fork()\n if (!em) return { title: '', from: '' }\n\n const scope = {\n tenantId: payload.tenantId,\n organizationId: payload.organizationId ?? null,\n }\n const whereUser: { id: string; tenantId: string; deletedAt: null; organizationId?: string | null } = {\n id: payload.senderUserId,\n tenantId: payload.tenantId,\n deletedAt: null,\n }\n if (payload.organizationId !== undefined) {\n whereUser.organizationId = payload.organizationId\n }\n\n const [message, sender] = await Promise.all([\n findOneWithDecryption(\n em,\n Message,\n {\n id: payload.messageId,\n tenantId: payload.tenantId,\n deletedAt: null,\n },\n undefined,\n scope,\n ),\n findOneWithDecryption(\n em,\n User,\n whereUser,\n undefined,\n scope,\n ),\n ])\n\n return {\n title: typeof message?.subject === 'string' ? message.subject : '',\n from: typeof sender?.name === 'string' && sender.name.trim().length > 0\n ? sender.name\n : typeof sender?.email === 'string'\n ? sender.email\n : '',\n }\n } catch {\n return { title: '', from: '' }\n }\n}\n\n\nexport default async function handle(payload: MessageSentPayload, ctx: ResolverContext): Promise<void> {\n const uniqueRecipientUserIds = Array.from(new Set(payload.recipientUserIds))\n\n const typeDef = notificationTypes.find((type) => type.type === 'messages.new')\n if (typeDef && uniqueRecipientUserIds.length > 0) {\n const variables = await resolveNotificationVariables(payload, ctx)\n const notificationService = resolveNotificationService(ctx)\n const notificationInput = buildBatchNotificationFromType(typeDef, {\n recipientUserIds: uniqueRecipientUserIds,\n titleVariables: variables,\n bodyVariables: variables,\n sourceEntityType: 'message',\n sourceEntityId: payload.messageId,\n linkHref: `/backend/messages/${payload.messageId}`,\n })\n await notificationService.createBatch(notificationInput, {\n tenantId: payload.tenantId,\n organizationId: payload.organizationId ?? null,\n })\n }\n\n if (!payload.sendViaEmail) {\n return\n }\n\n const strategy = process.env.QUEUE_STRATEGY === 'async' ? 'async' : 'local'\n\n const emailQueue = createQueue<SendMessageEmailJob>(MESSAGES_EMAIL_QUEUE_NAME, strategy)\n\n for (const recipientUserId of uniqueRecipientUserIds) {\n await emailQueue.enqueue({\n type: 'recipient',\n messageId: payload.messageId,\n recipientUserId,\n tenantId: payload.tenantId,\n organizationId: payload.organizationId ?? null,\n })\n }\n\n const externalEmail = payload.externalEmail?.trim()\n if (externalEmail) {\n await emailQueue.enqueue({\n type: 'external',\n messageId: payload.messageId,\n email: externalEmail,\n tenantId: payload.tenantId,\n organizationId: payload.organizationId ?? null,\n })\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
2
|
+
import { User } from "../../auth/data/entities.js";
|
|
3
|
+
import { Message, MessageObject, MessageRecipient } from "../data/entities.js";
|
|
4
|
+
import { emitMessagesEvent } from "../events.js";
|
|
5
|
+
import { getMessageEmailAttachments } from "../lib/attachments.js";
|
|
6
|
+
import {
|
|
7
|
+
sendMessageEmailToExternal,
|
|
8
|
+
sendMessageEmailToRecipient
|
|
9
|
+
} from "../lib/email-sender.js";
|
|
10
|
+
const MESSAGES_EMAIL_QUEUE_NAME = "messages-email";
|
|
11
|
+
const metadata = {
|
|
12
|
+
queue: MESSAGES_EMAIL_QUEUE_NAME,
|
|
13
|
+
id: "messages:send-email",
|
|
14
|
+
concurrency: 10
|
|
15
|
+
};
|
|
16
|
+
async function emitEmailDeliveryEvent(ctx, eventId, payload) {
|
|
17
|
+
const eventBus = ctx.resolve("eventBus");
|
|
18
|
+
if (!eventBus || typeof eventBus !== "object" || typeof eventBus.emit !== "function") {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
await emitMessagesEvent(eventId, payload, { persistent: true });
|
|
22
|
+
}
|
|
23
|
+
async function resolveSender(em, message) {
|
|
24
|
+
const sender = await findOneWithDecryption(
|
|
25
|
+
em,
|
|
26
|
+
User,
|
|
27
|
+
{
|
|
28
|
+
id: message.senderUserId,
|
|
29
|
+
tenantId: message.tenantId,
|
|
30
|
+
deletedAt: null
|
|
31
|
+
},
|
|
32
|
+
void 0,
|
|
33
|
+
{ tenantId: message.tenantId, organizationId: message.organizationId ?? null }
|
|
34
|
+
);
|
|
35
|
+
return {
|
|
36
|
+
name: sender?.name ?? null,
|
|
37
|
+
email: sender?.email ?? null
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async function resolveMessageScope(em, payload) {
|
|
41
|
+
return await em.findOne(Message, {
|
|
42
|
+
id: payload.messageId,
|
|
43
|
+
tenantId: payload.tenantId,
|
|
44
|
+
organizationId: payload.organizationId ?? null,
|
|
45
|
+
deletedAt: null
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async function claimRecipientDelivery(em, payload) {
|
|
49
|
+
const claimTimestamp = /* @__PURE__ */ new Date();
|
|
50
|
+
const updatedRows = await em.nativeUpdate(
|
|
51
|
+
MessageRecipient,
|
|
52
|
+
{
|
|
53
|
+
messageId: payload.messageId,
|
|
54
|
+
recipientUserId: payload.recipientUserId,
|
|
55
|
+
emailSentAt: null
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
emailSentAt: claimTimestamp,
|
|
59
|
+
emailFailedAt: null,
|
|
60
|
+
emailError: null
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
return updatedRows > 0 ? claimTimestamp : null;
|
|
64
|
+
}
|
|
65
|
+
async function releaseRecipientClaim(em, payload, claimTimestamp, errorMessage) {
|
|
66
|
+
await em.nativeUpdate(
|
|
67
|
+
MessageRecipient,
|
|
68
|
+
{
|
|
69
|
+
messageId: payload.messageId,
|
|
70
|
+
recipientUserId: payload.recipientUserId,
|
|
71
|
+
emailSentAt: claimTimestamp
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
emailSentAt: null,
|
|
75
|
+
emailFailedAt: /* @__PURE__ */ new Date(),
|
|
76
|
+
emailError: errorMessage
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
async function claimExternalDelivery(em, payload) {
|
|
81
|
+
const claimTimestamp = /* @__PURE__ */ new Date();
|
|
82
|
+
const updatedRows = await em.nativeUpdate(
|
|
83
|
+
Message,
|
|
84
|
+
{
|
|
85
|
+
id: payload.messageId,
|
|
86
|
+
tenantId: payload.tenantId,
|
|
87
|
+
organizationId: payload.organizationId ?? null,
|
|
88
|
+
externalEmailSentAt: null
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
externalEmailSentAt: claimTimestamp,
|
|
92
|
+
externalEmailFailedAt: null,
|
|
93
|
+
externalEmailError: null
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
return updatedRows > 0 ? claimTimestamp : null;
|
|
97
|
+
}
|
|
98
|
+
async function releaseExternalClaim(em, payload, claimTimestamp, errorMessage) {
|
|
99
|
+
await em.nativeUpdate(
|
|
100
|
+
Message,
|
|
101
|
+
{
|
|
102
|
+
id: payload.messageId,
|
|
103
|
+
tenantId: payload.tenantId,
|
|
104
|
+
organizationId: payload.organizationId ?? null,
|
|
105
|
+
externalEmailSentAt: claimTimestamp
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
externalEmailSentAt: null,
|
|
109
|
+
externalEmailFailedAt: /* @__PURE__ */ new Date(),
|
|
110
|
+
externalEmailError: errorMessage
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
async function handle(job, ctx) {
|
|
115
|
+
const { payload } = job;
|
|
116
|
+
const em = ctx.resolve("em").fork();
|
|
117
|
+
const message = await resolveMessageScope(em, payload);
|
|
118
|
+
if (!message) {
|
|
119
|
+
console.error("[messages:send-email] Message not found", payload.messageId);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const objects = await em.find(MessageObject, { messageId: message.id });
|
|
123
|
+
const attachments = await getMessageEmailAttachments(
|
|
124
|
+
em,
|
|
125
|
+
message.id,
|
|
126
|
+
message.organizationId ?? null,
|
|
127
|
+
message.tenantId
|
|
128
|
+
);
|
|
129
|
+
const sender = await resolveSender(em, message);
|
|
130
|
+
if (payload.type === "external") {
|
|
131
|
+
const externalClaimTimestamp = await claimExternalDelivery(em, payload);
|
|
132
|
+
if (!externalClaimTimestamp) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
await sendMessageEmailToExternal({
|
|
137
|
+
message,
|
|
138
|
+
email: payload.email,
|
|
139
|
+
sender,
|
|
140
|
+
objects,
|
|
141
|
+
attachments
|
|
142
|
+
});
|
|
143
|
+
await emitEmailDeliveryEvent(ctx, "messages.message.email_sent", {
|
|
144
|
+
messageId: message.id,
|
|
145
|
+
target: "external",
|
|
146
|
+
email: payload.email,
|
|
147
|
+
tenantId: message.tenantId,
|
|
148
|
+
organizationId: message.organizationId ?? null
|
|
149
|
+
});
|
|
150
|
+
} catch (error) {
|
|
151
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
152
|
+
await releaseExternalClaim(
|
|
153
|
+
em,
|
|
154
|
+
payload,
|
|
155
|
+
externalClaimTimestamp,
|
|
156
|
+
errorMessage
|
|
157
|
+
);
|
|
158
|
+
await emitEmailDeliveryEvent(ctx, "messages.message.email_failed", {
|
|
159
|
+
messageId: message.id,
|
|
160
|
+
target: "external",
|
|
161
|
+
email: payload.email,
|
|
162
|
+
error: errorMessage,
|
|
163
|
+
tenantId: message.tenantId,
|
|
164
|
+
organizationId: message.organizationId ?? null
|
|
165
|
+
});
|
|
166
|
+
console.error("[messages:send-email] External email send failed", error);
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const recipientRecord = await em.findOne(MessageRecipient, {
|
|
171
|
+
messageId: payload.messageId,
|
|
172
|
+
recipientUserId: payload.recipientUserId
|
|
173
|
+
});
|
|
174
|
+
if (!recipientRecord) {
|
|
175
|
+
console.error("[messages:send-email] Recipient row not found", payload);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (recipientRecord.emailSentAt) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const recipientClaimTimestamp = await claimRecipientDelivery(em, payload);
|
|
182
|
+
if (!recipientClaimTimestamp) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const recipientUser = await findOneWithDecryption(
|
|
186
|
+
em,
|
|
187
|
+
User,
|
|
188
|
+
{
|
|
189
|
+
id: payload.recipientUserId,
|
|
190
|
+
tenantId: message.tenantId,
|
|
191
|
+
deletedAt: null
|
|
192
|
+
},
|
|
193
|
+
void 0,
|
|
194
|
+
{ tenantId: message.tenantId, organizationId: message.organizationId ?? null }
|
|
195
|
+
);
|
|
196
|
+
const recipientEmail = recipientUser?.email?.trim();
|
|
197
|
+
if (!recipientEmail) {
|
|
198
|
+
await releaseRecipientClaim(
|
|
199
|
+
em,
|
|
200
|
+
payload,
|
|
201
|
+
recipientClaimTimestamp,
|
|
202
|
+
"Recipient has no email address"
|
|
203
|
+
);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
await sendMessageEmailToRecipient({
|
|
208
|
+
em,
|
|
209
|
+
message,
|
|
210
|
+
recipientUserId: payload.recipientUserId,
|
|
211
|
+
recipientEmail,
|
|
212
|
+
sender,
|
|
213
|
+
objects,
|
|
214
|
+
attachments
|
|
215
|
+
});
|
|
216
|
+
await emitEmailDeliveryEvent(ctx, "messages.message.email_sent", {
|
|
217
|
+
messageId: message.id,
|
|
218
|
+
target: "recipient",
|
|
219
|
+
recipientUserId: payload.recipientUserId,
|
|
220
|
+
email: recipientEmail,
|
|
221
|
+
tenantId: message.tenantId,
|
|
222
|
+
organizationId: message.organizationId ?? null
|
|
223
|
+
});
|
|
224
|
+
} catch (error) {
|
|
225
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
226
|
+
await releaseRecipientClaim(
|
|
227
|
+
em,
|
|
228
|
+
payload,
|
|
229
|
+
recipientClaimTimestamp,
|
|
230
|
+
errorMessage
|
|
231
|
+
);
|
|
232
|
+
await emitEmailDeliveryEvent(ctx, "messages.message.email_failed", {
|
|
233
|
+
messageId: message.id,
|
|
234
|
+
target: "recipient",
|
|
235
|
+
recipientUserId: payload.recipientUserId,
|
|
236
|
+
email: recipientEmail,
|
|
237
|
+
error: errorMessage,
|
|
238
|
+
tenantId: message.tenantId,
|
|
239
|
+
organizationId: message.organizationId ?? null
|
|
240
|
+
});
|
|
241
|
+
console.error("[messages:send-email] Recipient email send failed", error);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
export {
|
|
245
|
+
MESSAGES_EMAIL_QUEUE_NAME,
|
|
246
|
+
claimExternalDelivery,
|
|
247
|
+
claimRecipientDelivery,
|
|
248
|
+
handle as default,
|
|
249
|
+
metadata,
|
|
250
|
+
releaseExternalClaim,
|
|
251
|
+
releaseRecipientClaim
|
|
252
|
+
};
|
|
253
|
+
//# sourceMappingURL=send-email.worker.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/messages/workers/send-email.worker.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { JobContext, QueuedJob, WorkerMeta } from '@open-mercato/queue'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { User } from '../../auth/data/entities'\nimport { Message, MessageObject, MessageRecipient } from '../data/entities'\nimport { emitMessagesEvent } from '../events'\nimport { getMessageEmailAttachments } from '../lib/attachments'\nimport {\n sendMessageEmailToExternal,\n sendMessageEmailToRecipient,\n} from '../lib/email-sender'\n\nexport const MESSAGES_EMAIL_QUEUE_NAME = 'messages-email'\n\nexport type SendMessageEmailToRecipientJob = {\n type: 'recipient'\n messageId: string\n recipientUserId: string\n tenantId: string\n organizationId?: string | null\n}\n\nexport type SendMessageEmailToExternalJob = {\n type: 'external'\n messageId: string\n email: string\n tenantId: string\n organizationId?: string | null\n}\n\nexport type SendMessageEmailJob = SendMessageEmailToRecipientJob | SendMessageEmailToExternalJob\n\nexport const metadata: WorkerMeta = {\n queue: MESSAGES_EMAIL_QUEUE_NAME,\n id: 'messages:send-email',\n concurrency: 10,\n}\n\ntype HandlerContext = {\n resolve: <T = unknown>(name: string) => T\n}\n\nasync function emitEmailDeliveryEvent(\n ctx: HandlerContext,\n eventId: 'messages.message.email_sent' | 'messages.message.email_failed',\n payload: {\n messageId: string\n target: 'recipient' | 'external'\n recipientUserId?: string\n email?: string\n error?: string\n tenantId: string\n organizationId?: string | null\n }\n) {\n const eventBus = ctx.resolve<{ emit?: unknown } | null>('eventBus')\n if (!eventBus || typeof eventBus !== 'object' || typeof (eventBus as { emit?: unknown }).emit !== 'function') {\n return\n }\n await emitMessagesEvent(eventId, payload, { persistent: true })\n}\n\nasync function resolveSender(em: EntityManager, message: Message) {\n const sender = await findOneWithDecryption(\n em,\n User,\n {\n id: message.senderUserId,\n tenantId: message.tenantId,\n deletedAt: null,\n },\n undefined,\n { tenantId: message.tenantId, organizationId: message.organizationId ?? null }\n )\n return {\n name: sender?.name ?? null,\n email: sender?.email ?? null,\n }\n}\n\nasync function resolveMessageScope(\n em: EntityManager,\n payload: SendMessageEmailJob\n) {\n return await em.findOne(Message, {\n id: payload.messageId,\n tenantId: payload.tenantId,\n organizationId: payload.organizationId ?? null,\n deletedAt: null,\n })\n}\n\nexport async function claimRecipientDelivery(\n em: EntityManager,\n payload: SendMessageEmailToRecipientJob,\n): Promise<Date | null> {\n const claimTimestamp = new Date()\n const updatedRows = await em.nativeUpdate(\n MessageRecipient,\n {\n messageId: payload.messageId,\n recipientUserId: payload.recipientUserId,\n emailSentAt: null,\n },\n {\n emailSentAt: claimTimestamp,\n emailFailedAt: null,\n emailError: null,\n },\n )\n return updatedRows > 0 ? claimTimestamp : null\n}\n\nexport async function releaseRecipientClaim(\n em: EntityManager,\n payload: SendMessageEmailToRecipientJob,\n claimTimestamp: Date,\n errorMessage: string,\n): Promise<void> {\n await em.nativeUpdate(\n MessageRecipient,\n {\n messageId: payload.messageId,\n recipientUserId: payload.recipientUserId,\n emailSentAt: claimTimestamp,\n },\n {\n emailSentAt: null,\n emailFailedAt: new Date(),\n emailError: errorMessage,\n },\n )\n}\n\nexport async function claimExternalDelivery(\n em: EntityManager,\n payload: SendMessageEmailToExternalJob,\n): Promise<Date | null> {\n const claimTimestamp = new Date()\n const updatedRows = await em.nativeUpdate(\n Message,\n {\n id: payload.messageId,\n tenantId: payload.tenantId,\n organizationId: payload.organizationId ?? null,\n externalEmailSentAt: null,\n },\n {\n externalEmailSentAt: claimTimestamp,\n externalEmailFailedAt: null,\n externalEmailError: null,\n },\n )\n return updatedRows > 0 ? claimTimestamp : null\n}\n\nexport async function releaseExternalClaim(\n em: EntityManager,\n payload: SendMessageEmailToExternalJob,\n claimTimestamp: Date,\n errorMessage: string,\n): Promise<void> {\n await em.nativeUpdate(\n Message,\n {\n id: payload.messageId,\n tenantId: payload.tenantId,\n organizationId: payload.organizationId ?? null,\n externalEmailSentAt: claimTimestamp,\n },\n {\n externalEmailSentAt: null,\n externalEmailFailedAt: new Date(),\n externalEmailError: errorMessage,\n },\n )\n}\n\nexport default async function handle(\n job: QueuedJob<SendMessageEmailJob>,\n ctx: JobContext & HandlerContext\n): Promise<void> {\n const { payload } = job\n const em = (ctx.resolve('em') as EntityManager).fork()\n\n const message = await resolveMessageScope(em, payload)\n if (!message) {\n console.error('[messages:send-email] Message not found', payload.messageId)\n return\n }\n\n const objects = await em.find(MessageObject, { messageId: message.id })\n const attachments = await getMessageEmailAttachments(\n em,\n message.id,\n message.organizationId ?? null,\n message.tenantId\n )\n const sender = await resolveSender(em, message)\n\n if (payload.type === 'external') {\n const externalClaimTimestamp = await claimExternalDelivery(em, payload)\n if (!externalClaimTimestamp) {\n return\n }\n\n try {\n await sendMessageEmailToExternal({\n message,\n email: payload.email,\n sender,\n objects,\n attachments,\n })\n await emitEmailDeliveryEvent(ctx, 'messages.message.email_sent', {\n messageId: message.id,\n target: 'external',\n email: payload.email,\n tenantId: message.tenantId,\n organizationId: message.organizationId ?? null,\n })\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n await releaseExternalClaim(\n em,\n payload,\n externalClaimTimestamp,\n errorMessage,\n )\n await emitEmailDeliveryEvent(ctx, 'messages.message.email_failed', {\n messageId: message.id,\n target: 'external',\n email: payload.email,\n error: errorMessage,\n tenantId: message.tenantId,\n organizationId: message.organizationId ?? null,\n })\n console.error('[messages:send-email] External email send failed', error)\n }\n return\n }\n\n const recipientRecord = await em.findOne(MessageRecipient, {\n messageId: payload.messageId,\n recipientUserId: payload.recipientUserId,\n })\n if (!recipientRecord) {\n console.error('[messages:send-email] Recipient row not found', payload)\n return\n }\n\n if (recipientRecord.emailSentAt) {\n return\n }\n\n const recipientClaimTimestamp = await claimRecipientDelivery(em, payload)\n if (!recipientClaimTimestamp) {\n return\n }\n\n const recipientUser = await findOneWithDecryption(\n em,\n User,\n {\n id: payload.recipientUserId,\n tenantId: message.tenantId,\n deletedAt: null,\n },\n undefined,\n { tenantId: message.tenantId, organizationId: message.organizationId ?? null }\n )\n\n const recipientEmail = recipientUser?.email?.trim()\n if (!recipientEmail) {\n await releaseRecipientClaim(\n em,\n payload,\n recipientClaimTimestamp,\n 'Recipient has no email address',\n )\n return\n }\n\n try {\n await sendMessageEmailToRecipient({\n em,\n message,\n recipientUserId: payload.recipientUserId,\n recipientEmail,\n sender,\n objects,\n attachments,\n })\n await emitEmailDeliveryEvent(ctx, 'messages.message.email_sent', {\n messageId: message.id,\n target: 'recipient',\n recipientUserId: payload.recipientUserId,\n email: recipientEmail,\n tenantId: message.tenantId,\n organizationId: message.organizationId ?? null,\n })\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n await releaseRecipientClaim(\n em,\n payload,\n recipientClaimTimestamp,\n errorMessage,\n )\n await emitEmailDeliveryEvent(ctx, 'messages.message.email_failed', {\n messageId: message.id,\n target: 'recipient',\n recipientUserId: payload.recipientUserId,\n email: recipientEmail,\n error: errorMessage,\n tenantId: message.tenantId,\n organizationId: message.organizationId ?? null,\n })\n console.error('[messages:send-email] Recipient email send failed', error)\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { useSearchParams, useRouter } from "next/navigation";
|
|
5
5
|
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
@@ -21,6 +21,7 @@ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, D
|
|
|
21
21
|
import { ArrowRightLeft, Building2, CreditCard, Mail, Pencil, Plus, Send, Store, Truck, UserRound, Wand2, X } from "lucide-react";
|
|
22
22
|
import { FormHeader } from "@open-mercato/ui/backend/forms";
|
|
23
23
|
import { VersionHistoryAction } from "@open-mercato/ui/backend/version-history";
|
|
24
|
+
import { SendObjectMessageDialog } from "@open-mercato/ui/backend/messages";
|
|
24
25
|
import Link from "next/link";
|
|
25
26
|
import { flash } from "@open-mercato/ui/backend/FlashMessages";
|
|
26
27
|
import { apiCall, apiCallOrThrow, readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
|
|
@@ -3664,16 +3665,34 @@ function SalesDocumentDetailPage({
|
|
|
3664
3665
|
mode: "detail",
|
|
3665
3666
|
backHref: kind === "order" ? "/backend/sales/orders" : "/backend/sales/quotes",
|
|
3666
3667
|
backLabel: t("sales.documents.detail.back", "Back to documents"),
|
|
3667
|
-
utilityActions: record ? /* @__PURE__ */
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3668
|
+
utilityActions: record ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3669
|
+
/* @__PURE__ */ jsx(
|
|
3670
|
+
SendObjectMessageDialog,
|
|
3671
|
+
{
|
|
3672
|
+
object: {
|
|
3673
|
+
entityModule: "sales",
|
|
3674
|
+
entityType: kind,
|
|
3675
|
+
entityId: record.id,
|
|
3676
|
+
sourceEntityType: kind === "order" ? "sales.order" : "sales.quote",
|
|
3677
|
+
sourceEntityId: record.id
|
|
3678
|
+
},
|
|
3679
|
+
defaultValues: {
|
|
3680
|
+
sourceEntityType: kind === "order" ? "sales.order" : "sales.quote",
|
|
3681
|
+
sourceEntityId: record.id
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3684
|
+
),
|
|
3685
|
+
/* @__PURE__ */ jsx(
|
|
3686
|
+
VersionHistoryAction,
|
|
3687
|
+
{
|
|
3688
|
+
config: {
|
|
3689
|
+
resourceKind: kind === "order" ? "sales.order" : "sales.quote",
|
|
3690
|
+
resourceId: record.id
|
|
3691
|
+
},
|
|
3692
|
+
t
|
|
3693
|
+
}
|
|
3694
|
+
)
|
|
3695
|
+
] }) : null,
|
|
3677
3696
|
entityTypeLabel: kind === "order" ? t("sales.documents.detail.order", "Sales order") : t("sales.documents.detail.quote", "Sales quote"),
|
|
3678
3697
|
title: canEditNumber ? /* @__PURE__ */ jsx(
|
|
3679
3698
|
InlineTextEditor,
|