@open-mercato/core 0.6.6-develop.6256.1.9fc16aedc4 → 0.6.6-develop.6286.1.d985c5c374

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.
Files changed (234) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/carrier_shipment_idempotency_key/index.js +19 -0
  3. package/dist/generated/entities/carrier_shipment_idempotency_key/index.js.map +7 -0
  4. package/dist/generated/entities.ids.generated.js +2 -1
  5. package/dist/generated/entities.ids.generated.js.map +2 -2
  6. package/dist/generated/entity-fields-registry.js +10 -0
  7. package/dist/generated/entity-fields-registry.js.map +2 -2
  8. package/dist/modules/catalog/lib/productResolution.js +45 -0
  9. package/dist/modules/catalog/lib/productResolution.js.map +7 -0
  10. package/dist/modules/communication_channels/workers/channel-import-history.js +1 -1
  11. package/dist/modules/communication_channels/workers/channel-import-history.js.map +2 -2
  12. package/dist/modules/currencies/api/fetch-configs/route.js +34 -0
  13. package/dist/modules/currencies/api/fetch-configs/route.js.map +2 -2
  14. package/dist/modules/currencies/components/CurrencyFetchingConfig.js +17 -15
  15. package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
  16. package/dist/modules/customers/api/companies/[id]/route.js +176 -161
  17. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  18. package/dist/modules/customers/api/people/[id]/route.js +75 -59
  19. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  20. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +17 -10
  21. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
  22. package/dist/modules/customers/components/detail/ActivitiesAddNewMenu.js +6 -4
  23. package/dist/modules/customers/components/detail/ActivitiesAddNewMenu.js.map +2 -2
  24. package/dist/modules/customers/components/detail/AiActionChips.js +5 -2
  25. package/dist/modules/customers/components/detail/AiActionChips.js.map +2 -2
  26. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +19 -21
  27. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
  28. package/dist/modules/data_sync/api/runs/[id]/cancel.js +1 -1
  29. package/dist/modules/data_sync/api/runs/[id]/cancel.js.map +2 -2
  30. package/dist/modules/data_sync/backend/data-sync/page.js +9 -45
  31. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  32. package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js +11 -17
  33. package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js.map +2 -2
  34. package/dist/modules/data_sync/components/IntegrationScheduleTab.js +12 -10
  35. package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
  36. package/dist/modules/data_sync/lib/id-mapping.js +46 -1
  37. package/dist/modules/data_sync/lib/id-mapping.js.map +2 -2
  38. package/dist/modules/data_sync/lib/sync-engine.js +2 -2
  39. package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
  40. package/dist/modules/data_sync/lib/syncRunStatus.js +30 -0
  41. package/dist/modules/data_sync/lib/syncRunStatus.js.map +7 -0
  42. package/dist/modules/entities/api/records.js +6 -0
  43. package/dist/modules/entities/api/records.js.map +2 -2
  44. package/dist/modules/feature_toggles/api/global/route.js +17 -15
  45. package/dist/modules/feature_toggles/api/global/route.js.map +2 -2
  46. package/dist/modules/feature_toggles/api/openapi.js +2 -2
  47. package/dist/modules/feature_toggles/api/openapi.js.map +2 -2
  48. package/dist/modules/feature_toggles/commands/global.js +14 -0
  49. package/dist/modules/feature_toggles/commands/global.js.map +2 -2
  50. package/dist/modules/inbox_ops/backend/inbox-ops/page.js +6 -0
  51. package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
  52. package/dist/modules/messages/api/[id]/conversation/archive/route.js +25 -7
  53. package/dist/modules/messages/api/[id]/conversation/archive/route.js.map +2 -2
  54. package/dist/modules/messages/api/[id]/conversation/read/route.js +24 -6
  55. package/dist/modules/messages/api/[id]/conversation/read/route.js.map +2 -2
  56. package/dist/modules/messages/api/[id]/route.js +13 -1
  57. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  58. package/dist/modules/messages/api/openapi.js +3 -1
  59. package/dist/modules/messages/api/openapi.js.map +2 -2
  60. package/dist/modules/messages/commands/conversation.js +77 -0
  61. package/dist/modules/messages/commands/conversation.js.map +2 -2
  62. package/dist/modules/messages/components/MessageDetailPageClient.js +16 -4
  63. package/dist/modules/messages/components/MessageDetailPageClient.js.map +2 -2
  64. package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js +3 -1
  65. package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js.map +2 -2
  66. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js +29 -4
  67. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js.map +2 -2
  68. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js +10 -1
  69. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js.map +2 -2
  70. package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js +13 -11
  71. package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js.map +2 -2
  72. package/dist/modules/payment_gateways/api/cancel/route.js +5 -0
  73. package/dist/modules/payment_gateways/api/cancel/route.js.map +2 -2
  74. package/dist/modules/payment_gateways/api/capture/route.js +5 -0
  75. package/dist/modules/payment_gateways/api/capture/route.js.map +2 -2
  76. package/dist/modules/payment_gateways/api/refund/route.js +5 -0
  77. package/dist/modules/payment_gateways/api/refund/route.js.map +2 -2
  78. package/dist/modules/payment_gateways/lib/gateway-service.js +52 -25
  79. package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
  80. package/dist/modules/payment_gateways/lib/status-machine.js +13 -0
  81. package/dist/modules/payment_gateways/lib/status-machine.js.map +2 -2
  82. package/dist/modules/perspectives/api/[tableId]/route.js +8 -2
  83. package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
  84. package/dist/modules/perspectives/data/entities.js +33 -3
  85. package/dist/modules/perspectives/data/entities.js.map +2 -2
  86. package/dist/modules/perspectives/migrations/Migration20260619120000_perspectives_live_row_uniqueness.js +63 -0
  87. package/dist/modules/perspectives/migrations/Migration20260619120000_perspectives_live_row_uniqueness.js.map +7 -0
  88. package/dist/modules/perspectives/services/perspectiveService.js +17 -0
  89. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  90. package/dist/modules/planner/commands/availability-weekly.js +33 -1
  91. package/dist/modules/planner/commands/availability-weekly.js.map +2 -2
  92. package/dist/modules/planner/components/AvailabilityRulesEditor.js +14 -2
  93. package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
  94. package/dist/modules/progress/api/active/route.js +1 -1
  95. package/dist/modules/progress/api/active/route.js.map +2 -2
  96. package/dist/modules/progress/lib/progressService.js.map +1 -1
  97. package/dist/modules/progress/lib/progressServiceImpl.js +33 -8
  98. package/dist/modules/progress/lib/progressServiceImpl.js.map +2 -2
  99. package/dist/modules/query_index/api/status.js +19 -24
  100. package/dist/modules/query_index/api/status.js.map +3 -3
  101. package/dist/modules/query_index/lib/coverage.js +35 -0
  102. package/dist/modules/query_index/lib/coverage.js.map +2 -2
  103. package/dist/modules/query_index/lib/engine.js +11 -6
  104. package/dist/modules/query_index/lib/engine.js.map +2 -2
  105. package/dist/modules/resources/api/resource-types.js +5 -37
  106. package/dist/modules/resources/api/resource-types.js.map +2 -2
  107. package/dist/modules/resources/api/resourceTypeCounts.js +35 -0
  108. package/dist/modules/resources/api/resourceTypeCounts.js.map +7 -0
  109. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +1 -1
  110. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +1 -1
  111. package/dist/modules/resources/backend/resources/resource-types/page.js +2 -1
  112. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  113. package/dist/modules/sales/components/documents/ReturnDialog.js +4 -1
  114. package/dist/modules/sales/components/documents/ReturnDialog.js.map +2 -2
  115. package/dist/modules/sales/components/documents/ShipmentDialog.js +17 -2
  116. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  117. package/dist/modules/sales/di.js +4 -0
  118. package/dist/modules/sales/di.js.map +2 -2
  119. package/dist/modules/sales/services/salesOrderService.js +26 -0
  120. package/dist/modules/sales/services/salesOrderService.js.map +7 -0
  121. package/dist/modules/shipping_carriers/api/shipments/route.js +8 -0
  122. package/dist/modules/shipping_carriers/api/shipments/route.js.map +2 -2
  123. package/dist/modules/shipping_carriers/data/entities.js +38 -0
  124. package/dist/modules/shipping_carriers/data/entities.js.map +2 -2
  125. package/dist/modules/shipping_carriers/data/validators.js +2 -1
  126. package/dist/modules/shipping_carriers/data/validators.js.map +2 -2
  127. package/dist/modules/shipping_carriers/lib/shipment-idempotency.js +76 -0
  128. package/dist/modules/shipping_carriers/lib/shipment-idempotency.js.map +7 -0
  129. package/dist/modules/shipping_carriers/lib/shipment-wizard/hooks/shipmentApi.js +2 -1
  130. package/dist/modules/shipping_carriers/lib/shipment-wizard/hooks/shipmentApi.js.map +2 -2
  131. package/dist/modules/shipping_carriers/lib/shipment-wizard/hooks/useShipmentWizard.js +20 -2
  132. package/dist/modules/shipping_carriers/lib/shipment-wizard/hooks/useShipmentWizard.js.map +2 -2
  133. package/dist/modules/shipping_carriers/lib/shipping-service.js +82 -43
  134. package/dist/modules/shipping_carriers/lib/shipping-service.js.map +2 -2
  135. package/dist/modules/shipping_carriers/migrations/Migration20260618173616_shipping_carriers.js +14 -0
  136. package/dist/modules/shipping_carriers/migrations/Migration20260618173616_shipping_carriers.js.map +7 -0
  137. package/dist/modules/staff/lib/timesheets-ui/ListView.js +15 -6
  138. package/dist/modules/staff/lib/timesheets-ui/ListView.js.map +2 -2
  139. package/dist/modules/translations/components/TranslationManager.js +9 -18
  140. package/dist/modules/translations/components/TranslationManager.js.map +2 -2
  141. package/generated/entities/carrier_shipment_idempotency_key/index.ts +8 -0
  142. package/generated/entities.ids.generated.ts +2 -1
  143. package/generated/entity-fields-registry.ts +10 -0
  144. package/package.json +9 -8
  145. package/src/modules/catalog/lib/productResolution.ts +75 -0
  146. package/src/modules/communication_channels/workers/channel-import-history.ts +1 -1
  147. package/src/modules/currencies/api/fetch-configs/route.ts +36 -0
  148. package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +20 -17
  149. package/src/modules/currencies/i18n/de.json +2 -1
  150. package/src/modules/currencies/i18n/en.json +2 -1
  151. package/src/modules/currencies/i18n/es.json +2 -1
  152. package/src/modules/currencies/i18n/pl.json +2 -1
  153. package/src/modules/customers/api/companies/[id]/route.ts +214 -189
  154. package/src/modules/customers/api/people/[id]/route.ts +106 -80
  155. package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +19 -12
  156. package/src/modules/customers/components/detail/ActivitiesAddNewMenu.tsx +8 -6
  157. package/src/modules/customers/components/detail/AiActionChips.tsx +6 -3
  158. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +16 -18
  159. package/src/modules/data_sync/api/runs/[id]/cancel.ts +1 -1
  160. package/src/modules/data_sync/backend/data-sync/page.tsx +11 -58
  161. package/src/modules/data_sync/backend/data-sync/runs/[id]/page.tsx +13 -20
  162. package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +10 -8
  163. package/src/modules/data_sync/lib/id-mapping.ts +58 -1
  164. package/src/modules/data_sync/lib/sync-engine.ts +2 -2
  165. package/src/modules/data_sync/lib/syncRunStatus.ts +39 -0
  166. package/src/modules/entities/api/records.ts +14 -0
  167. package/src/modules/feature_toggles/api/global/route.ts +16 -14
  168. package/src/modules/feature_toggles/api/openapi.ts +2 -2
  169. package/src/modules/feature_toggles/commands/global.ts +15 -0
  170. package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +7 -0
  171. package/src/modules/messages/api/[id]/conversation/archive/route.ts +29 -6
  172. package/src/modules/messages/api/[id]/conversation/read/route.ts +29 -6
  173. package/src/modules/messages/api/[id]/route.ts +15 -0
  174. package/src/modules/messages/api/openapi.ts +2 -0
  175. package/src/modules/messages/commands/conversation.ts +87 -0
  176. package/src/modules/messages/components/MessageDetailPageClient.tsx +16 -4
  177. package/src/modules/messages/components/message-detail/hooks/useMessageDetails.ts +2 -0
  178. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsActions.ts +39 -4
  179. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.ts +15 -1
  180. package/src/modules/messages/components/message-detail/panels/MainMessageHeader.tsx +29 -14
  181. package/src/modules/messages/components/message-detail/types.ts +2 -0
  182. package/src/modules/messages/i18n/de.json +4 -0
  183. package/src/modules/messages/i18n/en.json +4 -0
  184. package/src/modules/messages/i18n/es.json +4 -0
  185. package/src/modules/messages/i18n/pl.json +4 -0
  186. package/src/modules/payment_gateways/api/cancel/route.ts +5 -0
  187. package/src/modules/payment_gateways/api/capture/route.ts +5 -0
  188. package/src/modules/payment_gateways/api/refund/route.ts +5 -0
  189. package/src/modules/payment_gateways/lib/gateway-service.ts +58 -25
  190. package/src/modules/payment_gateways/lib/status-machine.ts +16 -0
  191. package/src/modules/perspectives/api/[tableId]/route.ts +8 -2
  192. package/src/modules/perspectives/data/entities.ts +43 -3
  193. package/src/modules/perspectives/migrations/.snapshot-open-mercato.json +69 -25
  194. package/src/modules/perspectives/migrations/Migration20260619120000_perspectives_live_row_uniqueness.ts +65 -0
  195. package/src/modules/perspectives/services/perspectiveService.ts +17 -0
  196. package/src/modules/planner/commands/availability-weekly.ts +48 -1
  197. package/src/modules/planner/components/AvailabilityRulesEditor.tsx +31 -10
  198. package/src/modules/progress/api/active/route.ts +1 -1
  199. package/src/modules/progress/lib/progressService.ts +2 -2
  200. package/src/modules/progress/lib/progressServiceImpl.ts +33 -8
  201. package/src/modules/query_index/api/status.ts +28 -32
  202. package/src/modules/query_index/lib/coverage.ts +63 -0
  203. package/src/modules/query_index/lib/engine.ts +37 -24
  204. package/src/modules/resources/api/resource-types.ts +4 -44
  205. package/src/modules/resources/api/resourceTypeCounts.ts +74 -0
  206. package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +1 -1
  207. package/src/modules/resources/backend/resources/resource-types/page.tsx +1 -0
  208. package/src/modules/sales/components/documents/ReturnDialog.tsx +4 -1
  209. package/src/modules/sales/components/documents/ShipmentDialog.tsx +20 -2
  210. package/src/modules/sales/di.ts +6 -0
  211. package/src/modules/sales/services/salesOrderService.ts +38 -0
  212. package/src/modules/shipping_carriers/api/shipments/route.ts +8 -0
  213. package/src/modules/shipping_carriers/data/entities.ts +33 -0
  214. package/src/modules/shipping_carriers/data/validators.ts +1 -0
  215. package/src/modules/shipping_carriers/i18n/de.json +1 -0
  216. package/src/modules/shipping_carriers/i18n/en.json +1 -0
  217. package/src/modules/shipping_carriers/i18n/es.json +1 -0
  218. package/src/modules/shipping_carriers/i18n/pl.json +1 -0
  219. package/src/modules/shipping_carriers/lib/shipment-idempotency.ts +119 -0
  220. package/src/modules/shipping_carriers/lib/shipment-wizard/hooks/shipmentApi.ts +3 -1
  221. package/src/modules/shipping_carriers/lib/shipment-wizard/hooks/useShipmentWizard.ts +24 -2
  222. package/src/modules/shipping_carriers/lib/shipping-service.ts +87 -43
  223. package/src/modules/shipping_carriers/migrations/.snapshot-open-mercato.json +197 -0
  224. package/src/modules/shipping_carriers/migrations/Migration20260618173616_shipping_carriers.ts +14 -0
  225. package/src/modules/staff/i18n/de.json +1 -0
  226. package/src/modules/staff/i18n/en.json +1 -0
  227. package/src/modules/staff/i18n/es.json +1 -0
  228. package/src/modules/staff/i18n/pl.json +1 -0
  229. package/src/modules/staff/lib/timesheets-ui/ListView.tsx +15 -7
  230. package/src/modules/translations/components/TranslationManager.tsx +17 -24
  231. package/src/modules/translations/i18n/de.json +1 -0
  232. package/src/modules/translations/i18n/en.json +1 -0
  233. package/src/modules/translations/i18n/es.json +1 -0
  234. package/src/modules/translations/i18n/pl.json +1 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/messages/api/%5Bid%5D/conversation/read/route.ts"],
