@open-mercato/core 0.4.5-develop-5191db4ef3 → 0.4.5-develop-033a719bf2
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,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/messages/commands/messages.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { z } from 'zod'\nimport { registerCommand, type CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { extractUndoPayload, type UndoPayload } from '@open-mercato/shared/lib/commands/undo'\nimport { Message, MessageObject, MessageRecipient, type MessageActionData } from '../data/entities'\nimport { emitMessagesEvent } from '../events'\nimport {\n composeMessageSchema,\n forwardMessageSchema,\n replyMessageSchema,\n updateDraftSchema,\n} from '../data/validators'\nimport { linkAttachmentsToMessage, linkLibraryAttachmentsToMessage, copyAttachmentsForForwardMessages } from '../lib/attachments'\nimport { MESSAGE_ATTACHMENT_ENTITY_ID } from '../lib/constants'\nimport { getMessageTypeOrDefault } from '../lib/message-types-registry'\nimport { validateMessageObjectsForType } from '../lib/object-validation'\nimport { buildForwardBodyFromLegacyInput, buildForwardPreviewFromThreadSlice, buildForwardThreadSlice } from '../lib/forwarding'\nimport {\n assertOrganizationAccess,\n loadMessageAggregateSnapshot,\n restoreMessageAggregateSnapshot,\n type MessageAggregateSnapshot,\n type MessageScopeInput,\n} from './shared'\n\ntype MessageSentEventPayload = {\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 ContainerWithResolve = {\n resolve: (name: string) => unknown\n}\n\nasync function emitMessageSentEvent(_container: ContainerWithResolve, payload: MessageSentEventPayload) {\n await emitMessagesEvent('messages.message.sent', payload, { persistent: true })\n}\n\nasync function emitMessageDeletedEvent(_container: ContainerWithResolve, payload: {\n messageId: string\n actorUserId: string\n target: 'sender' | 'recipient'\n tenantId: string\n organizationId: string | null\n}) {\n await emitMessagesEvent('messages.message.deleted', payload, { persistent: true })\n}\n\nconst scopeSchema = z.object({\n tenantId: z.string().uuid(),\n organizationId: z.string().uuid().nullable(),\n userId: z.string().uuid(),\n})\n\nconst composeCommandSchema = composeMessageSchema.safeExtend({\n tenantId: scopeSchema.shape.tenantId,\n organizationId: scopeSchema.shape.organizationId,\n userId: scopeSchema.shape.userId,\n})\n\nconst updateDraftCommandSchema = updateDraftSchema.safeExtend({\n messageId: z.string().uuid(),\n tenantId: scopeSchema.shape.tenantId,\n organizationId: scopeSchema.shape.organizationId,\n userId: scopeSchema.shape.userId,\n})\n\nconst replyCommandSchema = replyMessageSchema.safeExtend({\n messageId: z.string().uuid(),\n tenantId: scopeSchema.shape.tenantId,\n organizationId: scopeSchema.shape.organizationId,\n userId: scopeSchema.shape.userId,\n})\n\nconst forwardCommandSchema = forwardMessageSchema.safeExtend({\n messageId: z.string().uuid(),\n tenantId: scopeSchema.shape.tenantId,\n organizationId: scopeSchema.shape.organizationId,\n userId: scopeSchema.shape.userId,\n})\n\nconst deleteForActorCommandSchema = z.object({\n messageId: z.string().uuid(),\n tenantId: scopeSchema.shape.tenantId,\n organizationId: scopeSchema.shape.organizationId,\n userId: scopeSchema.shape.userId,\n})\n\ntype ComposeCommandInput = z.infer<typeof composeCommandSchema>\ntype UpdateDraftCommandInput = z.infer<typeof updateDraftCommandSchema>\ntype ReplyCommandInput = z.infer<typeof replyCommandSchema>\ntype ForwardCommandInput = z.infer<typeof forwardCommandSchema>\ntype DeleteForActorCommandInput = z.infer<typeof deleteForActorCommandSchema>\n\ntype MessageDeleteUndoState = {\n messageId: string\n messageDeletedAt: string | null\n recipientId: string | null\n recipientStatus: 'unread' | 'read' | 'archived' | 'deleted' | null\n recipientDeletedAt: string | null\n}\n\nfunction toIso(value: Date | null | undefined): string | null {\n return value ? value.toISOString() : null\n}\n\nfunction toDate(value: string | null | undefined): Date | null {\n if (!value) return null\n return new Date(value)\n}\n\nfunction buildReplySubject(subject: string): string {\n if (/^re:\\s*/i.test(subject)) return subject\n return `Re: ${subject}`\n}\n\nasync function requireMessageById(\n em: EntityManager,\n scope: MessageScopeInput,\n messageId: string,\n) {\n const message = await em.findOne(Message, {\n id: messageId,\n tenantId: scope.tenantId,\n deletedAt: null,\n })\n if (!message) throw new Error('Message not found')\n assertOrganizationAccess(scope, message)\n return message\n}\n\nconst composeMessageCommand: CommandHandler<unknown, { id: string; threadId: string | null; externalEmail: string | null; isDraft: boolean; recipientUserIds: string[] }> = {\n id: 'messages.messages.compose',\n async execute(rawInput, ctx) {\n const input = composeCommandSchema.parse(rawInput)\n if (input.objects?.length) {\n const objectValidationError = validateMessageObjectsForType(input.type, input.objects)\n if (objectValidationError) throw new Error(objectValidationError)\n }\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let messageId = ''\n let responseThreadId: string | null = null\n let responseExternalEmail: string | null = null\n\n await em.transactional(async (trx) => {\n const threadId = input.parentMessageId\n ? (\n await trx.findOne(Message, {\n id: input.parentMessageId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n })\n )?.threadId ?? input.parentMessageId\n : undefined\n\n const isPublicVisibility = input.visibility === 'public'\n const sendViaEmail = isPublicVisibility ? true : input.sendViaEmail\n const message = trx.create(Message, {\n type: input.type,\n visibility: input.visibility ?? null,\n sourceEntityType: input.sourceEntityType,\n sourceEntityId: input.sourceEntityId,\n externalEmail: input.externalEmail,\n externalName: input.externalName,\n threadId: threadId ?? undefined,\n parentMessageId: input.parentMessageId,\n senderUserId: input.userId,\n subject: input.subject,\n body: input.body,\n bodyFormat: input.bodyFormat,\n priority: input.priority,\n status: input.isDraft ? 'draft' : 'sent',\n isDraft: input.isDraft ?? false,\n sentAt: input.isDraft ? null : new Date(),\n actionData: input.actionData as MessageActionData | undefined,\n sendViaEmail,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n\n await trx.persistAndFlush(message)\n if (!threadId && !input.isDraft && !message.threadId) {\n message.threadId = message.id\n await trx.flush()\n }\n\n for (const recipient of input.recipients) {\n trx.persist(trx.create(MessageRecipient, {\n messageId: message.id,\n recipientUserId: recipient.userId,\n recipientType: recipient.type,\n status: 'unread',\n }))\n }\n\n if (input.objects) {\n for (const obj of input.objects) {\n trx.persist(trx.create(MessageObject, {\n messageId: message.id,\n entityModule: obj.entityModule,\n entityType: obj.entityType,\n entityId: obj.entityId,\n actionRequired: obj.actionRequired,\n actionType: obj.actionType,\n actionLabel: obj.actionLabel,\n }))\n }\n }\n\n await trx.flush()\n\n if (input.attachmentIds?.length) {\n await linkAttachmentsToMessage(\n trx,\n message.id,\n input.attachmentIds,\n input.organizationId,\n input.tenantId,\n )\n }\n\n if (input.attachmentRecordId) {\n await linkLibraryAttachmentsToMessage(\n trx,\n message.id,\n input.attachmentRecordId,\n input.organizationId,\n input.tenantId,\n )\n }\n\n messageId = message.id\n responseThreadId = message.threadId ?? null\n responseExternalEmail = message.externalEmail ?? null\n })\n\n if (!input.isDraft) {\n await emitMessageSentEvent(ctx.container, {\n messageId,\n senderUserId: input.userId,\n recipientUserIds: input.recipients.map((recipient) => recipient.userId),\n sendViaEmail: input.visibility === 'public' ? true : input.sendViaEmail,\n externalEmail: responseExternalEmail,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n }\n\n return {\n id: messageId,\n threadId: responseThreadId,\n externalEmail: responseExternalEmail,\n isDraft: input.isDraft,\n recipientUserIds: input.recipients.map((recipient) => recipient.userId),\n }\n },\n async captureAfter(_input, result, ctx) {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadMessageAggregateSnapshot(em, result.id)\n },\n buildLog: async ({ input, result, snapshots }) => {\n const parsed = composeCommandSchema.parse(input)\n return {\n actionLabel: parsed.isDraft ? 'Create draft message' : 'Compose message',\n resourceKind: 'messages.message',\n resourceId: result.id,\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n payload: {\n undo: {\n after: (snapshots.after as MessageAggregateSnapshot | undefined) ?? null,\n } satisfies UndoPayload<MessageAggregateSnapshot>,\n },\n snapshotAfter: snapshots.after ?? null,\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<UndoPayload<MessageAggregateSnapshot>>(logEntry)\n const after = undo?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const message = await em.findOne(Message, { id: after.message.id })\n if (!message) return\n message.deletedAt = new Date()\n await em.flush()\n },\n}\n\nconst updateDraftCommand: CommandHandler<unknown, { ok: true; id: string }> = {\n id: 'messages.messages.update_draft',\n async prepare(rawInput, ctx) {\n const input = updateDraftCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadMessageAggregateSnapshot(em, input.messageId, {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const input = updateDraftCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const message = await requireMessageById(em, input, input.messageId)\n\n if (message.senderUserId !== input.userId) throw new Error('Access denied')\n if (!message.isDraft) throw new Error('Only draft messages can be edited')\n\n const nextMessageType = input.type ?? message.type\n if (input.objects) {\n const objectValidationError = validateMessageObjectsForType(nextMessageType, input.objects)\n if (objectValidationError) throw new Error(objectValidationError)\n } else if (input.type !== undefined) {\n const existingObjects = await em.find(MessageObject, { messageId: message.id })\n if (existingObjects.length > 0) {\n const objectValidationError = validateMessageObjectsForType(\n nextMessageType,\n existingObjects.map((item) => ({\n entityModule: item.entityModule,\n entityType: item.entityType,\n entityId: item.entityId,\n })),\n )\n if (objectValidationError) throw new Error(objectValidationError)\n }\n }\n\n if (input.type !== undefined) message.type = input.type\n if (input.visibility !== undefined) message.visibility = input.visibility\n if (input.sourceEntityType !== undefined) message.sourceEntityType = input.sourceEntityType\n if (input.sourceEntityId !== undefined) message.sourceEntityId = input.sourceEntityId\n if (input.externalEmail !== undefined) message.externalEmail = input.externalEmail\n if (input.externalName !== undefined) message.externalName = input.externalName\n if (input.subject !== undefined) message.subject = input.subject\n if (input.body !== undefined) message.body = input.body\n if (input.bodyFormat !== undefined) message.bodyFormat = input.bodyFormat\n if (input.priority !== undefined) message.priority = input.priority\n if (input.actionData !== undefined) message.actionData = input.actionData\n if (input.sendViaEmail !== undefined) message.sendViaEmail = input.sendViaEmail\n\n if (input.recipients) {\n await em.nativeDelete(MessageRecipient, { messageId: message.id })\n for (const recipient of input.recipients) {\n em.persist(em.create(MessageRecipient, {\n messageId: message.id,\n recipientUserId: recipient.userId,\n recipientType: recipient.type,\n status: 'unread',\n }))\n }\n }\n\n if (input.objects) {\n await em.nativeDelete(MessageObject, { messageId: message.id })\n for (const object of input.objects) {\n em.persist(em.create(MessageObject, {\n messageId: message.id,\n entityModule: object.entityModule,\n entityType: object.entityType,\n entityId: object.entityId,\n actionRequired: object.actionRequired,\n actionType: object.actionType,\n actionLabel: object.actionLabel,\n }))\n }\n }\n\n if (input.attachmentIds) {\n const { Attachment } = await import('@open-mercato/core/modules/attachments/data/entities')\n if (input.attachmentIds.length === 0) {\n await em.nativeDelete(Attachment, {\n entityId: MESSAGE_ATTACHMENT_ENTITY_ID,\n recordId: message.id,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n } else {\n await em.nativeDelete(Attachment, {\n entityId: MESSAGE_ATTACHMENT_ENTITY_ID,\n recordId: message.id,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n id: { $nin: input.attachmentIds },\n })\n }\n await linkAttachmentsToMessage(\n em,\n message.id,\n input.attachmentIds,\n input.organizationId,\n input.tenantId,\n )\n }\n\n await em.flush()\n return { ok: true, id: message.id }\n },\n async captureAfter(rawInput, _result, ctx) {\n const input = updateDraftCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadMessageAggregateSnapshot(em, input.messageId, {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n },\n buildLog: async ({ input, snapshots }) => {\n const parsed = updateDraftCommandSchema.parse(input)\n return {\n actionLabel: 'Update draft message',\n resourceKind: 'messages.message',\n resourceId: parsed.messageId,\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n payload: {\n undo: {\n before: (snapshots.before as MessageAggregateSnapshot | undefined) ?? null,\n after: (snapshots.after as MessageAggregateSnapshot | undefined) ?? null,\n } satisfies UndoPayload<MessageAggregateSnapshot>,\n },\n snapshotBefore: snapshots.before ?? null,\n snapshotAfter: snapshots.after ?? null,\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<UndoPayload<MessageAggregateSnapshot>>(logEntry)\n const before = undo?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await restoreMessageAggregateSnapshot(em, before)\n },\n}\n\nconst replyMessageCommand: CommandHandler<unknown, { id: string; externalEmail: string | null; recipientUserIds: string[] }> = {\n id: 'messages.messages.reply',\n async execute(rawInput, ctx) {\n const input = replyCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const original = await requireMessageById(em, input, input.messageId)\n const ownRecipient = await em.findOne(MessageRecipient, {\n messageId: original.id,\n recipientUserId: input.userId,\n deletedAt: null,\n })\n if (original.senderUserId !== input.userId && !ownRecipient) throw new Error('Access denied')\n\n const messageType = getMessageTypeOrDefault(original.type)\n if (messageType.allowReply === false) throw new Error('Reply is not allowed for this message type')\n\n const recipientIds = new Set(\n (input.recipients ?? [])\n .map((recipient) => recipient.userId)\n .filter((recipientUserId) => recipientUserId !== input.userId),\n )\n\n if (recipientIds.size === 0) {\n const originalRecipients = await em.find(MessageRecipient, { messageId: original.id, deletedAt: null })\n if (input.replyAll) {\n if (original.senderUserId !== input.userId) recipientIds.add(original.senderUserId)\n for (const recipient of originalRecipients) {\n if (recipient.recipientUserId !== input.userId) recipientIds.add(recipient.recipientUserId)\n }\n } else if (original.senderUserId !== input.userId) {\n recipientIds.add(original.senderUserId)\n } else {\n for (const recipient of originalRecipients) {\n if (recipient.recipientUserId !== input.userId) {\n recipientIds.add(recipient.recipientUserId)\n break\n }\n }\n }\n }\n if (recipientIds.size === 0) throw new Error('No recipients available for reply')\n\n let messageId = ''\n let responseExternalEmail: string | null = null\n await em.transactional(async (trx) => {\n const message = trx.create(Message, {\n type: original.type,\n visibility: original.visibility ?? null,\n sourceEntityType: original.sourceEntityType,\n sourceEntityId: original.sourceEntityId,\n externalEmail: original.externalEmail,\n externalName: original.externalName,\n threadId: original.threadId ?? original.id,\n parentMessageId: original.id,\n senderUserId: input.userId,\n subject: buildReplySubject(original.subject),\n body: input.body,\n bodyFormat: input.bodyFormat,\n priority: original.priority,\n status: 'sent',\n isDraft: false,\n sentAt: new Date(),\n sendViaEmail: input.sendViaEmail,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n await trx.persistAndFlush(message)\n for (const recipientUserId of recipientIds) {\n trx.persist(trx.create(MessageRecipient, {\n messageId: message.id,\n recipientUserId,\n recipientType: 'to',\n status: 'unread',\n }))\n }\n await trx.flush()\n if (input.attachmentIds?.length) {\n await linkAttachmentsToMessage(\n trx,\n message.id,\n input.attachmentIds,\n input.organizationId,\n input.tenantId,\n )\n }\n if (input.attachmentRecordId) {\n await linkLibraryAttachmentsToMessage(\n trx,\n message.id,\n input.attachmentRecordId,\n input.organizationId,\n input.tenantId,\n )\n }\n messageId = message.id\n responseExternalEmail = message.externalEmail ?? null\n })\n\n await emitMessageSentEvent(ctx.container, {\n messageId,\n senderUserId: input.userId,\n recipientUserIds: Array.from(recipientIds),\n sendViaEmail: input.sendViaEmail,\n externalEmail: responseExternalEmail,\n replyTo: original.id,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n\n return {\n id: messageId,\n externalEmail: responseExternalEmail,\n recipientUserIds: Array.from(recipientIds),\n }\n },\n async captureAfter(_input, result, ctx) {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadMessageAggregateSnapshot(em, result.id)\n },\n buildLog: async ({ input, result, snapshots }) => {\n const parsed = replyCommandSchema.parse(input)\n return {\n actionLabel: 'Reply to message',\n resourceKind: 'messages.message',\n resourceId: result.id,\n parentResourceKind: 'messages.message',\n parentResourceId: parsed.messageId,\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n payload: {\n undo: {\n after: (snapshots.after as MessageAggregateSnapshot | undefined) ?? null,\n } satisfies UndoPayload<MessageAggregateSnapshot>,\n },\n snapshotAfter: snapshots.after ?? null,\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<UndoPayload<MessageAggregateSnapshot>>(logEntry)\n const after = undo?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const message = await em.findOne(Message, { id: after.message.id })\n if (!message) return\n message.deletedAt = new Date()\n await em.flush()\n },\n}\n\nconst forwardMessageCommand: CommandHandler<unknown, { id: string; externalEmail: string | null; recipientUserIds: string[] }> = {\n id: 'messages.messages.forward',\n async execute(rawInput, ctx) {\n const input = forwardCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const original = await requireMessageById(em, input, input.messageId)\n const isRecipient = await em.findOne(MessageRecipient, {\n messageId: input.messageId,\n recipientUserId: input.userId,\n deletedAt: null,\n })\n if (original.senderUserId !== input.userId && !isRecipient) throw new Error('Access denied')\n\n const messageType = getMessageTypeOrDefault(original.type)\n if (messageType.allowForward === false) throw new Error('Forward is not allowed for this message type')\n\n const originalObjects = await em.find(MessageObject, { messageId: input.messageId })\n const forwardThreadSlice = await buildForwardThreadSlice(em, {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n userId: input.userId,\n }, original)\n const generatedPreview = await buildForwardPreviewFromThreadSlice(em, {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n userId: input.userId,\n }, original, forwardThreadSlice)\n const forwardedBody = typeof input.body === 'string'\n ? input.body\n : buildForwardBodyFromLegacyInput(generatedPreview.body, input.additionalBody)\n let newMessageId = ''\n let responseExternalEmail: string | null = null\n await em.transactional(async (trx) => {\n const newMessage = trx.create(Message, {\n type: original.type,\n visibility: original.visibility ?? null,\n sourceEntityType: original.sourceEntityType,\n sourceEntityId: original.sourceEntityId,\n externalEmail: original.externalEmail,\n externalName: original.externalName,\n threadId: original.threadId ?? original.id,\n parentMessageId: original.id,\n senderUserId: input.userId,\n subject: `Fwd: ${original.subject}`,\n body: forwardedBody,\n bodyFormat: original.bodyFormat,\n priority: original.priority,\n status: 'sent',\n isDraft: false,\n sentAt: new Date(),\n sendViaEmail: input.sendViaEmail,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n await trx.persistAndFlush(newMessage)\n for (const recipient of input.recipients) {\n trx.persist(trx.create(MessageRecipient, {\n messageId: newMessage.id,\n recipientUserId: recipient.userId,\n recipientType: recipient.type,\n status: 'unread',\n }))\n }\n for (const obj of originalObjects) {\n trx.persist(trx.create(MessageObject, {\n messageId: newMessage.id,\n entityModule: obj.entityModule,\n entityType: obj.entityType,\n entityId: obj.entityId,\n actionRequired: obj.actionRequired,\n actionType: obj.actionType,\n actionLabel: obj.actionLabel,\n entitySnapshot: obj.entitySnapshot,\n }))\n }\n await trx.flush()\n if (input.includeAttachments !== false) {\n await copyAttachmentsForForwardMessages(\n trx,\n forwardThreadSlice.map((item) => item.id),\n newMessage.id,\n input.organizationId,\n input.tenantId,\n )\n }\n newMessageId = newMessage.id\n responseExternalEmail = newMessage.externalEmail ?? null\n })\n\n await emitMessageSentEvent(ctx.container, {\n messageId: newMessageId,\n senderUserId: input.userId,\n recipientUserIds: input.recipients.map((item) => item.userId),\n sendViaEmail: input.sendViaEmail,\n externalEmail: responseExternalEmail,\n forwardedFrom: original.id,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n\n return {\n id: newMessageId,\n externalEmail: responseExternalEmail,\n recipientUserIds: input.recipients.map((item) => item.userId),\n }\n },\n async captureAfter(_input, result, ctx) {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadMessageAggregateSnapshot(em, result.id)\n },\n buildLog: async ({ input, result, snapshots }) => {\n const parsed = forwardCommandSchema.parse(input)\n return {\n actionLabel: 'Forward message',\n resourceKind: 'messages.message',\n resourceId: result.id,\n parentResourceKind: 'messages.message',\n parentResourceId: parsed.messageId,\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n payload: {\n undo: {\n after: (snapshots.after as MessageAggregateSnapshot | undefined) ?? null,\n } satisfies UndoPayload<MessageAggregateSnapshot>,\n },\n snapshotAfter: snapshots.after ?? null,\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<UndoPayload<MessageAggregateSnapshot>>(logEntry)\n const after = undo?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const message = await em.findOne(Message, { id: after.message.id })\n if (!message) return\n message.deletedAt = new Date()\n await em.flush()\n },\n}\n\nconst deleteForActorCommand: CommandHandler<unknown, { ok: true }> = {\n id: 'messages.messages.delete_for_actor',\n async prepare(rawInput, ctx) {\n const input = deleteForActorCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const message = await requireMessageById(em, input, input.messageId)\n const recipient = await em.findOne(MessageRecipient, {\n messageId: input.messageId,\n recipientUserId: input.userId,\n deletedAt: null,\n })\n return {\n before: {\n messageId: message.id,\n messageDeletedAt: toIso(message.deletedAt),\n recipientId: recipient?.id ?? null,\n recipientStatus: recipient?.status ?? null,\n recipientDeletedAt: toIso(recipient?.deletedAt),\n } satisfies MessageDeleteUndoState,\n }\n },\n async execute(rawInput, ctx) {\n const input = deleteForActorCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const message = await requireMessageById(em, input, input.messageId)\n const recipient = await em.findOne(MessageRecipient, {\n messageId: input.messageId,\n recipientUserId: input.userId,\n deletedAt: null,\n })\n if (recipient) {\n recipient.status = 'deleted'\n recipient.deletedAt = new Date()\n await em.flush()\n await emitMessageDeletedEvent(ctx.container, {\n messageId: input.messageId,\n actorUserId: input.userId,\n target: 'recipient',\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n return { ok: true }\n }\n if (message.senderUserId === input.userId) {\n message.deletedAt = new Date()\n await em.flush()\n await emitMessageDeletedEvent(ctx.container, {\n messageId: input.messageId,\n actorUserId: input.userId,\n target: 'sender',\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n })\n return { ok: true }\n }\n throw new Error('Access denied')\n },\n async captureAfter(rawInput, _result, ctx) {\n const input = deleteForActorCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const message = await em.findOne(Message, { id: input.messageId, tenantId: input.tenantId })\n const recipient = await em.findOne(MessageRecipient, {\n messageId: input.messageId,\n recipientUserId: input.userId,\n })\n return {\n messageId: input.messageId,\n messageDeletedAt: toIso(message?.deletedAt),\n recipientId: recipient?.id ?? null,\n recipientStatus: recipient?.status ?? null,\n recipientDeletedAt: toIso(recipient?.deletedAt),\n } satisfies MessageDeleteUndoState\n },\n buildLog: async ({ input, snapshots }) => {\n const parsed = deleteForActorCommandSchema.parse(input)\n return {\n actionLabel: 'Delete message for actor',\n resourceKind: 'messages.message',\n resourceId: parsed.messageId,\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n payload: {\n undo: {\n before: (snapshots.before as MessageDeleteUndoState | undefined) ?? null,\n after: (snapshots.after as MessageDeleteUndoState | undefined) ?? null,\n } satisfies UndoPayload<MessageDeleteUndoState>,\n },\n snapshotBefore: snapshots.before ?? null,\n snapshotAfter: snapshots.after ?? null,\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<UndoPayload<MessageDeleteUndoState>>(logEntry)\n const before = undo?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const message = await em.findOne(Message, { id: before.messageId })\n if (message) {\n message.deletedAt = toDate(before.messageDeletedAt)\n }\n if (before.recipientId) {\n const recipient = await em.findOne(MessageRecipient, { id: before.recipientId })\n if (recipient) {\n recipient.status = (before.recipientStatus ?? 'unread') as MessageRecipient['status']\n recipient.deletedAt = toDate(before.recipientDeletedAt)\n }\n }\n await em.flush()\n },\n}\n\nregisterCommand(composeMessageCommand)\nregisterCommand(updateDraftCommand)\nregisterCommand(replyMessageCommand)\nregisterCommand(forwardMessageCommand)\nregisterCommand(deleteForActorCommand)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { registerCommand } from "@open-mercato/shared/lib/commands";
|
|
3
|
+
import { extractUndoPayload } from "@open-mercato/shared/lib/commands/undo";
|
|
4
|
+
import { Message, MessageRecipient } from "../data/entities.js";
|
|
5
|
+
import { emitMessagesEvent } from "../events.js";
|
|
6
|
+
import { assertOrganizationAccess } from "./shared.js";
|
|
7
|
+
const recipientMutationSchema = z.object({
|
|
8
|
+
messageId: z.string().uuid(),
|
|
9
|
+
tenantId: z.string().uuid(),
|
|
10
|
+
organizationId: z.string().uuid().nullable(),
|
|
11
|
+
userId: z.string().uuid()
|
|
12
|
+
});
|
|
13
|
+
function toIso(value) {
|
|
14
|
+
return value ? value.toISOString() : null;
|
|
15
|
+
}
|
|
16
|
+
function toDate(value) {
|
|
17
|
+
if (!value) return null;
|
|
18
|
+
return new Date(value);
|
|
19
|
+
}
|
|
20
|
+
async function loadRecipientForMutation(em, input) {
|
|
21
|
+
const message = await em.findOne(Message, {
|
|
22
|
+
id: input.messageId,
|
|
23
|
+
tenantId: input.tenantId,
|
|
24
|
+
deletedAt: null
|
|
25
|
+
});
|
|
26
|
+
if (!message) throw new Error("Message not found");
|
|
27
|
+
assertOrganizationAccess(input, message);
|
|
28
|
+
const recipient = await em.findOne(MessageRecipient, {
|
|
29
|
+
messageId: input.messageId,
|
|
30
|
+
recipientUserId: input.userId,
|
|
31
|
+
deletedAt: null
|
|
32
|
+
});
|
|
33
|
+
if (!recipient) throw new Error("Access denied");
|
|
34
|
+
return { message, recipient };
|
|
35
|
+
}
|
|
36
|
+
function snapshotRecipient(recipient) {
|
|
37
|
+
return {
|
|
38
|
+
id: recipient.id,
|
|
39
|
+
messageId: recipient.messageId,
|
|
40
|
+
recipientUserId: recipient.recipientUserId,
|
|
41
|
+
recipientType: recipient.recipientType,
|
|
42
|
+
status: recipient.status,
|
|
43
|
+
readAt: toIso(recipient.readAt),
|
|
44
|
+
archivedAt: toIso(recipient.archivedAt),
|
|
45
|
+
deletedAt: toIso(recipient.deletedAt)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function buildLog(actionLabel, payload, input) {
|
|
49
|
+
return {
|
|
50
|
+
actionLabel,
|
|
51
|
+
resourceKind: "messages.message",
|
|
52
|
+
resourceId: input.messageId,
|
|
53
|
+
tenantId: input.tenantId,
|
|
54
|
+
organizationId: input.organizationId,
|
|
55
|
+
payload: { undo: payload },
|
|
56
|
+
snapshotBefore: payload.before ?? null,
|
|
57
|
+
snapshotAfter: payload.after ?? null
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function applyRecipientSnapshot(recipient, snapshot) {
|
|
61
|
+
recipient.status = snapshot.status;
|
|
62
|
+
recipient.readAt = toDate(snapshot.readAt);
|
|
63
|
+
recipient.archivedAt = toDate(snapshot.archivedAt);
|
|
64
|
+
recipient.deletedAt = toDate(snapshot.deletedAt);
|
|
65
|
+
}
|
|
66
|
+
async function emitRecipientMutationEvent(eventId, input) {
|
|
67
|
+
await emitMessagesEvent(
|
|
68
|
+
eventId,
|
|
69
|
+
{
|
|
70
|
+
messageId: input.messageId,
|
|
71
|
+
recipientUserId: input.userId,
|
|
72
|
+
userId: input.userId,
|
|
73
|
+
tenantId: input.tenantId,
|
|
74
|
+
organizationId: input.organizationId
|
|
75
|
+
},
|
|
76
|
+
{ persistent: true }
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
const markReadCommand = {
|
|
80
|
+
id: "messages.recipients.mark_read",
|
|
81
|
+
async prepare(rawInput, ctx) {
|
|
82
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
83
|
+
const em = ctx.container.resolve("em").fork();
|
|
84
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
85
|
+
return { before: snapshotRecipient(recipient) };
|
|
86
|
+
},
|
|
87
|
+
async execute(rawInput, ctx) {
|
|
88
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
89
|
+
const em = ctx.container.resolve("em").fork();
|
|
90
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
91
|
+
if (recipient.status !== "read") {
|
|
92
|
+
recipient.status = "read";
|
|
93
|
+
recipient.readAt = /* @__PURE__ */ new Date();
|
|
94
|
+
await em.flush();
|
|
95
|
+
await emitRecipientMutationEvent("messages.message.read", input);
|
|
96
|
+
}
|
|
97
|
+
return { ok: true };
|
|
98
|
+
},
|
|
99
|
+
async captureAfter(rawInput, _result, ctx) {
|
|
100
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
101
|
+
const em = ctx.container.resolve("em").fork();
|
|
102
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
103
|
+
return snapshotRecipient(recipient);
|
|
104
|
+
},
|
|
105
|
+
async buildLog({ input, snapshots }) {
|
|
106
|
+
const parsed = recipientMutationSchema.parse(input);
|
|
107
|
+
return buildLog("Mark message as read", {
|
|
108
|
+
before: snapshots.before ?? null,
|
|
109
|
+
after: snapshots.after ?? null
|
|
110
|
+
}, parsed);
|
|
111
|
+
},
|
|
112
|
+
undo: async ({ logEntry, ctx }) => {
|
|
113
|
+
const undo = extractUndoPayload(logEntry);
|
|
114
|
+
const before = undo?.before;
|
|
115
|
+
if (!before) return;
|
|
116
|
+
const em = ctx.container.resolve("em").fork();
|
|
117
|
+
const recipient = await em.findOne(MessageRecipient, { id: before.id });
|
|
118
|
+
if (!recipient) return;
|
|
119
|
+
applyRecipientSnapshot(recipient, before);
|
|
120
|
+
await em.flush();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const markUnreadCommand = {
|
|
124
|
+
id: "messages.recipients.mark_unread",
|
|
125
|
+
async prepare(rawInput, ctx) {
|
|
126
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
127
|
+
const em = ctx.container.resolve("em").fork();
|
|
128
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
129
|
+
return { before: snapshotRecipient(recipient) };
|
|
130
|
+
},
|
|
131
|
+
async execute(rawInput, ctx) {
|
|
132
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
133
|
+
const em = ctx.container.resolve("em").fork();
|
|
134
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
135
|
+
if (recipient.status !== "unread" || recipient.readAt !== null) {
|
|
136
|
+
recipient.status = "unread";
|
|
137
|
+
recipient.readAt = null;
|
|
138
|
+
await em.flush();
|
|
139
|
+
await emitRecipientMutationEvent("messages.message.marked_unread", input);
|
|
140
|
+
}
|
|
141
|
+
return { ok: true };
|
|
142
|
+
},
|
|
143
|
+
async captureAfter(rawInput, _result, ctx) {
|
|
144
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
145
|
+
const em = ctx.container.resolve("em").fork();
|
|
146
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
147
|
+
return snapshotRecipient(recipient);
|
|
148
|
+
},
|
|
149
|
+
async buildLog({ input, snapshots }) {
|
|
150
|
+
const parsed = recipientMutationSchema.parse(input);
|
|
151
|
+
return buildLog("Mark message as unread", {
|
|
152
|
+
before: snapshots.before ?? null,
|
|
153
|
+
after: snapshots.after ?? null
|
|
154
|
+
}, parsed);
|
|
155
|
+
},
|
|
156
|
+
undo: async ({ logEntry, ctx }) => {
|
|
157
|
+
const undo = extractUndoPayload(logEntry);
|
|
158
|
+
const before = undo?.before;
|
|
159
|
+
if (!before) return;
|
|
160
|
+
const em = ctx.container.resolve("em").fork();
|
|
161
|
+
const recipient = await em.findOne(MessageRecipient, { id: before.id });
|
|
162
|
+
if (!recipient) return;
|
|
163
|
+
applyRecipientSnapshot(recipient, before);
|
|
164
|
+
await em.flush();
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const archiveRecipientCommand = {
|
|
168
|
+
id: "messages.recipients.archive",
|
|
169
|
+
async prepare(rawInput, ctx) {
|
|
170
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
171
|
+
const em = ctx.container.resolve("em").fork();
|
|
172
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
173
|
+
return { before: snapshotRecipient(recipient) };
|
|
174
|
+
},
|
|
175
|
+
async execute(rawInput, ctx) {
|
|
176
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
177
|
+
const em = ctx.container.resolve("em").fork();
|
|
178
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
179
|
+
if (recipient.status !== "archived" || recipient.archivedAt === null) {
|
|
180
|
+
recipient.archivedAt = /* @__PURE__ */ new Date();
|
|
181
|
+
recipient.status = "archived";
|
|
182
|
+
await em.flush();
|
|
183
|
+
await emitRecipientMutationEvent("messages.message.archived", input);
|
|
184
|
+
}
|
|
185
|
+
return { ok: true };
|
|
186
|
+
},
|
|
187
|
+
async captureAfter(rawInput, _result, ctx) {
|
|
188
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
189
|
+
const em = ctx.container.resolve("em").fork();
|
|
190
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
191
|
+
return snapshotRecipient(recipient);
|
|
192
|
+
},
|
|
193
|
+
async buildLog({ input, snapshots }) {
|
|
194
|
+
const parsed = recipientMutationSchema.parse(input);
|
|
195
|
+
return buildLog("Archive message", {
|
|
196
|
+
before: snapshots.before ?? null,
|
|
197
|
+
after: snapshots.after ?? null
|
|
198
|
+
}, parsed);
|
|
199
|
+
},
|
|
200
|
+
undo: async ({ logEntry, ctx }) => {
|
|
201
|
+
const undo = extractUndoPayload(logEntry);
|
|
202
|
+
const before = undo?.before;
|
|
203
|
+
if (!before) return;
|
|
204
|
+
const em = ctx.container.resolve("em").fork();
|
|
205
|
+
const recipient = await em.findOne(MessageRecipient, { id: before.id });
|
|
206
|
+
if (!recipient) return;
|
|
207
|
+
applyRecipientSnapshot(recipient, before);
|
|
208
|
+
await em.flush();
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const unarchiveRecipientCommand = {
|
|
212
|
+
id: "messages.recipients.unarchive",
|
|
213
|
+
async prepare(rawInput, ctx) {
|
|
214
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
215
|
+
const em = ctx.container.resolve("em").fork();
|
|
216
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
217
|
+
return { before: snapshotRecipient(recipient) };
|
|
218
|
+
},
|
|
219
|
+
async execute(rawInput, ctx) {
|
|
220
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
221
|
+
const em = ctx.container.resolve("em").fork();
|
|
222
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
223
|
+
if (recipient.archivedAt !== null || recipient.status === "archived") {
|
|
224
|
+
recipient.archivedAt = null;
|
|
225
|
+
recipient.status = recipient.readAt ? "read" : "unread";
|
|
226
|
+
await em.flush();
|
|
227
|
+
await emitRecipientMutationEvent("messages.message.unarchived", input);
|
|
228
|
+
}
|
|
229
|
+
return { ok: true };
|
|
230
|
+
},
|
|
231
|
+
async captureAfter(rawInput, _result, ctx) {
|
|
232
|
+
const input = recipientMutationSchema.parse(rawInput);
|
|
233
|
+
const em = ctx.container.resolve("em").fork();
|
|
234
|
+
const { recipient } = await loadRecipientForMutation(em, input);
|
|
235
|
+
return snapshotRecipient(recipient);
|
|
236
|
+
},
|
|
237
|
+
async buildLog({ input, snapshots }) {
|
|
238
|
+
const parsed = recipientMutationSchema.parse(input);
|
|
239
|
+
return buildLog("Unarchive message", {
|
|
240
|
+
before: snapshots.before ?? null,
|
|
241
|
+
after: snapshots.after ?? null
|
|
242
|
+
}, parsed);
|
|
243
|
+
},
|
|
244
|
+
undo: async ({ logEntry, ctx }) => {
|
|
245
|
+
const undo = extractUndoPayload(logEntry);
|
|
246
|
+
const before = undo?.before;
|
|
247
|
+
if (!before) return;
|
|
248
|
+
const em = ctx.container.resolve("em").fork();
|
|
249
|
+
const recipient = await em.findOne(MessageRecipient, { id: before.id });
|
|
250
|
+
if (!recipient) return;
|
|
251
|
+
applyRecipientSnapshot(recipient, before);
|
|
252
|
+
await em.flush();
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
registerCommand(markReadCommand);
|
|
256
|
+
registerCommand(markUnreadCommand);
|
|
257
|
+
registerCommand(archiveRecipientCommand);
|
|
258
|
+
registerCommand(unarchiveRecipientCommand);
|
|
259
|
+
//# sourceMappingURL=recipients.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/messages/commands/recipients.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { z } from 'zod'\nimport { registerCommand, type CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { extractUndoPayload, type UndoPayload } from '@open-mercato/shared/lib/commands/undo'\nimport { Message, MessageRecipient } from '../data/entities'\nimport { emitMessagesEvent, type MessagesEventId } from '../events'\nimport { assertOrganizationAccess, type MessageRecipientSnapshot, type MessageScopeInput } from './shared'\n\nconst recipientMutationSchema = z.object({\n messageId: z.string().uuid(),\n tenantId: z.string().uuid(),\n organizationId: z.string().uuid().nullable(),\n userId: z.string().uuid(),\n})\n\ntype RecipientMutationInput = z.infer<typeof recipientMutationSchema>\n\ntype RecipientUndoPayload = UndoPayload<MessageRecipientSnapshot>\n\nfunction toIso(value: Date | null | undefined): string | null {\n return value ? value.toISOString() : null\n}\n\nfunction toDate(value: string | null | undefined): Date | null {\n if (!value) return null\n return new Date(value)\n}\n\nasync function loadRecipientForMutation(em: EntityManager, input: RecipientMutationInput) {\n const message = await em.findOne(Message, {\n id: input.messageId,\n tenantId: input.tenantId,\n deletedAt: null,\n })\n if (!message) throw new Error('Message not found')\n assertOrganizationAccess(input as MessageScopeInput, message)\n\n const recipient = await em.findOne(MessageRecipient, {\n messageId: input.messageId,\n recipientUserId: input.userId,\n deletedAt: null,\n })\n if (!recipient) throw new Error('Access denied')\n\n return { message, recipient }\n}\n\nfunction snapshotRecipient(recipient: MessageRecipient): MessageRecipientSnapshot {\n return {\n id: recipient.id,\n messageId: recipient.messageId,\n recipientUserId: recipient.recipientUserId,\n recipientType: recipient.recipientType,\n status: recipient.status,\n readAt: toIso(recipient.readAt),\n archivedAt: toIso(recipient.archivedAt),\n deletedAt: toIso(recipient.deletedAt),\n }\n}\n\nfunction buildLog(actionLabel: string, payload: RecipientUndoPayload, input: RecipientMutationInput) {\n return {\n actionLabel,\n resourceKind: 'messages.message',\n resourceId: input.messageId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n payload: { undo: payload },\n snapshotBefore: payload.before ?? null,\n snapshotAfter: payload.after ?? null,\n }\n}\n\nfunction applyRecipientSnapshot(recipient: MessageRecipient, snapshot: MessageRecipientSnapshot) {\n recipient.status = snapshot.status\n recipient.readAt = toDate(snapshot.readAt)\n recipient.archivedAt = toDate(snapshot.archivedAt)\n recipient.deletedAt = toDate(snapshot.deletedAt)\n}\n\nasync function emitRecipientMutationEvent(\n eventId: MessagesEventId,\n input: RecipientMutationInput,\n): Promise<void> {\n await emitMessagesEvent(\n eventId,\n {\n messageId: input.messageId,\n recipientUserId: input.userId,\n userId: input.userId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n },\n { persistent: true },\n )\n}\n\nconst markReadCommand: CommandHandler<unknown, { ok: true }> = {\n id: 'messages.recipients.mark_read',\n async prepare(rawInput, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n return { before: snapshotRecipient(recipient) }\n },\n async execute(rawInput, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n if (recipient.status !== 'read') {\n recipient.status = 'read'\n recipient.readAt = new Date()\n await em.flush()\n await emitRecipientMutationEvent('messages.message.read', input)\n }\n return { ok: true }\n },\n async captureAfter(rawInput, _result, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n return snapshotRecipient(recipient)\n },\n async buildLog({ input, snapshots }) {\n const parsed = recipientMutationSchema.parse(input)\n return buildLog('Mark message as read', {\n before: (snapshots.before as MessageRecipientSnapshot | undefined) ?? null,\n after: (snapshots.after as MessageRecipientSnapshot | undefined) ?? null,\n }, parsed)\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<RecipientUndoPayload>(logEntry)\n const before = undo?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const recipient = await em.findOne(MessageRecipient, { id: before.id })\n if (!recipient) return\n applyRecipientSnapshot(recipient, before)\n await em.flush()\n },\n}\n\nconst markUnreadCommand: CommandHandler<unknown, { ok: true }> = {\n id: 'messages.recipients.mark_unread',\n async prepare(rawInput, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n return { before: snapshotRecipient(recipient) }\n },\n async execute(rawInput, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n if (recipient.status !== 'unread' || recipient.readAt !== null) {\n recipient.status = 'unread'\n recipient.readAt = null\n await em.flush()\n await emitRecipientMutationEvent('messages.message.marked_unread', input)\n }\n return { ok: true }\n },\n async captureAfter(rawInput, _result, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n return snapshotRecipient(recipient)\n },\n async buildLog({ input, snapshots }) {\n const parsed = recipientMutationSchema.parse(input)\n return buildLog('Mark message as unread', {\n before: (snapshots.before as MessageRecipientSnapshot | undefined) ?? null,\n after: (snapshots.after as MessageRecipientSnapshot | undefined) ?? null,\n }, parsed)\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<RecipientUndoPayload>(logEntry)\n const before = undo?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const recipient = await em.findOne(MessageRecipient, { id: before.id })\n if (!recipient) return\n applyRecipientSnapshot(recipient, before)\n await em.flush()\n },\n}\n\nconst archiveRecipientCommand: CommandHandler<unknown, { ok: true }> = {\n id: 'messages.recipients.archive',\n async prepare(rawInput, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n return { before: snapshotRecipient(recipient) }\n },\n async execute(rawInput, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n if (recipient.status !== 'archived' || recipient.archivedAt === null) {\n recipient.archivedAt = new Date()\n recipient.status = 'archived'\n await em.flush()\n await emitRecipientMutationEvent('messages.message.archived', input)\n }\n return { ok: true }\n },\n async captureAfter(rawInput, _result, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n return snapshotRecipient(recipient)\n },\n async buildLog({ input, snapshots }) {\n const parsed = recipientMutationSchema.parse(input)\n return buildLog('Archive message', {\n before: (snapshots.before as MessageRecipientSnapshot | undefined) ?? null,\n after: (snapshots.after as MessageRecipientSnapshot | undefined) ?? null,\n }, parsed)\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<RecipientUndoPayload>(logEntry)\n const before = undo?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const recipient = await em.findOne(MessageRecipient, { id: before.id })\n if (!recipient) return\n applyRecipientSnapshot(recipient, before)\n await em.flush()\n },\n}\n\nconst unarchiveRecipientCommand: CommandHandler<unknown, { ok: true }> = {\n id: 'messages.recipients.unarchive',\n async prepare(rawInput, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n return { before: snapshotRecipient(recipient) }\n },\n async execute(rawInput, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n if (recipient.archivedAt !== null || recipient.status === 'archived') {\n recipient.archivedAt = null\n recipient.status = recipient.readAt ? 'read' : 'unread'\n await em.flush()\n await emitRecipientMutationEvent('messages.message.unarchived', input)\n }\n return { ok: true }\n },\n async captureAfter(rawInput, _result, ctx) {\n const input = recipientMutationSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { recipient } = await loadRecipientForMutation(em, input)\n return snapshotRecipient(recipient)\n },\n async buildLog({ input, snapshots }) {\n const parsed = recipientMutationSchema.parse(input)\n return buildLog('Unarchive message', {\n before: (snapshots.before as MessageRecipientSnapshot | undefined) ?? null,\n after: (snapshots.after as MessageRecipientSnapshot | undefined) ?? null,\n }, parsed)\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<RecipientUndoPayload>(logEntry)\n const before = undo?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const recipient = await em.findOne(MessageRecipient, { id: before.id })\n if (!recipient) return\n applyRecipientSnapshot(recipient, before)\n await em.flush()\n },\n}\n\nregisterCommand(markReadCommand)\nregisterCommand(markUnreadCommand)\nregisterCommand(archiveRecipientCommand)\nregisterCommand(unarchiveRecipientCommand)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|