4
- "sourcesContent": ["import type { CommandBus } from '@open-mercato/shared/lib/commands/command-bus'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'\nimport { attachOperationMetadataHeader } from '../../../../lib/operationMetadata'\nimport { resolveMessageContext } from '../../../../lib/routeHelpers'\nimport { resolveUserFeatures, runMessageMutationGuardAfterSuccess, runMessageMutationGuards } from '../../../guards'\nimport {\n conversationMutationResponseSchema,\n errorResponseSchema,\n} from '../../../openapi'\n\nexport const metadata = {\n DELETE: { requireAuth: true, requireFeatures: ['messages.view'] },\n}\n\nexport async function DELETE(req: Request, { params }: { params: { id: string } }) {\n const { ctx, scope } = await resolveMessageContext(req)\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n\n const guardResult = await runMessageMutationGuards(\n ctx.container,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.conversation',\n resourceId: params.id,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: null,\n },\n resolveUserFeatures(ctx.auth),\n )\n if (!guardResult.ok) {\n return Response.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n try {\n const { result, logEntry } = await commandBus.execute('messages.conversation.mark_unread_for_actor', {\n input: {\n anchorMessageId: params.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n ctx: {\n container: ctx.container,\n auth: ctx.auth ?? null,\n organizationScope: null,\n selectedOrganizationId: scope.organizationId,\n organizationIds: scope.organizationId ? [scope.organizationId] : null,\n request: req,\n },\n })\n\n const response = Response.json(result)\n attachOperationMetadataHeader(response, logEntry, {\n resourceKind: 'messages.conversation',\n resourceId: params.id,\n })\n await runMessageMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.conversation',\n resourceId: params.id,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return response\n } catch (error) {\n if (error instanceof Error) {\n if (error.message === 'Message not found') {\n return Response.json({ error: error.message }, { status: 404 })\n }\n if (error.message === 'Access denied') {\n return Response.json({ error: error.message }, { status: 403 })\n }\n }\n throw error\n }\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Messages',\n methods: {\n DELETE: {\n summary: 'Mark entire conversation as unread for current actor',\n responses: [\n { status: 200, description: 'Conversation marked unread', schema: conversationMutationResponseSchema },\n ],\n errors: [\n { status: 403, description: 'Access denied', schema: errorResponseSchema },\n { status: 404, description: 'Message not found', schema: errorResponseSchema },\n ],\n },\n },\n}\n"],
5
- "mappings": "AAEA,SAAS,qCAAqC;AAC9C,SAAS,6BAA6B;AACtC,SAAS,qBAAqB,qCAAqC,gCAAgC;AACnG;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEA,MAAM,WAAW;AAAA,EACtB,QAAQ,EAAE,aAAa,MAAM,iBAAiB,CAAC,eAAe,EAAE;AAClE;AAEA,eAAsB,OAAO,KAAc,EAAE,OAAO,GAA+B;AACjF,QAAM,EAAE,KAAK,MAAM,IAAI,MAAM,sBAAsB,GAAG;AACtD,QAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AAErD,QAAM,cAAc,MAAM;AAAA,IACxB,IAAI;AAAA,IACJ;AAAA,MACE,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,QAAQ,MAAM;AAAA,MACd,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,WAAW;AAAA,MACX,eAAe,IAAI;AAAA,MACnB,gBAAgB,IAAI;AAAA,MACpB,iBAAiB;AAAA,IACnB;AAAA,IACA,oBAAoB,IAAI,IAAI;AAAA,EAC9B;AACA,MAAI,CAAC,YAAY,IAAI;AACnB,WAAO,SAAS;AAAA,MACd,YAAY,aAAa,EAAE,OAAO,6BAA6B;AAAA,MAC/D,EAAE,QAAQ,YAAY,eAAe,IAAI;AAAA,IAC3C;AAAA,EACF;AAEA,MAAI;AACF,UAAM,EAAE,QAAQ,SAAS,IAAI,MAAM,WAAW,QAAQ,+CAA+C;AAAA,MACnG,OAAO;AAAA,QACL,iBAAiB,OAAO;AAAA,QACxB,UAAU,MAAM;AAAA,QAChB,gBAAgB,MAAM;AAAA,QACtB,QAAQ,MAAM;AAAA,MAChB;AAAA,MACA,KAAK;AAAA,QACH,WAAW,IAAI;AAAA,QACf,MAAM,IAAI,QAAQ;AAAA,QAClB,mBAAmB;AAAA,QACnB,wBAAwB,MAAM;AAAA,QAC9B,iBAAiB,MAAM,iBAAiB,CAAC,MAAM,cAAc,IAAI;AAAA,QACjE,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,UAAM,WAAW,SAAS,KAAK,MAAM;AACrC,kCAA8B,UAAU,UAAU;AAAA,MAChD,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,IACrB,CAAC;AACD,UAAM,oCAAoC,YAAY,uBAAuB;AAAA,MAC3E,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,QAAQ,MAAM;AAAA,MACd,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,WAAW;AAAA,MACX,eAAe,IAAI;AAAA,MACnB,gBAAgB,IAAI;AAAA,IACtB,CAAC;AACD,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,OAAO;AAC1B,UAAI,MAAM,YAAY,qBAAqB;AACzC,eAAO,SAAS,KAAK,EAAE,OAAO,MAAM,QAAQ,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MAChE;AACA,UAAI,MAAM,YAAY,iBAAiB;AACrC,eAAO,SAAS,KAAK,EAAE,OAAO,MAAM,QAAQ,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MAChE;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEO,MAAM,UAA2B;AAAA,EACtC,KAAK;AAAA,EACL,SAAS;AAAA,IACP,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,8BAA8B,QAAQ,mCAAmC;AAAA,MACvG;AAAA,MACA,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,iBAAiB,QAAQ,oBAAoB;AAAA,QACzE,EAAE,QAAQ,KAAK,aAAa,qBAAqB,QAAQ,oBAAoB;AAAA,MAC/E;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import type { CommandBus } from '@open-mercato/shared/lib/commands/command-bus'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'\nimport { attachOperationMetadataHeader } from '../../../../lib/operationMetadata'\nimport { resolveMessageContext } from '../../../../lib/routeHelpers'\nimport { resolveUserFeatures, runMessageMutationGuardAfterSuccess, runMessageMutationGuards } from '../../../guards'\nimport {\n conversationMutationResponseSchema,\n errorResponseSchema,\n} from '../../../openapi'\n\nexport const metadata = {\n PUT: { requireAuth: true, requireFeatures: ['messages.view'] },\n DELETE: { requireAuth: true, requireFeatures: ['messages.view'] },\n}\n\nasync function runConversationReadMutation(\n req: Request,\n id: string,\n commandId: 'messages.conversation.mark_read_for_actor' | 'messages.conversation.mark_unread_for_actor',\n) {\n const { ctx, scope } = await resolveMessageContext(req)\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n\n const guardResult = await runMessageMutationGuards(\n ctx.container,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.conversation',\n resourceId: id,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: null,\n },\n resolveUserFeatures(ctx.auth),\n )\n if (!guardResult.ok) {\n return Response.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n try {\n const { result, logEntry } = await commandBus.execute(commandId, {\n input: {\n anchorMessageId: id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n ctx: {\n container: ctx.container,\n auth: ctx.auth ?? null,\n organizationScope: null,\n selectedOrganizationId: scope.organizationId,\n organizationIds: scope.organizationId ? [scope.organizationId] : null,\n request: req,\n },\n })\n\n const response = Response.json(result)\n attachOperationMetadataHeader(response, logEntry, {\n resourceKind: 'messages.conversation',\n resourceId: id,\n })\n await runMessageMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.conversation',\n resourceId: id,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return response\n } catch (error) {\n if (error instanceof Error) {\n if (error.message === 'Message not found') {\n return Response.json({ error: error.message }, { status: 404 })\n }\n if (error.message === 'Access denied') {\n return Response.json({ error: error.message }, { status: 403 })\n }\n }\n throw error\n }\n}\n\nexport async function PUT(req: Request, { params }: { params: { id: string } }) {\n return runConversationReadMutation(req, params.id, 'messages.conversation.mark_read_for_actor')\n}\n\nexport async function DELETE(req: Request, { params }: { params: { id: string } }) {\n return runConversationReadMutation(req, params.id, 'messages.conversation.mark_unread_for_actor')\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Messages',\n methods: {\n PUT: {\n summary: 'Mark entire conversation as read for current actor',\n responses: [\n { status: 200, description: 'Conversation marked read', schema: conversationMutationResponseSchema },\n ],\n errors: [\n { status: 403, description: 'Access denied', schema: errorResponseSchema },\n { status: 404, description: 'Message not found', schema: errorResponseSchema },\n ],\n },\n DELETE: {\n summary: 'Mark entire conversation as unread for current actor',\n responses: [\n { status: 200, description: 'Conversation marked unread', schema: conversationMutationResponseSchema },\n ],\n errors: [\n { status: 403, description: 'Access denied', schema: errorResponseSchema },\n { status: 404, description: 'Message not found', schema: errorResponseSchema },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -95,6 +95,16 @@ async function GET(req, { params }) {
95
95
  }) : [];
96
96
  const visibleRecipientMessageIds = new Set(visibleRecipientRows.map((item) => item.messageId));
97
97
  const actorVisibleThreadMessages = threadMessages.filter((threadMessage) => threadMessage.senderUserId === scope.userId || visibleRecipientMessageIds.has(threadMessage.id));
98
+ const actorRecipientStatusByMessageId = /* @__PURE__ */ new Map();
99
+ for (const row of visibleRecipientRows) {
100
+ actorRecipientStatusByMessageId.set(row.messageId, row.status);
101
+ }
102
+ if (recipient) {
103
+ actorRecipientStatusByMessageId.set(params.id, autoMarkRead ? "read" : recipient.status);
104
+ }
105
+ const actorRecipientStatuses = Array.from(actorRecipientStatusByMessageId.values());
106
+ const conversationArchived = actorRecipientStatuses.length > 0 && actorRecipientStatuses.every((status) => status === "archived");
107
+ const conversationAllUnread = actorRecipientStatuses.length > 0 && actorRecipientStatuses.every((status) => status === "unread");
98
108
  const threadSenderIds = actorVisibleThreadMessages.map((threadMessage) => threadMessage.senderUserId).filter((value) => typeof value === "string" && value.length > 0);
99
109
  const threadSenders = threadSenderIds.length > 0 ? await findWithDecryption(
100
110
  em,
@@ -200,7 +210,9 @@ async function GET(req, { params }) {
200
210
  sentAt: threadMessage.sentAt
201
211
  };
202
212
  }),
203
- isRead: recipient ? autoMarkRead || recipient.status !== "unread" : true
213
+ isRead: recipient ? autoMarkRead || recipient.status !== "unread" : true,
214
+ conversationArchived,
215
+ conversationAllUnread
204
216
  });
205
217
  }
206
218
  async function PATCH(req, { params }) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/messages/api/%5Bid%5D/route.ts"],
4
- "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { CommandBus } from '@open-mercato/shared/lib/commands/command-bus'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { User } from '../../../auth/data/entities'\nimport { Message, MessageObject, MessageRecipient } from '../../data/entities'\nimport { updateDraftSchema } from '../../data/validators'\nimport { buildResolvedMessageActions } from '../../lib/actions'\nimport { getMessageObjectType } from '../../lib/message-objects-registry'\nimport { getMessageTypeOrDefault } from '../../lib/message-types-registry'\nimport { attachOperationMetadataHeader } from '../../lib/operationMetadata'\nimport { hasOrganizationAccess, resolveMessageContext } from '../../lib/routeHelpers'\nimport { resolveUserFeatures, runMessageMutationGuardAfterSuccess, runMessageMutationGuards } from '../guards'\nimport {\n errorResponseSchema,\n messageDetailResponseSchema,\n okResponseSchema,\n updateDraftSchema as updateDraftOpenApiSchema,\n} from '../openapi'\n\nexport const metadata = {\n GET: { requireAuth: true },\n PATCH: { requireAuth: true, requireFeatures: ['messages.compose'] },\n DELETE: { requireAuth: true, requireFeatures: ['messages.view'] },\n}\n\ntype MessageObjectPreviewPayload = {\n title: string\n subtitle?: string\n status?: string\n statusColor?: string\n metadata?: Record<string, string>\n} | null\n\nexport async function GET(req: Request, { params }: { params: { id: string } }) {\n const { ctx, scope } = await resolveMessageContext(req)\n const em = ctx.container.resolve('em') as EntityManager\n const url = new URL(req.url)\n const skipMarkReadParam = url.searchParams.get('skipMarkRead')\n const skipMarkRead = skipMarkReadParam === '1'\n\n const message = await findOneWithDecryption(\n em,\n Message,\n {\n id: params.id,\n tenantId: scope.tenantId,\n deletedAt: null,\n },\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n\n if (!message) {\n return Response.json({ error: 'Message not found' }, { status: 404 })\n }\n\n if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n\n const recipient = await em.findOne(MessageRecipient, {\n messageId: params.id,\n recipientUserId: scope.userId,\n deletedAt: null,\n })\n\n const isSender = message.senderUserId === scope.userId\n const isRecipient = Boolean(recipient)\n\n if (!isSender && !isRecipient) {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n\n const autoMarkRead = !skipMarkRead && recipient?.status === 'unread'\n const readAt = autoMarkRead ? new Date() : recipient?.readAt ?? null\n\n const objects = await em.find(MessageObject, { messageId: params.id })\n const objectPreviews = await Promise.all(\n objects.map(async (item): Promise<MessageObjectPreviewPayload> => {\n const objectType = getMessageObjectType(item.entityModule, item.entityType)\n if (!objectType?.loadPreview) return null\n try {\n return await objectType.loadPreview(item.entityId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n } catch (error) {\n console.error(\n `[messages] Failed to load preview for ${item.entityModule}:${item.entityType}:${item.entityId}`,\n error,\n )\n return null\n }\n }),\n )\n const allRecipients = await em.find(MessageRecipient, { messageId: params.id, deletedAt: null })\n\n const threadMessages = await findWithDecryption(\n em,\n Message,\n {\n threadId: message.threadId ?? message.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n deletedAt: null,\n isDraft: false,\n },\n { orderBy: { sentAt: 'ASC' } },\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n const threadMessageIds = threadMessages.map((item) => item.id)\n const visibleRecipientRows = threadMessageIds.length > 0\n ? await em.find(MessageRecipient, {\n messageId: { $in: threadMessageIds },\n recipientUserId: scope.userId,\n deletedAt: null,\n })\n : []\n const visibleRecipientMessageIds = new Set(visibleRecipientRows.map((item) => item.messageId))\n const actorVisibleThreadMessages = threadMessages.filter((threadMessage) => (\n threadMessage.senderUserId === scope.userId || visibleRecipientMessageIds.has(threadMessage.id)\n ))\n\n const threadSenderIds = actorVisibleThreadMessages\n .map((threadMessage) => threadMessage.senderUserId)\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n\n const threadSenders = threadSenderIds.length > 0\n ? await findWithDecryption(\n em,\n User,\n { id: { $in: Array.from(new Set(threadSenderIds)) } },\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId }\n )\n : []\n\n const threadSenderMap = new Map(threadSenders.map((user) => [user.id, user]))\n\n const senderUser = await findOneWithDecryption(\n em,\n User,\n { id: message.senderUserId },\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId }\n )\n\n const senderName = typeof senderUser?.name === 'string' && senderUser.name.trim().length\n ? senderUser.name.trim()\n : null\n const senderEmail = senderUser?.email ?? null\n\n const messageType = getMessageTypeOrDefault(message.type)\n const resolvedActionData = buildResolvedMessageActions(message, objects)\n\n if (autoMarkRead) {\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n await commandBus.execute('messages.recipients.mark_read', {\n input: {\n messageId: params.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n ctx: {\n container: ctx.container,\n auth: ctx.auth ?? null,\n organizationScope: null,\n selectedOrganizationId: scope.organizationId,\n organizationIds: scope.organizationId ? [scope.organizationId] : null,\n request: req,\n },\n })\n }\n\n return Response.json({\n id: message.id,\n type: message.type,\n isDraft: message.isDraft,\n canEditDraft: message.isDraft && message.senderUserId === scope.userId,\n visibility: message.visibility,\n sourceEntityType: message.sourceEntityType,\n sourceEntityId: message.sourceEntityId,\n externalEmail: message.externalEmail,\n externalName: message.externalName,\n typeDefinition: {\n labelKey: messageType.labelKey,\n icon: messageType.icon,\n color: messageType.color,\n allowReply: messageType.allowReply ?? true,\n allowForward: messageType.allowForward ?? true,\n ui: {\n listItemComponent: messageType.ui?.listItemComponent ?? null,\n contentComponent: messageType.ui?.contentComponent ?? null,\n actionsComponent: messageType.ui?.actionsComponent ?? null,\n },\n },\n threadId: message.threadId,\n parentMessageId: message.parentMessageId,\n senderUserId: message.senderUserId,\n senderName,\n senderEmail,\n subject: message.subject,\n body: message.body,\n bodyFormat: message.bodyFormat,\n priority: message.priority,\n sentAt: message.sentAt,\n actionData: resolvedActionData,\n actionTaken: message.actionTaken,\n actionTakenAt: message.actionTakenAt,\n actionTakenByUserId: message.actionTakenByUserId,\n recipients: allRecipients.map((item) => ({\n userId: item.recipientUserId,\n type: item.recipientType,\n status: autoMarkRead && item.recipientUserId === scope.userId ? 'read' : item.status,\n readAt: autoMarkRead && item.recipientUserId === scope.userId ? readAt : item.readAt,\n })),\n objects: objects.map((item, index) => ({\n id: item.id,\n entityModule: item.entityModule,\n entityType: item.entityType,\n entityId: item.entityId,\n actionRequired: item.actionRequired,\n actionType: item.actionType,\n actionLabel: item.actionLabel,\n snapshot: item.entitySnapshot,\n preview: objectPreviews[index] ?? null,\n })),\n thread: actorVisibleThreadMessages.map((threadMessage) => {\n const sender = threadSenderMap.get(threadMessage.senderUserId)\n const threadSenderName = typeof sender?.name === 'string' && sender.name.trim().length\n ? sender.name.trim()\n : null\n\n return {\n id: threadMessage.id,\n senderUserId: threadMessage.senderUserId,\n senderName: threadSenderName,\n senderEmail: sender?.email ?? null,\n body: threadMessage.body,\n bodyFormat: threadMessage.bodyFormat,\n sentAt: threadMessage.sentAt,\n }\n }),\n isRead: recipient ? (autoMarkRead || recipient.status !== 'unread') : true,\n })\n}\n\nexport async function PATCH(req: Request, { params }: { params: { id: string } }) {\n const { ctx, scope } = await resolveMessageContext(req)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n const body = await req.json().catch(() => ({}))\n const input = updateDraftSchema.parse(body)\n\n const message = await em.findOne(Message, {\n id: params.id,\n tenantId: scope.tenantId,\n deletedAt: null,\n })\n\n if (!message) {\n return Response.json({ error: 'Message not found' }, { status: 404 })\n }\n\n if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n\n if (message.senderUserId !== scope.userId) {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n\n if (!message.isDraft) {\n return Response.json({ error: 'Only draft messages can be edited' }, { status: 409 })\n }\n\n const guardResult = await runMessageMutationGuards(\n ctx.container,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.message',\n resourceId: message.id,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: input as Record<string, unknown>,\n },\n resolveUserFeatures(ctx.auth),\n )\n if (!guardResult.ok) {\n return Response.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n try {\n const { logEntry } = await commandBus.execute('messages.messages.update_draft', {\n input: {\n ...input,\n messageId: message.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n ctx: {\n container: ctx.container,\n auth: ctx.auth ?? null,\n organizationScope: null,\n selectedOrganizationId: scope.organizationId,\n organizationIds: scope.organizationId ? [scope.organizationId] : null,\n request: req,\n },\n })\n\n const response = Response.json({ ok: true, id: message.id })\n attachOperationMetadataHeader(response, logEntry, {\n resourceKind: 'messages.message',\n resourceId: message.id,\n })\n await runMessageMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.message',\n resourceId: message.id,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return response\n } catch (error) {\n if (error instanceof Error) {\n if (error.message === 'Message type cannot be created by users') {\n return Response.json({ error: error.message }, { status: 400 })\n }\n if (error.message === 'Only draft messages can be edited') {\n return Response.json({ error: error.message }, { status: 409 })\n }\n if (error.message === 'Access denied') {\n return Response.json({ error: error.message }, { status: 403 })\n }\n }\n throw error\n }\n\n}\n\nexport async function DELETE(req: Request, { params }: { params: { id: string } }) {\n const { ctx, scope } = await resolveMessageContext(req)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n\n const message = await em.findOne(Message, {\n id: params.id,\n tenantId: scope.tenantId,\n deletedAt: null,\n })\n\n if (!message) {\n return Response.json({ error: 'Message not found' }, { status: 404 })\n }\n\n if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n\n const guardResult = await runMessageMutationGuards(\n ctx.container,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.message',\n resourceId: params.id,\n operation: 'delete',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: null,\n },\n resolveUserFeatures(ctx.auth),\n )\n if (!guardResult.ok) {\n return Response.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n try {\n const { logEntry } = await commandBus.execute('messages.messages.delete_for_actor', {\n input: {\n messageId: params.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n ctx: {\n container: ctx.container,\n auth: ctx.auth ?? null,\n organizationScope: null,\n selectedOrganizationId: scope.organizationId,\n organizationIds: scope.organizationId ? [scope.organizationId] : null,\n request: req,\n },\n })\n\n const response = Response.json({ ok: true })\n attachOperationMetadataHeader(response, logEntry, {\n resourceKind: 'messages.message',\n resourceId: params.id,\n })\n await runMessageMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.message',\n resourceId: params.id,\n operation: 'delete',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return response\n } catch (error) {\n if (error instanceof Error && error.message === 'Access denied') {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n throw error\n }\n\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Messages',\n methods: {\n GET: {\n summary: 'Get message detail',\n responses: [\n {\n status: 200,\n description: 'Message detail with actor-visible thread items only',\n schema: messageDetailResponseSchema,\n },\n ],\n errors: [\n { status: 403, description: 'Access denied', schema: errorResponseSchema },\n { status: 404, description: 'Message not found', schema: errorResponseSchema },\n ],\n },\n PATCH: {\n summary: 'Update draft message',\n requestBody: { schema: updateDraftOpenApiSchema },\n responses: [\n { status: 200, description: 'Draft updated', schema: okResponseSchema },\n ],\n errors: [\n { status: 403, description: 'Access denied', schema: errorResponseSchema },\n { status: 404, description: 'Message not found', schema: errorResponseSchema },\n { status: 409, description: 'Only drafts can be edited', schema: errorResponseSchema },\n ],\n },\n DELETE: {\n summary: 'Delete message for current sender/recipient context',\n responses: [\n { status: 200, description: 'Message deleted', schema: okResponseSchema },\n ],\n errors: [\n { status: 403, description: 'Access denied', schema: errorResponseSchema },\n { status: 404, description: 'Message not found', schema: errorResponseSchema },\n ],\n },\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { CommandBus } from '@open-mercato/shared/lib/commands/command-bus'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { User } from '../../../auth/data/entities'\nimport { Message, MessageObject, MessageRecipient } from '../../data/entities'\nimport { updateDraftSchema } from '../../data/validators'\nimport { buildResolvedMessageActions } from '../../lib/actions'\nimport { getMessageObjectType } from '../../lib/message-objects-registry'\nimport { getMessageTypeOrDefault } from '../../lib/message-types-registry'\nimport { attachOperationMetadataHeader } from '../../lib/operationMetadata'\nimport { hasOrganizationAccess, resolveMessageContext } from '../../lib/routeHelpers'\nimport { resolveUserFeatures, runMessageMutationGuardAfterSuccess, runMessageMutationGuards } from '../guards'\nimport {\n errorResponseSchema,\n messageDetailResponseSchema,\n okResponseSchema,\n updateDraftSchema as updateDraftOpenApiSchema,\n} from '../openapi'\n\nexport const metadata = {\n GET: { requireAuth: true },\n PATCH: { requireAuth: true, requireFeatures: ['messages.compose'] },\n DELETE: { requireAuth: true, requireFeatures: ['messages.view'] },\n}\n\ntype MessageObjectPreviewPayload = {\n title: string\n subtitle?: string\n status?: string\n statusColor?: string\n metadata?: Record<string, string>\n} | null\n\nexport async function GET(req: Request, { params }: { params: { id: string } }) {\n const { ctx, scope } = await resolveMessageContext(req)\n const em = ctx.container.resolve('em') as EntityManager\n const url = new URL(req.url)\n const skipMarkReadParam = url.searchParams.get('skipMarkRead')\n const skipMarkRead = skipMarkReadParam === '1'\n\n const message = await findOneWithDecryption(\n em,\n Message,\n {\n id: params.id,\n tenantId: scope.tenantId,\n deletedAt: null,\n },\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n\n if (!message) {\n return Response.json({ error: 'Message not found' }, { status: 404 })\n }\n\n if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n\n const recipient = await em.findOne(MessageRecipient, {\n messageId: params.id,\n recipientUserId: scope.userId,\n deletedAt: null,\n })\n\n const isSender = message.senderUserId === scope.userId\n const isRecipient = Boolean(recipient)\n\n if (!isSender && !isRecipient) {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n\n const autoMarkRead = !skipMarkRead && recipient?.status === 'unread'\n const readAt = autoMarkRead ? new Date() : recipient?.readAt ?? null\n\n const objects = await em.find(MessageObject, { messageId: params.id })\n const objectPreviews = await Promise.all(\n objects.map(async (item): Promise<MessageObjectPreviewPayload> => {\n const objectType = getMessageObjectType(item.entityModule, item.entityType)\n if (!objectType?.loadPreview) return null\n try {\n return await objectType.loadPreview(item.entityId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n } catch (error) {\n console.error(\n `[messages] Failed to load preview for ${item.entityModule}:${item.entityType}:${item.entityId}`,\n error,\n )\n return null\n }\n }),\n )\n const allRecipients = await em.find(MessageRecipient, { messageId: params.id, deletedAt: null })\n\n const threadMessages = await findWithDecryption(\n em,\n Message,\n {\n threadId: message.threadId ?? message.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n deletedAt: null,\n isDraft: false,\n },\n { orderBy: { sentAt: 'ASC' } },\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n const threadMessageIds = threadMessages.map((item) => item.id)\n const visibleRecipientRows = threadMessageIds.length > 0\n ? await em.find(MessageRecipient, {\n messageId: { $in: threadMessageIds },\n recipientUserId: scope.userId,\n deletedAt: null,\n })\n : []\n const visibleRecipientMessageIds = new Set(visibleRecipientRows.map((item) => item.messageId))\n const actorVisibleThreadMessages = threadMessages.filter((threadMessage) => (\n threadMessage.senderUserId === scope.userId || visibleRecipientMessageIds.has(threadMessage.id)\n ))\n\n const actorRecipientStatusByMessageId = new Map<string, string>()\n for (const row of visibleRecipientRows) {\n actorRecipientStatusByMessageId.set(row.messageId, row.status)\n }\n if (recipient) {\n actorRecipientStatusByMessageId.set(params.id, autoMarkRead ? 'read' : recipient.status)\n }\n const actorRecipientStatuses = Array.from(actorRecipientStatusByMessageId.values())\n const conversationArchived = actorRecipientStatuses.length > 0\n && actorRecipientStatuses.every((status) => status === 'archived')\n const conversationAllUnread = actorRecipientStatuses.length > 0\n && actorRecipientStatuses.every((status) => status === 'unread')\n\n const threadSenderIds = actorVisibleThreadMessages\n .map((threadMessage) => threadMessage.senderUserId)\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n\n const threadSenders = threadSenderIds.length > 0\n ? await findWithDecryption(\n em,\n User,\n { id: { $in: Array.from(new Set(threadSenderIds)) } },\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId }\n )\n : []\n\n const threadSenderMap = new Map(threadSenders.map((user) => [user.id, user]))\n\n const senderUser = await findOneWithDecryption(\n em,\n User,\n { id: message.senderUserId },\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId }\n )\n\n const senderName = typeof senderUser?.name === 'string' && senderUser.name.trim().length\n ? senderUser.name.trim()\n : null\n const senderEmail = senderUser?.email ?? null\n\n const messageType = getMessageTypeOrDefault(message.type)\n const resolvedActionData = buildResolvedMessageActions(message, objects)\n\n if (autoMarkRead) {\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n await commandBus.execute('messages.recipients.mark_read', {\n input: {\n messageId: params.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n ctx: {\n container: ctx.container,\n auth: ctx.auth ?? null,\n organizationScope: null,\n selectedOrganizationId: scope.organizationId,\n organizationIds: scope.organizationId ? [scope.organizationId] : null,\n request: req,\n },\n })\n }\n\n return Response.json({\n id: message.id,\n type: message.type,\n isDraft: message.isDraft,\n canEditDraft: message.isDraft && message.senderUserId === scope.userId,\n visibility: message.visibility,\n sourceEntityType: message.sourceEntityType,\n sourceEntityId: message.sourceEntityId,\n externalEmail: message.externalEmail,\n externalName: message.externalName,\n typeDefinition: {\n labelKey: messageType.labelKey,\n icon: messageType.icon,\n color: messageType.color,\n allowReply: messageType.allowReply ?? true,\n allowForward: messageType.allowForward ?? true,\n ui: {\n listItemComponent: messageType.ui?.listItemComponent ?? null,\n contentComponent: messageType.ui?.contentComponent ?? null,\n actionsComponent: messageType.ui?.actionsComponent ?? null,\n },\n },\n threadId: message.threadId,\n parentMessageId: message.parentMessageId,\n senderUserId: message.senderUserId,\n senderName,\n senderEmail,\n subject: message.subject,\n body: message.body,\n bodyFormat: message.bodyFormat,\n priority: message.priority,\n sentAt: message.sentAt,\n actionData: resolvedActionData,\n actionTaken: message.actionTaken,\n actionTakenAt: message.actionTakenAt,\n actionTakenByUserId: message.actionTakenByUserId,\n recipients: allRecipients.map((item) => ({\n userId: item.recipientUserId,\n type: item.recipientType,\n status: autoMarkRead && item.recipientUserId === scope.userId ? 'read' : item.status,\n readAt: autoMarkRead && item.recipientUserId === scope.userId ? readAt : item.readAt,\n })),\n objects: objects.map((item, index) => ({\n id: item.id,\n entityModule: item.entityModule,\n entityType: item.entityType,\n entityId: item.entityId,\n actionRequired: item.actionRequired,\n actionType: item.actionType,\n actionLabel: item.actionLabel,\n snapshot: item.entitySnapshot,\n preview: objectPreviews[index] ?? null,\n })),\n thread: actorVisibleThreadMessages.map((threadMessage) => {\n const sender = threadSenderMap.get(threadMessage.senderUserId)\n const threadSenderName = typeof sender?.name === 'string' && sender.name.trim().length\n ? sender.name.trim()\n : null\n\n return {\n id: threadMessage.id,\n senderUserId: threadMessage.senderUserId,\n senderName: threadSenderName,\n senderEmail: sender?.email ?? null,\n body: threadMessage.body,\n bodyFormat: threadMessage.bodyFormat,\n sentAt: threadMessage.sentAt,\n }\n }),\n isRead: recipient ? (autoMarkRead || recipient.status !== 'unread') : true,\n conversationArchived,\n conversationAllUnread,\n })\n}\n\nexport async function PATCH(req: Request, { params }: { params: { id: string } }) {\n const { ctx, scope } = await resolveMessageContext(req)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n const body = await req.json().catch(() => ({}))\n const input = updateDraftSchema.parse(body)\n\n const message = await em.findOne(Message, {\n id: params.id,\n tenantId: scope.tenantId,\n deletedAt: null,\n })\n\n if (!message) {\n return Response.json({ error: 'Message not found' }, { status: 404 })\n }\n\n if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n\n if (message.senderUserId !== scope.userId) {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n\n if (!message.isDraft) {\n return Response.json({ error: 'Only draft messages can be edited' }, { status: 409 })\n }\n\n const guardResult = await runMessageMutationGuards(\n ctx.container,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.message',\n resourceId: message.id,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: input as Record<string, unknown>,\n },\n resolveUserFeatures(ctx.auth),\n )\n if (!guardResult.ok) {\n return Response.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n try {\n const { logEntry } = await commandBus.execute('messages.messages.update_draft', {\n input: {\n ...input,\n messageId: message.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n ctx: {\n container: ctx.container,\n auth: ctx.auth ?? null,\n organizationScope: null,\n selectedOrganizationId: scope.organizationId,\n organizationIds: scope.organizationId ? [scope.organizationId] : null,\n request: req,\n },\n })\n\n const response = Response.json({ ok: true, id: message.id })\n attachOperationMetadataHeader(response, logEntry, {\n resourceKind: 'messages.message',\n resourceId: message.id,\n })\n await runMessageMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.message',\n resourceId: message.id,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return response\n } catch (error) {\n if (error instanceof Error) {\n if (error.message === 'Message type cannot be created by users') {\n return Response.json({ error: error.message }, { status: 400 })\n }\n if (error.message === 'Only draft messages can be edited') {\n return Response.json({ error: error.message }, { status: 409 })\n }\n if (error.message === 'Access denied') {\n return Response.json({ error: error.message }, { status: 403 })\n }\n }\n throw error\n }\n\n}\n\nexport async function DELETE(req: Request, { params }: { params: { id: string } }) {\n const { ctx, scope } = await resolveMessageContext(req)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n\n const message = await em.findOne(Message, {\n id: params.id,\n tenantId: scope.tenantId,\n deletedAt: null,\n })\n\n if (!message) {\n return Response.json({ error: 'Message not found' }, { status: 404 })\n }\n\n if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n\n const guardResult = await runMessageMutationGuards(\n ctx.container,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.message',\n resourceId: params.id,\n operation: 'delete',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: null,\n },\n resolveUserFeatures(ctx.auth),\n )\n if (!guardResult.ok) {\n return Response.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n try {\n const { logEntry } = await commandBus.execute('messages.messages.delete_for_actor', {\n input: {\n messageId: params.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n ctx: {\n container: ctx.container,\n auth: ctx.auth ?? null,\n organizationScope: null,\n selectedOrganizationId: scope.organizationId,\n organizationIds: scope.organizationId ? [scope.organizationId] : null,\n request: req,\n },\n })\n\n const response = Response.json({ ok: true })\n attachOperationMetadataHeader(response, logEntry, {\n resourceKind: 'messages.message',\n resourceId: params.id,\n })\n await runMessageMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n resourceKind: 'messages.message',\n resourceId: params.id,\n operation: 'delete',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return response\n } catch (error) {\n if (error instanceof Error && error.message === 'Access denied') {\n return Response.json({ error: 'Access denied' }, { status: 403 })\n }\n throw error\n }\n\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Messages',\n methods: {\n GET: {\n summary: 'Get message detail',\n responses: [\n {\n status: 200,\n description: 'Message detail with actor-visible thread items only',\n schema: messageDetailResponseSchema,\n },\n ],\n errors: [\n { status: 403, description: 'Access denied', schema: errorResponseSchema },\n { status: 404, description: 'Message not found', schema: errorResponseSchema },\n ],\n },\n PATCH: {\n summary: 'Update draft message',\n requestBody: { schema: updateDraftOpenApiSchema },\n responses: [\n { status: 200, description: 'Draft updated', schema: okResponseSchema },\n ],\n errors: [\n { status: 403, description: 'Access denied', schema: errorResponseSchema },\n { status: 404, description: 'Message not found', schema: errorResponseSchema },\n { status: 409, description: 'Only drafts can be edited', schema: errorResponseSchema },\n ],\n },\n DELETE: {\n summary: 'Delete message for current sender/recipient context',\n responses: [\n { status: 200, description: 'Message deleted', schema: okResponseSchema },\n ],\n errors: [\n { status: 403, description: 'Access denied', schema: errorResponseSchema },\n { status: 404, description: 'Message not found', schema: errorResponseSchema },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -116,7 +116,9 @@ const messageDetailResponseSchema = z.object({
116
116
  }).nullable().optional()
117
117
  })),
118
118
  thread: z.array(messageThreadItemSchema),
119
- isRead: z.boolean()
119
+ isRead: z.boolean(),
120
+ conversationArchived: z.boolean(),
121
+ conversationAllUnread: z.boolean()
120
122
  });
121
123
  const messageTokenDetailResponseSchema = z.object({
122
124
  id: z.string().uuid(),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/messages/api/openapi.ts"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport {\n attachmentIdsPayloadSchema,\n composeMessageSchema,\n executeActionSchema,\n forwardMessageSchema,\n listMessagesSchema,\n messageObjectTypesQuerySchema,\n messageActionDataSchema,\n messageActionSchema,\n messageObjectSchema,\n messageRecipientSchema,\n replyMessageSchema,\n unlinkAttachmentPayloadSchema,\n updateDraftSchema,\n} from '../data/validators'\n\nexport const messageAttachmentSchema = z.object({\n id: z.string().uuid(),\n fileName: z.string(),\n fileSize: z.number(),\n mimeType: z.string(),\n url: z.string(),\n})\n\nexport const messageListItemSchema = z.object({\n id: z.string().uuid(),\n type: z.string(),\n visibility: z.enum(['public', 'internal']).nullable().optional(),\n sourceEntityType: z.string().nullable().optional(),\n sourceEntityId: z.string().uuid().nullable().optional(),\n externalEmail: z.string().nullable().optional(),\n externalName: z.string().nullable().optional(),\n subject: z.string(),\n bodyPreview: z.string(),\n senderUserId: z.string().uuid(),\n senderName: z.string().nullable().optional(),\n senderEmail: z.string().nullable().optional(),\n priority: z.string(),\n status: z.string(),\n hasObjects: z.boolean(),\n objectCount: z.number(),\n hasAttachments: z.boolean(),\n attachmentCount: z.number(),\n recipientCount: z.number(),\n hasActions: z.boolean(),\n actionTaken: z.string().nullable().optional(),\n sentAt: z.string().nullable().optional(),\n readAt: z.string().nullable().optional(),\n threadId: z.string().uuid().nullable().optional(),\n})\n\nexport const messageThreadItemSchema = z.object({\n id: z.string().uuid(),\n senderUserId: z.string().uuid(),\n senderName: z.string().nullable().optional(),\n senderEmail: z.string().nullable().optional(),\n body: z.string(),\n bodyFormat: z.enum(['text', 'markdown']).optional(),\n sentAt: z.string().nullable().optional(),\n})\n\nexport const messageDetailResponseSchema = z.object({\n id: z.string().uuid(),\n type: z.string(),\n isDraft: z.boolean(),\n canEditDraft: z.boolean(),\n visibility: z.enum(['public', 'internal']).nullable().optional(),\n sourceEntityType: z.string().nullable().optional(),\n sourceEntityId: z.string().uuid().nullable().optional(),\n externalEmail: z.string().nullable().optional(),\n externalName: z.string().nullable().optional(),\n typeDefinition: z.object({\n labelKey: z.string(),\n icon: z.string(),\n color: z.string().optional().nullable(),\n allowReply: z.boolean(),\n allowForward: z.boolean(),\n ui: z.object({\n listItemComponent: z.string().nullable().optional(),\n contentComponent: z.string().nullable().optional(),\n actionsComponent: z.string().nullable().optional(),\n }).nullable().optional(),\n }),\n threadId: z.string().uuid().nullable().optional(),\n parentMessageId: z.string().uuid().nullable().optional(),\n senderUserId: z.string().uuid(),\n senderName: z.string().nullable().optional(),\n senderEmail: z.string().nullable().optional(),\n subject: z.string(),\n body: z.string(),\n bodyFormat: z.enum(['text', 'markdown']),\n priority: z.string(),\n sentAt: z.string().nullable().optional(),\n actionData: messageActionDataSchema.optional().nullable(),\n actionTaken: z.string().nullable().optional(),\n actionTakenAt: z.string().nullable().optional(),\n actionTakenByUserId: z.string().uuid().nullable().optional(),\n recipients: z.array(z.object({\n userId: z.string().uuid(),\n type: z.enum(['to', 'cc', 'bcc']),\n status: z.string(),\n readAt: z.string().nullable().optional(),\n })),\n objects: z.array(z.object({\n id: z.string().uuid(),\n entityModule: z.string(),\n entityType: z.string(),\n entityId: z.string().uuid(),\n actionRequired: z.boolean(),\n actionType: z.string().nullable().optional(),\n actionLabel: z.string().nullable().optional(),\n snapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n preview: z.object({\n title: z.string(),\n subtitle: z.string().optional(),\n status: z.string().optional(),\n statusColor: z.string().optional(),\n metadata: z.record(z.string(), z.string()).optional(),\n }).nullable().optional(),\n })),\n thread: z.array(messageThreadItemSchema),\n isRead: z.boolean(),\n})\n\nexport const messageTokenDetailResponseSchema = z.object({\n id: z.string().uuid(),\n type: z.string(),\n subject: z.string(),\n body: z.string(),\n bodyFormat: z.enum(['text', 'markdown']),\n priority: z.enum(['low', 'normal', 'high', 'urgent']),\n senderUserId: z.string().uuid(),\n sentAt: z.string().nullable().optional(),\n actionData: messageActionDataSchema.optional().nullable(),\n actionTaken: z.string().nullable().optional(),\n actionTakenAt: z.string().nullable().optional(),\n actionTakenByUserId: z.string().uuid().nullable().optional(),\n objects: z.array(z.object({\n id: z.string().uuid(),\n entityModule: z.string(),\n entityType: z.string(),\n entityId: z.string().uuid(),\n actionRequired: z.boolean(),\n actionType: z.string().nullable().optional(),\n actionLabel: z.string().nullable().optional(),\n snapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n })),\n requiresAuth: z.boolean(),\n recipientUserId: z.string().uuid(),\n})\n\nexport const messageTokenPreflightResponseSchema = z.object({\n requiresAuth: z.literal(true),\n})\n\nexport const messageTokenResponseSchema = z.union([\n messageTokenDetailResponseSchema,\n messageTokenPreflightResponseSchema,\n])\n\nexport const unreadCountResponseSchema = z.object({\n unreadCount: z.number(),\n})\n\nexport const messageConfirmationResponseSchema = z.object({\n messageId: z.string().uuid(),\n confirmed: z.boolean(),\n confirmedAt: z.string().nullable(),\n confirmedByUserId: z.string().uuid().nullable(),\n})\n\nexport const actionResultResponseSchema = z.object({\n ok: z.boolean(),\n actionId: z.string(),\n result: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const forwardResponseSchema = z.object({\n id: z.string().uuid(),\n})\n\nexport const forwardPreviewResponseSchema = z.object({\n subject: z.string(),\n body: z.string(),\n})\n\nexport const conversationMutationResponseSchema = z.object({\n ok: z.boolean(),\n affectedCount: z.number().int().min(0),\n})\n\nexport const composeResponseSchema = z.object({\n id: z.string().uuid(),\n threadId: z.string().uuid().nullable().optional(),\n})\n\nexport const messageAttachmentResponseSchema = z.object({\n attachments: z.array(messageAttachmentSchema),\n})\n\nexport const okResponseSchema = z.object({\n ok: z.boolean(),\n id: z.string().uuid().optional(),\n message: z.string().optional(),\n})\n\nexport const errorResponseSchema = z.object({\n error: z.string(),\n})\n\nexport const messageTypeResponseItemSchema = z.object({\n type: z.string(),\n module: z.string(),\n labelKey: z.string(),\n icon: z.string(),\n color: z.string().nullable().optional(),\n allowReply: z.boolean(),\n allowForward: z.boolean(),\n actionsExpireAfterHours: z.number().int().nullable().optional(),\n ui: z.object({\n listItemComponent: z.string().nullable().optional(),\n contentComponent: z.string().nullable().optional(),\n actionsComponent: z.string().nullable().optional(),\n }).nullable().optional(),\n})\n\nexport const messageTypeListResponseSchema = z.object({\n items: z.array(messageTypeResponseItemSchema),\n})\n\nexport const messageObjectTypeActionResponseSchema = z.object({\n id: z.string(),\n labelKey: z.string(),\n variant: z.enum(['default', 'secondary', 'destructive', 'outline']).optional(),\n icon: z.string().optional(),\n commandId: z.string().optional(),\n href: z.string().optional(),\n isTerminal: z.boolean().optional(),\n confirmRequired: z.boolean().optional(),\n confirmMessage: z.string().optional(),\n})\n\nexport const messageObjectTypeResponseItemSchema = z.object({\n module: z.string(),\n entityType: z.string(),\n labelKey: z.string(),\n icon: z.string(),\n actions: z.array(messageObjectTypeActionResponseSchema),\n})\n\nexport const messageObjectTypeListResponseSchema = z.object({\n items: z.array(messageObjectTypeResponseItemSchema),\n})\n\nexport {\n messageActionDataSchema,\n messageActionSchema,\n messageObjectSchema,\n messageRecipientSchema,\n composeMessageSchema,\n listMessagesSchema,\n forwardMessageSchema,\n replyMessageSchema,\n updateDraftSchema,\n executeActionSchema,\n messageObjectTypesQuerySchema,\n attachmentIdsPayloadSchema,\n unlinkAttachmentPayloadSchema,\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { z } from 'zod'\nimport {\n attachmentIdsPayloadSchema,\n composeMessageSchema,\n executeActionSchema,\n forwardMessageSchema,\n listMessagesSchema,\n messageObjectTypesQuerySchema,\n messageActionDataSchema,\n messageActionSchema,\n messageObjectSchema,\n messageRecipientSchema,\n replyMessageSchema,\n unlinkAttachmentPayloadSchema,\n updateDraftSchema,\n} from '../data/validators'\n\nexport const messageAttachmentSchema = z.object({\n id: z.string().uuid(),\n fileName: z.string(),\n fileSize: z.number(),\n mimeType: z.string(),\n url: z.string(),\n})\n\nexport const messageListItemSchema = z.object({\n id: z.string().uuid(),\n type: z.string(),\n visibility: z.enum(['public', 'internal']).nullable().optional(),\n sourceEntityType: z.string().nullable().optional(),\n sourceEntityId: z.string().uuid().nullable().optional(),\n externalEmail: z.string().nullable().optional(),\n externalName: z.string().nullable().optional(),\n subject: z.string(),\n bodyPreview: z.string(),\n senderUserId: z.string().uuid(),\n senderName: z.string().nullable().optional(),\n senderEmail: z.string().nullable().optional(),\n priority: z.string(),\n status: z.string(),\n hasObjects: z.boolean(),\n objectCount: z.number(),\n hasAttachments: z.boolean(),\n attachmentCount: z.number(),\n recipientCount: z.number(),\n hasActions: z.boolean(),\n actionTaken: z.string().nullable().optional(),\n sentAt: z.string().nullable().optional(),\n readAt: z.string().nullable().optional(),\n threadId: z.string().uuid().nullable().optional(),\n})\n\nexport const messageThreadItemSchema = z.object({\n id: z.string().uuid(),\n senderUserId: z.string().uuid(),\n senderName: z.string().nullable().optional(),\n senderEmail: z.string().nullable().optional(),\n body: z.string(),\n bodyFormat: z.enum(['text', 'markdown']).optional(),\n sentAt: z.string().nullable().optional(),\n})\n\nexport const messageDetailResponseSchema = z.object({\n id: z.string().uuid(),\n type: z.string(),\n isDraft: z.boolean(),\n canEditDraft: z.boolean(),\n visibility: z.enum(['public', 'internal']).nullable().optional(),\n sourceEntityType: z.string().nullable().optional(),\n sourceEntityId: z.string().uuid().nullable().optional(),\n externalEmail: z.string().nullable().optional(),\n externalName: z.string().nullable().optional(),\n typeDefinition: z.object({\n labelKey: z.string(),\n icon: z.string(),\n color: z.string().optional().nullable(),\n allowReply: z.boolean(),\n allowForward: z.boolean(),\n ui: z.object({\n listItemComponent: z.string().nullable().optional(),\n contentComponent: z.string().nullable().optional(),\n actionsComponent: z.string().nullable().optional(),\n }).nullable().optional(),\n }),\n threadId: z.string().uuid().nullable().optional(),\n parentMessageId: z.string().uuid().nullable().optional(),\n senderUserId: z.string().uuid(),\n senderName: z.string().nullable().optional(),\n senderEmail: z.string().nullable().optional(),\n subject: z.string(),\n body: z.string(),\n bodyFormat: z.enum(['text', 'markdown']),\n priority: z.string(),\n sentAt: z.string().nullable().optional(),\n actionData: messageActionDataSchema.optional().nullable(),\n actionTaken: z.string().nullable().optional(),\n actionTakenAt: z.string().nullable().optional(),\n actionTakenByUserId: z.string().uuid().nullable().optional(),\n recipients: z.array(z.object({\n userId: z.string().uuid(),\n type: z.enum(['to', 'cc', 'bcc']),\n status: z.string(),\n readAt: z.string().nullable().optional(),\n })),\n objects: z.array(z.object({\n id: z.string().uuid(),\n entityModule: z.string(),\n entityType: z.string(),\n entityId: z.string().uuid(),\n actionRequired: z.boolean(),\n actionType: z.string().nullable().optional(),\n actionLabel: z.string().nullable().optional(),\n snapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n preview: z.object({\n title: z.string(),\n subtitle: z.string().optional(),\n status: z.string().optional(),\n statusColor: z.string().optional(),\n metadata: z.record(z.string(), z.string()).optional(),\n }).nullable().optional(),\n })),\n thread: z.array(messageThreadItemSchema),\n isRead: z.boolean(),\n conversationArchived: z.boolean(),\n conversationAllUnread: z.boolean(),\n})\n\nexport const messageTokenDetailResponseSchema = z.object({\n id: z.string().uuid(),\n type: z.string(),\n subject: z.string(),\n body: z.string(),\n bodyFormat: z.enum(['text', 'markdown']),\n priority: z.enum(['low', 'normal', 'high', 'urgent']),\n senderUserId: z.string().uuid(),\n sentAt: z.string().nullable().optional(),\n actionData: messageActionDataSchema.optional().nullable(),\n actionTaken: z.string().nullable().optional(),\n actionTakenAt: z.string().nullable().optional(),\n actionTakenByUserId: z.string().uuid().nullable().optional(),\n objects: z.array(z.object({\n id: z.string().uuid(),\n entityModule: z.string(),\n entityType: z.string(),\n entityId: z.string().uuid(),\n actionRequired: z.boolean(),\n actionType: z.string().nullable().optional(),\n actionLabel: z.string().nullable().optional(),\n snapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n })),\n requiresAuth: z.boolean(),\n recipientUserId: z.string().uuid(),\n})\n\nexport const messageTokenPreflightResponseSchema = z.object({\n requiresAuth: z.literal(true),\n})\n\nexport const messageTokenResponseSchema = z.union([\n messageTokenDetailResponseSchema,\n messageTokenPreflightResponseSchema,\n])\n\nexport const unreadCountResponseSchema = z.object({\n unreadCount: z.number(),\n})\n\nexport const messageConfirmationResponseSchema = z.object({\n messageId: z.string().uuid(),\n confirmed: z.boolean(),\n confirmedAt: z.string().nullable(),\n confirmedByUserId: z.string().uuid().nullable(),\n})\n\nexport const actionResultResponseSchema = z.object({\n ok: z.boolean(),\n actionId: z.string(),\n result: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const forwardResponseSchema = z.object({\n id: z.string().uuid(),\n})\n\nexport const forwardPreviewResponseSchema = z.object({\n subject: z.string(),\n body: z.string(),\n})\n\nexport const conversationMutationResponseSchema = z.object({\n ok: z.boolean(),\n affectedCount: z.number().int().min(0),\n})\n\nexport const composeResponseSchema = z.object({\n id: z.string().uuid(),\n threadId: z.string().uuid().nullable().optional(),\n})\n\nexport const messageAttachmentResponseSchema = z.object({\n attachments: z.array(messageAttachmentSchema),\n})\n\nexport const okResponseSchema = z.object({\n ok: z.boolean(),\n id: z.string().uuid().optional(),\n message: z.string().optional(),\n})\n\nexport const errorResponseSchema = z.object({\n error: z.string(),\n})\n\nexport const messageTypeResponseItemSchema = z.object({\n type: z.string(),\n module: z.string(),\n labelKey: z.string(),\n icon: z.string(),\n color: z.string().nullable().optional(),\n allowReply: z.boolean(),\n allowForward: z.boolean(),\n actionsExpireAfterHours: z.number().int().nullable().optional(),\n ui: z.object({\n listItemComponent: z.string().nullable().optional(),\n contentComponent: z.string().nullable().optional(),\n actionsComponent: z.string().nullable().optional(),\n }).nullable().optional(),\n})\n\nexport const messageTypeListResponseSchema = z.object({\n items: z.array(messageTypeResponseItemSchema),\n})\n\nexport const messageObjectTypeActionResponseSchema = z.object({\n id: z.string(),\n labelKey: z.string(),\n variant: z.enum(['default', 'secondary', 'destructive', 'outline']).optional(),\n icon: z.string().optional(),\n commandId: z.string().optional(),\n href: z.string().optional(),\n isTerminal: z.boolean().optional(),\n confirmRequired: z.boolean().optional(),\n confirmMessage: z.string().optional(),\n})\n\nexport const messageObjectTypeResponseItemSchema = z.object({\n module: z.string(),\n entityType: z.string(),\n labelKey: z.string(),\n icon: z.string(),\n actions: z.array(messageObjectTypeActionResponseSchema),\n})\n\nexport const messageObjectTypeListResponseSchema = z.object({\n items: z.array(messageObjectTypeResponseItemSchema),\n})\n\nexport {\n messageActionDataSchema,\n messageActionSchema,\n messageObjectSchema,\n messageRecipientSchema,\n composeMessageSchema,\n listMessagesSchema,\n forwardMessageSchema,\n replyMessageSchema,\n updateDraftSchema,\n executeActionSchema,\n messageObjectTypesQuerySchema,\n attachmentIdsPayloadSchema,\n unlinkAttachmentPayloadSchema,\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -182,6 +182,81 @@ const markConversationUnreadForActorCommand = {
182
182
  return { ok: true, affectedCount: markedIds.length };
183
183
  }
184
184
  };
185
+ const unarchiveConversationForActorCommand = {
186
+ id: "messages.conversation.unarchive_for_actor",
187
+ async execute(rawInput, ctx) {
188
+ const input = conversationCommandSchema.parse(rawInput);
189
+ const em = ctx.container.resolve("em").fork();
190
+ const scope = await resolveConversationScope(em, input);
191
+ const messageIdsToUnarchive = scope.messageIds.filter((messageId) => scope.recipientMessageIds.has(messageId));
192
+ if (messageIdsToUnarchive.length === 0) {
193
+ return { ok: true, affectedCount: 0 };
194
+ }
195
+ const unarchivedIds = [];
196
+ await em.transactional(async (trx) => {
197
+ const recipients = await trx.find(MessageRecipient, {
198
+ messageId: { $in: messageIdsToUnarchive },
199
+ recipientUserId: input.userId,
200
+ deletedAt: null
201
+ });
202
+ for (const recipient of recipients) {
203
+ if (recipient.status === "archived" || recipient.archivedAt !== null) {
204
+ recipient.archivedAt = null;
205
+ recipient.status = recipient.readAt ? "read" : "unread";
206
+ unarchivedIds.push(recipient.messageId);
207
+ }
208
+ }
209
+ });
210
+ for (const messageId of unarchivedIds) {
211
+ await emitMessagesEvent("messages.message.unarchived", {
212
+ messageId,
213
+ recipientUserId: input.userId,
214
+ userId: input.userId,
215
+ tenantId: input.tenantId,
216
+ organizationId: input.organizationId
217
+ }, { persistent: true });
218
+ }
219
+ return { ok: true, affectedCount: unarchivedIds.length };
220
+ }
221
+ };
222
+ const markConversationReadForActorCommand = {
223
+ id: "messages.conversation.mark_read_for_actor",
224
+ async execute(rawInput, ctx) {
225
+ const input = conversationCommandSchema.parse(rawInput);
226
+ const em = ctx.container.resolve("em").fork();
227
+ const scope = await resolveConversationScope(em, input);
228
+ const messageIdsToMarkRead = scope.messageIds.filter((messageId) => scope.recipientMessageIds.has(messageId));
229
+ if (messageIdsToMarkRead.length === 0) {
230
+ return { ok: true, affectedCount: 0 };
231
+ }
232
+ const readAt = /* @__PURE__ */ new Date();
233
+ const markedIds = [];
234
+ await em.transactional(async (trx) => {
235
+ const recipients = await trx.find(MessageRecipient, {
236
+ messageId: { $in: messageIdsToMarkRead },
237
+ recipientUserId: input.userId,
238
+ deletedAt: null
239
+ });
240
+ for (const recipient of recipients) {
241
+ if (recipient.status === "unread") {
242
+ recipient.status = "read";
243
+ recipient.readAt = readAt;
244
+ markedIds.push(recipient.messageId);
245
+ }
246
+ }
247
+ });
248
+ for (const messageId of markedIds) {
249
+ await emitMessagesEvent("messages.message.read", {
250
+ messageId,
251
+ recipientUserId: input.userId,
252
+ userId: input.userId,
253
+ tenantId: input.tenantId,
254
+ organizationId: input.organizationId
255
+ }, { persistent: true });
256
+ }
257
+ return { ok: true, affectedCount: markedIds.length };
258
+ }
259
+ };
185
260
  const deleteConversationForActorCommand = {
186
261
  id: "messages.conversation.delete_for_actor",
187
262
  async execute(rawInput, ctx) {
@@ -236,6 +311,8 @@ const deleteConversationForActorCommand = {
236
311
  }
237
312
  };
238
313
  registerCommand(archiveConversationForActorCommand);
314
+ registerCommand(unarchiveConversationForActorCommand);
239
315
  registerCommand(markConversationUnreadForActorCommand);
316
+ registerCommand(markConversationReadForActorCommand);
240
317
  registerCommand(deleteConversationForActorCommand);
241
318
  //# sourceMappingURL=conversation.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/messages/commands/conversation.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 { Message, MessageRecipient } from '../data/entities'\nimport { emitMessagesEvent } from '../events'\nimport { assertOrganizationAccess, type MessageScopeInput } from './shared'\n\nconst conversationCommandSchema = z.object({\n anchorMessageId: z.string().uuid(),\n tenantId: z.string().uuid(),\n organizationId: z.string().uuid().nullable(),\n userId: z.string().uuid(),\n})\n\ntype ConversationCommandInput = z.infer<typeof conversationCommandSchema>\n\ntype ConversationScope = {\n anchorMessageId: string\n messageIds: string[]\n recipientMessageIds: Set<string>\n senderMessageIds: Set<string>\n}\n\nasync function resolveConversationScope(\n em: EntityManager,\n input: ConversationCommandInput,\n): Promise<ConversationScope> {\n const anchorMessage = await em.findOne(Message, {\n id: input.anchorMessageId,\n tenantId: input.tenantId,\n deletedAt: null,\n })\n\n if (!anchorMessage) throw new Error('Message not found')\n assertOrganizationAccess(input as MessageScopeInput, anchorMessage)\n\n const anchorRecipient = await em.findOne(MessageRecipient, {\n messageId: input.anchorMessageId,\n recipientUserId: input.userId,\n deletedAt: null,\n })\n\n const canAccessAnchor = anchorMessage.senderUserId === input.userId || Boolean(anchorRecipient)\n if (!canAccessAnchor) throw new Error('Access denied')\n\n const threadId = anchorMessage.threadId ?? anchorMessage.id\n const conversationMessages = await em.find(\n Message,\n {\n threadId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n isDraft: false,\n },\n {\n orderBy: {\n sentAt: 'ASC',\n createdAt: 'ASC',\n id: 'ASC',\n },\n },\n )\n\n const messagesById = new Map<string, Message>(conversationMessages.map((message) => [message.id, message]))\n messagesById.set(anchorMessage.id, anchorMessage)\n\n if (anchorMessage.threadId && !messagesById.has(anchorMessage.threadId)) {\n const threadRoot = await em.findOne(Message, {\n id: anchorMessage.threadId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n isDraft: false,\n })\n if (threadRoot) {\n messagesById.set(threadRoot.id, threadRoot)\n }\n }\n\n let parentMessageId = anchorMessage.parentMessageId ?? null\n while (parentMessageId) {\n if (messagesById.has(parentMessageId)) break\n const parentMessage = await em.findOne(Message, {\n id: parentMessageId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n isDraft: false,\n })\n if (!parentMessage) break\n messagesById.set(parentMessage.id, parentMessage)\n parentMessageId = parentMessage.parentMessageId ?? null\n }\n\n let frontier = Array.from(messagesById.keys())\n while (frontier.length > 0) {\n const children = await em.find(Message, {\n parentMessageId: { $in: frontier },\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n isDraft: false,\n })\n\n const nextFrontier: string[] = []\n for (const child of children) {\n if (messagesById.has(child.id)) continue\n messagesById.set(child.id, child)\n nextFrontier.push(child.id)\n }\n frontier = nextFrontier\n }\n\n const scopedMessages = Array.from(messagesById.values())\n const messageIds = scopedMessages.map((message) => message.id)\n const recipientRows = messageIds.length > 0\n ? await em.find(MessageRecipient, {\n messageId: { $in: messageIds },\n recipientUserId: input.userId,\n deletedAt: null,\n })\n : []\n\n const recipientMessageIds = new Set(recipientRows.map((item) => item.messageId))\n const senderMessageIds = new Set(\n scopedMessages\n .filter((item) => item.senderUserId === input.userId)\n .map((item) => item.id),\n )\n\n const visibleMessageIds = scopedMessages\n .map((item) => item.id)\n .filter((messageId) => recipientMessageIds.has(messageId) || senderMessageIds.has(messageId))\n\n if (visibleMessageIds.length === 0) throw new Error('Access denied')\n\n return {\n anchorMessageId: anchorMessage.id,\n messageIds: visibleMessageIds,\n recipientMessageIds,\n senderMessageIds,\n }\n}\n\nconst archiveConversationForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {\n id: 'messages.conversation.archive_for_actor',\n async execute(rawInput, ctx) {\n const input = conversationCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = await resolveConversationScope(em, input)\n const messageIdsToArchive = scope.messageIds.filter((messageId) => scope.recipientMessageIds.has(messageId))\n\n if (messageIdsToArchive.length === 0) {\n return { ok: true, affectedCount: 0 }\n }\n\n const archivedAt = new Date()\n const archivedIds: string[] = []\n await em.transactional(async (trx) => {\n const recipients = await trx.find(MessageRecipient, {\n messageId: { $in: messageIdsToArchive },\n recipientUserId: input.userId,\n deletedAt: null,\n })\n for (const recipient of recipients) {\n if (recipient.status !== 'archived' || recipient.archivedAt === null) {\n recipient.archivedAt = archivedAt\n recipient.status = 'archived'\n archivedIds.push(recipient.messageId)\n }\n }\n })\n\n for (const messageId of archivedIds) {\n await emitMessagesEvent('messages.message.archived', {\n messageId,\n recipientUserId: input.userId,\n userId: input.userId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n }, { persistent: true })\n }\n\n return { ok: true, affectedCount: archivedIds.length }\n },\n}\n\nconst markConversationUnreadForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {\n id: 'messages.conversation.mark_unread_for_actor',\n async execute(rawInput, ctx) {\n const input = conversationCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = await resolveConversationScope(em, input)\n const messageIdsToMarkUnread = scope.messageIds.filter((messageId) => scope.recipientMessageIds.has(messageId))\n\n if (messageIdsToMarkUnread.length === 0) {\n return { ok: true, affectedCount: 0 }\n }\n\n const markedIds: string[] = []\n await em.transactional(async (trx) => {\n const recipients = await trx.find(MessageRecipient, {\n messageId: { $in: messageIdsToMarkUnread },\n recipientUserId: input.userId,\n deletedAt: null,\n })\n for (const recipient of recipients) {\n if (recipient.status !== 'unread' || recipient.readAt !== null) {\n recipient.status = 'unread'\n recipient.readAt = null\n markedIds.push(recipient.messageId)\n }\n }\n })\n\n for (const messageId of markedIds) {\n await emitMessagesEvent('messages.message.marked_unread', {\n messageId,\n recipientUserId: input.userId,\n userId: input.userId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n }, { persistent: true })\n }\n\n return { ok: true, affectedCount: markedIds.length }\n },\n}\n\ntype DeletedTarget = { messageId: string; target: 'sender' | 'recipient' }\n\nconst deleteConversationForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {\n id: 'messages.conversation.delete_for_actor',\n async execute(rawInput, ctx) {\n const input = conversationCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = await resolveConversationScope(em, input)\n const messageIdsToDelete = scope.messageIds.filter(\n (messageId) => scope.recipientMessageIds.has(messageId) || scope.senderMessageIds.has(messageId),\n )\n\n if (messageIdsToDelete.length === 0) {\n return { ok: true, affectedCount: 0 }\n }\n\n const deletedNow = new Date()\n const deletedTargets: DeletedTarget[] = []\n await em.transactional(async (trx) => {\n for (const messageId of messageIdsToDelete) {\n const recipient = await trx.findOne(MessageRecipient, {\n messageId,\n recipientUserId: input.userId,\n deletedAt: null,\n })\n if (recipient) {\n recipient.status = 'deleted'\n recipient.deletedAt = deletedNow\n deletedTargets.push({ messageId, target: 'recipient' })\n continue\n }\n if (scope.senderMessageIds.has(messageId)) {\n const message = await trx.findOne(Message, {\n id: messageId,\n tenantId: input.tenantId,\n deletedAt: null,\n })\n if (message && message.senderUserId === input.userId) {\n message.deletedAt = deletedNow\n deletedTargets.push({ messageId, target: 'sender' })\n }\n }\n }\n })\n\n for (const { messageId, target } of deletedTargets) {\n await emitMessagesEvent('messages.message.deleted', {\n messageId,\n actorUserId: input.userId,\n recipientUserId: input.userId,\n target,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n }, { persistent: true })\n }\n\n return { ok: true, affectedCount: deletedTargets.length }\n },\n}\n\nregisterCommand(archiveConversationForActorCommand)\nregisterCommand(markConversationUnreadForActorCommand)\nregisterCommand(deleteConversationForActorCommand)\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { z } from 'zod'\nimport { registerCommand, type CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { Message, MessageRecipient } from '../data/entities'\nimport { emitMessagesEvent } from '../events'\nimport { assertOrganizationAccess, type MessageScopeInput } from './shared'\n\nconst conversationCommandSchema = z.object({\n anchorMessageId: z.string().uuid(),\n tenantId: z.string().uuid(),\n organizationId: z.string().uuid().nullable(),\n userId: z.string().uuid(),\n})\n\ntype ConversationCommandInput = z.infer<typeof conversationCommandSchema>\n\ntype ConversationScope = {\n anchorMessageId: string\n messageIds: string[]\n recipientMessageIds: Set<string>\n senderMessageIds: Set<string>\n}\n\nasync function resolveConversationScope(\n em: EntityManager,\n input: ConversationCommandInput,\n): Promise<ConversationScope> {\n const anchorMessage = await em.findOne(Message, {\n id: input.anchorMessageId,\n tenantId: input.tenantId,\n deletedAt: null,\n })\n\n if (!anchorMessage) throw new Error('Message not found')\n assertOrganizationAccess(input as MessageScopeInput, anchorMessage)\n\n const anchorRecipient = await em.findOne(MessageRecipient, {\n messageId: input.anchorMessageId,\n recipientUserId: input.userId,\n deletedAt: null,\n })\n\n const canAccessAnchor = anchorMessage.senderUserId === input.userId || Boolean(anchorRecipient)\n if (!canAccessAnchor) throw new Error('Access denied')\n\n const threadId = anchorMessage.threadId ?? anchorMessage.id\n const conversationMessages = await em.find(\n Message,\n {\n threadId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n isDraft: false,\n },\n {\n orderBy: {\n sentAt: 'ASC',\n createdAt: 'ASC',\n id: 'ASC',\n },\n },\n )\n\n const messagesById = new Map<string, Message>(conversationMessages.map((message) => [message.id, message]))\n messagesById.set(anchorMessage.id, anchorMessage)\n\n if (anchorMessage.threadId && !messagesById.has(anchorMessage.threadId)) {\n const threadRoot = await em.findOne(Message, {\n id: anchorMessage.threadId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n isDraft: false,\n })\n if (threadRoot) {\n messagesById.set(threadRoot.id, threadRoot)\n }\n }\n\n let parentMessageId = anchorMessage.parentMessageId ?? null\n while (parentMessageId) {\n if (messagesById.has(parentMessageId)) break\n const parentMessage = await em.findOne(Message, {\n id: parentMessageId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n isDraft: false,\n })\n if (!parentMessage) break\n messagesById.set(parentMessage.id, parentMessage)\n parentMessageId = parentMessage.parentMessageId ?? null\n }\n\n let frontier = Array.from(messagesById.keys())\n while (frontier.length > 0) {\n const children = await em.find(Message, {\n parentMessageId: { $in: frontier },\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n isDraft: false,\n })\n\n const nextFrontier: string[] = []\n for (const child of children) {\n if (messagesById.has(child.id)) continue\n messagesById.set(child.id, child)\n nextFrontier.push(child.id)\n }\n frontier = nextFrontier\n }\n\n const scopedMessages = Array.from(messagesById.values())\n const messageIds = scopedMessages.map((message) => message.id)\n const recipientRows = messageIds.length > 0\n ? await em.find(MessageRecipient, {\n messageId: { $in: messageIds },\n recipientUserId: input.userId,\n deletedAt: null,\n })\n : []\n\n const recipientMessageIds = new Set(recipientRows.map((item) => item.messageId))\n const senderMessageIds = new Set(\n scopedMessages\n .filter((item) => item.senderUserId === input.userId)\n .map((item) => item.id),\n )\n\n const visibleMessageIds = scopedMessages\n .map((item) => item.id)\n .filter((messageId) => recipientMessageIds.has(messageId) || senderMessageIds.has(messageId))\n\n if (visibleMessageIds.length === 0) throw new Error('Access denied')\n\n return {\n anchorMessageId: anchorMessage.id,\n messageIds: visibleMessageIds,\n recipientMessageIds,\n senderMessageIds,\n }\n}\n\nconst archiveConversationForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {\n id: 'messages.conversation.archive_for_actor',\n async execute(rawInput, ctx) {\n const input = conversationCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = await resolveConversationScope(em, input)\n const messageIdsToArchive = scope.messageIds.filter((messageId) => scope.recipientMessageIds.has(messageId))\n\n if (messageIdsToArchive.length === 0) {\n return { ok: true, affectedCount: 0 }\n }\n\n const archivedAt = new Date()\n const archivedIds: string[] = []\n await em.transactional(async (trx) => {\n const recipients = await trx.find(MessageRecipient, {\n messageId: { $in: messageIdsToArchive },\n recipientUserId: input.userId,\n deletedAt: null,\n })\n for (const recipient of recipients) {\n if (recipient.status !== 'archived' || recipient.archivedAt === null) {\n recipient.archivedAt = archivedAt\n recipient.status = 'archived'\n archivedIds.push(recipient.messageId)\n }\n }\n })\n\n for (const messageId of archivedIds) {\n await emitMessagesEvent('messages.message.archived', {\n messageId,\n recipientUserId: input.userId,\n userId: input.userId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n }, { persistent: true })\n }\n\n return { ok: true, affectedCount: archivedIds.length }\n },\n}\n\nconst markConversationUnreadForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {\n id: 'messages.conversation.mark_unread_for_actor',\n async execute(rawInput, ctx) {\n const input = conversationCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = await resolveConversationScope(em, input)\n const messageIdsToMarkUnread = scope.messageIds.filter((messageId) => scope.recipientMessageIds.has(messageId))\n\n if (messageIdsToMarkUnread.length === 0) {\n return { ok: true, affectedCount: 0 }\n }\n\n const markedIds: string[] = []\n await em.transactional(async (trx) => {\n const recipients = await trx.find(MessageRecipient, {\n messageId: { $in: messageIdsToMarkUnread },\n recipientUserId: input.userId,\n deletedAt: null,\n })\n for (const recipient of recipients) {\n if (recipient.status !== 'unread' || recipient.readAt !== null) {\n recipient.status = 'unread'\n recipient.readAt = null\n markedIds.push(recipient.messageId)\n }\n }\n })\n\n for (const messageId of markedIds) {\n await emitMessagesEvent('messages.message.marked_unread', {\n messageId,\n recipientUserId: input.userId,\n userId: input.userId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n }, { persistent: true })\n }\n\n return { ok: true, affectedCount: markedIds.length }\n },\n}\n\nconst unarchiveConversationForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {\n id: 'messages.conversation.unarchive_for_actor',\n async execute(rawInput, ctx) {\n const input = conversationCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = await resolveConversationScope(em, input)\n const messageIdsToUnarchive = scope.messageIds.filter((messageId) => scope.recipientMessageIds.has(messageId))\n\n if (messageIdsToUnarchive.length === 0) {\n return { ok: true, affectedCount: 0 }\n }\n\n const unarchivedIds: string[] = []\n await em.transactional(async (trx) => {\n const recipients = await trx.find(MessageRecipient, {\n messageId: { $in: messageIdsToUnarchive },\n recipientUserId: input.userId,\n deletedAt: null,\n })\n for (const recipient of recipients) {\n if (recipient.status === 'archived' || recipient.archivedAt !== null) {\n recipient.archivedAt = null\n recipient.status = recipient.readAt ? 'read' : 'unread'\n unarchivedIds.push(recipient.messageId)\n }\n }\n })\n\n for (const messageId of unarchivedIds) {\n await emitMessagesEvent('messages.message.unarchived', {\n messageId,\n recipientUserId: input.userId,\n userId: input.userId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n }, { persistent: true })\n }\n\n return { ok: true, affectedCount: unarchivedIds.length }\n },\n}\n\nconst markConversationReadForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {\n id: 'messages.conversation.mark_read_for_actor',\n async execute(rawInput, ctx) {\n const input = conversationCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = await resolveConversationScope(em, input)\n const messageIdsToMarkRead = scope.messageIds.filter((messageId) => scope.recipientMessageIds.has(messageId))\n\n if (messageIdsToMarkRead.length === 0) {\n return { ok: true, affectedCount: 0 }\n }\n\n const readAt = new Date()\n const markedIds: string[] = []\n await em.transactional(async (trx) => {\n const recipients = await trx.find(MessageRecipient, {\n messageId: { $in: messageIdsToMarkRead },\n recipientUserId: input.userId,\n deletedAt: null,\n })\n for (const recipient of recipients) {\n if (recipient.status === 'unread') {\n recipient.status = 'read'\n recipient.readAt = readAt\n markedIds.push(recipient.messageId)\n }\n }\n })\n\n for (const messageId of markedIds) {\n await emitMessagesEvent('messages.message.read', {\n messageId,\n recipientUserId: input.userId,\n userId: input.userId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n }, { persistent: true })\n }\n\n return { ok: true, affectedCount: markedIds.length }\n },\n}\n\ntype DeletedTarget = { messageId: string; target: 'sender' | 'recipient' }\n\nconst deleteConversationForActorCommand: CommandHandler<unknown, { ok: true; affectedCount: number }> = {\n id: 'messages.conversation.delete_for_actor',\n async execute(rawInput, ctx) {\n const input = conversationCommandSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = await resolveConversationScope(em, input)\n const messageIdsToDelete = scope.messageIds.filter(\n (messageId) => scope.recipientMessageIds.has(messageId) || scope.senderMessageIds.has(messageId),\n )\n\n if (messageIdsToDelete.length === 0) {\n return { ok: true, affectedCount: 0 }\n }\n\n const deletedNow = new Date()\n const deletedTargets: DeletedTarget[] = []\n await em.transactional(async (trx) => {\n for (const messageId of messageIdsToDelete) {\n const recipient = await trx.findOne(MessageRecipient, {\n messageId,\n recipientUserId: input.userId,\n deletedAt: null,\n })\n if (recipient) {\n recipient.status = 'deleted'\n recipient.deletedAt = deletedNow\n deletedTargets.push({ messageId, target: 'recipient' })\n continue\n }\n if (scope.senderMessageIds.has(messageId)) {\n const message = await trx.findOne(Message, {\n id: messageId,\n tenantId: input.tenantId,\n deletedAt: null,\n })\n if (message && message.senderUserId === input.userId) {\n message.deletedAt = deletedNow\n deletedTargets.push({ messageId, target: 'sender' })\n }\n }\n }\n })\n\n for (const { messageId, target } of deletedTargets) {\n await emitMessagesEvent('messages.message.deleted', {\n messageId,\n actorUserId: input.userId,\n recipientUserId: input.userId,\n target,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n }, { persistent: true })\n }\n\n return { ok: true, affectedCount: deletedTargets.length }\n },\n}\n\nregisterCommand(archiveConversationForActorCommand)\nregisterCommand(unarchiveConversationForActorCommand)\nregisterCommand(markConversationUnreadForActorCommand)\nregisterCommand(markConversationReadForActorCommand)\nregisterCommand(deleteConversationForActorCommand)\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -189,6 +189,8 @@ function MessageDetailPageClient({ id }) {
189
189
  const firstConversationMessageId = state.conversationItems[0]?.id ?? null;
190
190
  const latestConversationMessageId = state.conversationItems[state.conversationItems.length - 1]?.id ?? null;
191
191
  const canRunConversationActions = Boolean(firstConversationMessageId);
192
+ const conversationArchived = Boolean(detail.conversationArchived);
193
+ const conversationAllUnread = Boolean(detail.conversationAllUnread);
192
194
  return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
193
195
  /* @__PURE__ */ jsx(
194
196
  MainMessageHeader,
@@ -197,6 +199,8 @@ function MessageDetailPageClient({ id }) {
197
199
  priority: detail.priority ?? "normal",
198
200
  canReply: !detail.isDraft && detail.typeDefinition.allowReply && Boolean(firstConversationMessageId),
199
201
  canForwardAll: !detail.isDraft && detail.typeDefinition.allowForward && Boolean(latestConversationMessageId),
202
+ conversationArchived,
203
+ conversationAllUnread,
200
204
  actionsDisabled: Boolean(state.activeConversationAction),
201
205
  activeActionId: state.activeConversationAction,
202
206
  onReply: () => {
@@ -213,13 +217,21 @@ function MessageDetailPageClient({ id }) {
213
217
  messageId: latestConversationMessageId
214
218
  });
215
219
  },
216
- onArchiveConversation: () => {
220
+ onToggleArchiveConversation: () => {
217
221
  if (!canRunConversationActions) return;
218
- void state.archiveConversation(firstConversationMessageId ?? void 0);
222
+ if (conversationArchived) {
223
+ void state.unarchiveConversation(firstConversationMessageId ?? void 0);
224
+ } else {
225
+ void state.archiveConversation(firstConversationMessageId ?? void 0);
226
+ }
219
227
  },
220
- onMarkAllUnread: () => {
228
+ onToggleReadConversation: () => {
221
229
  if (!canRunConversationActions) return;
222
- void state.markConversationUnread(firstConversationMessageId ?? void 0);
230
+ if (conversationAllUnread) {
231
+ void state.markConversationRead(firstConversationMessageId ?? void 0);
232
+ } else {
233
+ void state.markConversationUnread(firstConversationMessageId ?? void 0);
234
+ }
223
235
  },
224
236
  onDeleteConversation: () => {
225
237
  if (!canRunConversationActions || state.activeConversationAction) return;