@open-mercato/core 0.4.5-develop-754ef4d2f0 → 0.4.5-develop-9f9549ebc8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (434) hide show
  1. package/dist/generated/entities/message/index.js +65 -0
  2. package/dist/generated/entities/message/index.js.map +7 -0
  3. package/dist/generated/entities/message_access_token/index.js +19 -0
  4. package/dist/generated/entities/message_access_token/index.js.map +7 -0
  5. package/dist/generated/entities/message_confirmation/index.js +21 -0
  6. package/dist/generated/entities/message_confirmation/index.js.map +7 -0
  7. package/dist/generated/entities/message_object/index.js +23 -0
  8. package/dist/generated/entities/message_object/index.js.map +7 -0
  9. package/dist/generated/entities/message_recipient/index.js +31 -0
  10. package/dist/generated/entities/message_recipient/index.js.map +7 -0
  11. package/dist/generated/entities.ids.generated.js +8 -0
  12. package/dist/generated/entities.ids.generated.js.map +2 -2
  13. package/dist/generated/entity-fields-registry.js +10 -0
  14. package/dist/generated/entity-fields-registry.js.map +2 -2
  15. package/dist/modules/auth/components/AclEditor.js +4 -2
  16. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  17. package/dist/modules/auth/frontend/reset.js +3 -3
  18. package/dist/modules/auth/frontend/reset.js.map +2 -2
  19. package/dist/modules/customers/backend/customers/deals/[id]/page.js +27 -8
  20. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  21. package/dist/modules/customers/lib/messageObjectPreviews.js +131 -0
  22. package/dist/modules/customers/lib/messageObjectPreviews.js.map +7 -0
  23. package/dist/modules/customers/message-objects.js +71 -0
  24. package/dist/modules/customers/message-objects.js.map +7 -0
  25. package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js +51 -0
  26. package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js.map +7 -0
  27. package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js +35 -0
  28. package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js.map +7 -0
  29. package/dist/modules/customers/widgets/messages/index.js +7 -0
  30. package/dist/modules/customers/widgets/messages/index.js.map +7 -0
  31. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +35 -6
  32. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
  33. package/dist/modules/messages/acl.js +15 -0
  34. package/dist/modules/messages/acl.js.map +7 -0
  35. package/dist/modules/messages/api/[id]/actions/[actionId]/route.js +92 -0
  36. package/dist/modules/messages/api/[id]/actions/[actionId]/route.js.map +7 -0
  37. package/dist/modules/messages/api/[id]/archive/route.js +120 -0
  38. package/dist/modules/messages/api/[id]/archive/route.js.map +7 -0
  39. package/dist/modules/messages/api/[id]/attachments/route.js +195 -0
  40. package/dist/modules/messages/api/[id]/attachments/route.js.map +7 -0
  41. package/dist/modules/messages/api/[id]/confirmation/route.js +67 -0
  42. package/dist/modules/messages/api/[id]/confirmation/route.js.map +7 -0
  43. package/dist/modules/messages/api/[id]/conversation/archive/route.js +68 -0
  44. package/dist/modules/messages/api/[id]/conversation/archive/route.js.map +7 -0
  45. package/dist/modules/messages/api/[id]/conversation/read/route.js +68 -0
  46. package/dist/modules/messages/api/[id]/conversation/read/route.js.map +7 -0
  47. package/dist/modules/messages/api/[id]/conversation/route.js +68 -0
  48. package/dist/modules/messages/api/[id]/conversation/route.js.map +7 -0
  49. package/dist/modules/messages/api/[id]/forward/route.js +85 -0
  50. package/dist/modules/messages/api/[id]/forward/route.js.map +7 -0
  51. package/dist/modules/messages/api/[id]/forward-preview/route.js +70 -0
  52. package/dist/modules/messages/api/[id]/forward-preview/route.js.map +7 -0
  53. package/dist/modules/messages/api/[id]/read/route.js +120 -0
  54. package/dist/modules/messages/api/[id]/read/route.js.map +7 -0
  55. package/dist/modules/messages/api/[id]/reply/route.js +87 -0
  56. package/dist/modules/messages/api/[id]/reply/route.js.map +7 -0
  57. package/dist/modules/messages/api/[id]/route.js +350 -0
  58. package/dist/modules/messages/api/[id]/route.js.map +7 -0
  59. package/dist/modules/messages/api/object-types/route.js +54 -0
  60. package/dist/modules/messages/api/object-types/route.js.map +7 -0
  61. package/dist/modules/messages/api/openapi.js +261 -0
  62. package/dist/modules/messages/api/openapi.js.map +7 -0
  63. package/dist/modules/messages/api/route.js +262 -0
  64. package/dist/modules/messages/api/route.js.map +7 -0
  65. package/dist/modules/messages/api/token/[token]/route.js +99 -0
  66. package/dist/modules/messages/api/token/[token]/route.js.map +7 -0
  67. package/dist/modules/messages/api/types/route.js +40 -0
  68. package/dist/modules/messages/api/types/route.js.map +7 -0
  69. package/dist/modules/messages/api/unread-count/route.js +43 -0
  70. package/dist/modules/messages/api/unread-count/route.js.map +7 -0
  71. package/dist/modules/messages/backend/messages/[id]/page.js +10 -0
  72. package/dist/modules/messages/backend/messages/[id]/page.js.map +7 -0
  73. package/dist/modules/messages/backend/messages/[id]/page.meta.js +16 -0
  74. package/dist/modules/messages/backend/messages/[id]/page.meta.js.map +7 -0
  75. package/dist/modules/messages/backend/messages/compose/page.js +10 -0
  76. package/dist/modules/messages/backend/messages/compose/page.js.map +7 -0
  77. package/dist/modules/messages/backend/messages/compose/page.meta.js +17 -0
  78. package/dist/modules/messages/backend/messages/compose/page.meta.js.map +7 -0
  79. package/dist/modules/messages/backend/page.js +10 -0
  80. package/dist/modules/messages/backend/page.js.map +7 -0
  81. package/dist/modules/messages/backend/page.meta.js +33 -0
  82. package/dist/modules/messages/backend/page.meta.js.map +7 -0
  83. package/dist/modules/messages/commands/actions.js +265 -0
  84. package/dist/modules/messages/commands/actions.js.map +7 -0
  85. package/dist/modules/messages/commands/attachments.js +217 -0
  86. package/dist/modules/messages/commands/attachments.js.map +7 -0
  87. package/dist/modules/messages/commands/confirmations.js +151 -0
  88. package/dist/modules/messages/commands/confirmations.js.map +7 -0
  89. package/dist/modules/messages/commands/conversation.js +240 -0
  90. package/dist/modules/messages/commands/conversation.js.map +7 -0
  91. package/dist/modules/messages/commands/messages.js +748 -0
  92. package/dist/modules/messages/commands/messages.js.map +7 -0
  93. package/dist/modules/messages/commands/recipients.js +259 -0
  94. package/dist/modules/messages/commands/recipients.js.map +7 -0
  95. package/dist/modules/messages/commands/shared.js +258 -0
  96. package/dist/modules/messages/commands/shared.js.map +7 -0
  97. package/dist/modules/messages/commands/tokens.js +69 -0
  98. package/dist/modules/messages/commands/tokens.js.map +7 -0
  99. package/dist/modules/messages/components/ComposeMessagePageClient.js +24 -0
  100. package/dist/modules/messages/components/ComposeMessagePageClient.js.map +7 -0
  101. package/dist/modules/messages/components/MessageDetailPageClient.js +261 -0
  102. package/dist/modules/messages/components/MessageDetailPageClient.js.map +7 -0
  103. package/dist/modules/messages/components/MessagesInboxPageClient.js +390 -0
  104. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +7 -0
  105. package/dist/modules/messages/components/confirmation/MessageConfirmationActions.js +31 -0
  106. package/dist/modules/messages/components/confirmation/MessageConfirmationActions.js.map +7 -0
  107. package/dist/modules/messages/components/confirmation/MessageConfirmationContent.js +69 -0
  108. package/dist/modules/messages/components/confirmation/MessageConfirmationContent.js.map +7 -0
  109. package/dist/modules/messages/components/defaults/DefaultMessageActions.js +31 -0
  110. package/dist/modules/messages/components/defaults/DefaultMessageActions.js.map +7 -0
  111. package/dist/modules/messages/components/defaults/DefaultMessageContent.js +19 -0
  112. package/dist/modules/messages/components/defaults/DefaultMessageContent.js.map +7 -0
  113. package/dist/modules/messages/components/defaults/DefaultMessageListItem.js +90 -0
  114. package/dist/modules/messages/components/defaults/DefaultMessageListItem.js.map +7 -0
  115. package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js +86 -0
  116. package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js.map +7 -0
  117. package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js +61 -0
  118. package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js.map +7 -0
  119. package/dist/modules/messages/components/message-detail/detail-panels.js +27 -0
  120. package/dist/modules/messages/components/message-detail/detail-panels.js.map +7 -0
  121. package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js +52 -0
  122. package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js.map +7 -0
  123. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js +289 -0
  124. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js.map +7 -0
  125. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +103 -0
  126. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +7 -0
  127. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js +78 -0
  128. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js.map +7 -0
  129. package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js +94 -0
  130. package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js.map +7 -0
  131. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +110 -0
  132. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +7 -0
  133. package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js +58 -0
  134. package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js.map +7 -0
  135. package/dist/modules/messages/components/message-detail/panels/actions-panel.js +51 -0
  136. package/dist/modules/messages/components/message-detail/panels/actions-panel.js.map +7 -0
  137. package/dist/modules/messages/components/message-detail/panels/attachments-panel.js +66 -0
  138. package/dist/modules/messages/components/message-detail/panels/attachments-panel.js.map +7 -0
  139. package/dist/modules/messages/components/message-detail/panels/body-panel.js +20 -0
  140. package/dist/modules/messages/components/message-detail/panels/body-panel.js.map +7 -0
  141. package/dist/modules/messages/components/message-detail/panels/composer-dialogs.js +36 -0
  142. package/dist/modules/messages/components/message-detail/panels/composer-dialogs.js.map +7 -0
  143. package/dist/modules/messages/components/message-detail/panels/dialogs.js +96 -0
  144. package/dist/modules/messages/components/message-detail/panels/dialogs.js.map +7 -0
  145. package/dist/modules/messages/components/message-detail/panels/index.js +25 -0
  146. package/dist/modules/messages/components/message-detail/panels/index.js.map +7 -0
  147. package/dist/modules/messages/components/message-detail/panels/meta-panel.js +14 -0
  148. package/dist/modules/messages/components/message-detail/panels/meta-panel.js.map +7 -0
  149. package/dist/modules/messages/components/message-detail/panels/objects-panel.js +51 -0
  150. package/dist/modules/messages/components/message-detail/panels/objects-panel.js.map +7 -0
  151. package/dist/modules/messages/components/message-detail/panels/thread-panel.js +54 -0
  152. package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +7 -0
  153. package/dist/modules/messages/components/message-detail/types.js +1 -0
  154. package/dist/modules/messages/components/message-detail/types.js.map +7 -0
  155. package/dist/modules/messages/components/message-detail/utils.js +54 -0
  156. package/dist/modules/messages/components/message-detail/utils.js.map +7 -0
  157. package/dist/modules/messages/components/utils/PriorityBadge.js +52 -0
  158. package/dist/modules/messages/components/utils/PriorityBadge.js.map +7 -0
  159. package/dist/modules/messages/components/utils/typeUiRegistry.js +77 -0
  160. package/dist/modules/messages/components/utils/typeUiRegistry.js.map +7 -0
  161. package/dist/modules/messages/data/entities.js +309 -0
  162. package/dist/modules/messages/data/entities.js.map +7 -0
  163. package/dist/modules/messages/data/validators.js +272 -0
  164. package/dist/modules/messages/data/validators.js.map +7 -0
  165. package/dist/modules/messages/emails/MessageEmail.js +108 -0
  166. package/dist/modules/messages/emails/MessageEmail.js.map +7 -0
  167. package/dist/modules/messages/events.js +24 -0
  168. package/dist/modules/messages/events.js.map +7 -0
  169. package/dist/modules/messages/frontend/messages/view/[token]/page.js +247 -0
  170. package/dist/modules/messages/frontend/messages/view/[token]/page.js.map +7 -0
  171. package/dist/modules/messages/frontend/messages/view/[token]/page.meta.js +9 -0
  172. package/dist/modules/messages/frontend/messages/view/[token]/page.meta.js.map +7 -0
  173. package/dist/modules/messages/index.js +21 -0
  174. package/dist/modules/messages/index.js.map +7 -0
  175. package/dist/modules/messages/lib/actions.js +141 -0
  176. package/dist/modules/messages/lib/actions.js.map +7 -0
  177. package/dist/modules/messages/lib/attachments.js +131 -0
  178. package/dist/modules/messages/lib/attachments.js.map +7 -0
  179. package/dist/modules/messages/lib/constants.js +7 -0
  180. package/dist/modules/messages/lib/constants.js.map +7 -0
  181. package/dist/modules/messages/lib/email-sender.js +201 -0
  182. package/dist/modules/messages/lib/email-sender.js.map +7 -0
  183. package/dist/modules/messages/lib/forwarding.js +179 -0
  184. package/dist/modules/messages/lib/forwarding.js.map +7 -0
  185. package/dist/modules/messages/lib/message-objects-registry.js +49 -0
  186. package/dist/modules/messages/lib/message-objects-registry.js.map +7 -0
  187. package/dist/modules/messages/lib/message-types-registry.js +41 -0
  188. package/dist/modules/messages/lib/message-types-registry.js.map +7 -0
  189. package/dist/modules/messages/lib/object-validation.js +20 -0
  190. package/dist/modules/messages/lib/object-validation.js.map +7 -0
  191. package/dist/modules/messages/lib/operationMetadata.js +21 -0
  192. package/dist/modules/messages/lib/operationMetadata.js.map +7 -0
  193. package/dist/modules/messages/lib/priorityUtils.js +61 -0
  194. package/dist/modules/messages/lib/priorityUtils.js.map +7 -0
  195. package/dist/modules/messages/lib/routeHelpers.js +44 -0
  196. package/dist/modules/messages/lib/routeHelpers.js.map +7 -0
  197. package/dist/modules/messages/message-objects.js +7 -0
  198. package/dist/modules/messages/message-objects.js.map +7 -0
  199. package/dist/modules/messages/message-types.js +67 -0
  200. package/dist/modules/messages/message-types.js.map +7 -0
  201. package/dist/modules/messages/migrations/Migration20260213181243.js +31 -0
  202. package/dist/modules/messages/migrations/Migration20260213181243.js.map +7 -0
  203. package/dist/modules/messages/migrations/Migration20260215165126.js +16 -0
  204. package/dist/modules/messages/migrations/Migration20260215165126.js.map +7 -0
  205. package/dist/modules/messages/notifications.js +27 -0
  206. package/dist/modules/messages/notifications.js.map +7 -0
  207. package/dist/modules/messages/setup.js +21 -0
  208. package/dist/modules/messages/setup.js.map +7 -0
  209. package/dist/modules/messages/subscribers/message-notification.js +108 -0
  210. package/dist/modules/messages/subscribers/message-notification.js.map +7 -0
  211. package/dist/modules/messages/workers/send-email.worker.js +253 -0
  212. package/dist/modules/messages/workers/send-email.worker.js.map +7 -0
  213. package/dist/modules/sales/backend/sales/documents/[id]/page.js +30 -11
  214. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  215. package/dist/modules/sales/commands/payments.js +12 -6
  216. package/dist/modules/sales/commands/payments.js.map +2 -2
  217. package/dist/modules/sales/lib/messageObjectPreviews.js +114 -0
  218. package/dist/modules/sales/lib/messageObjectPreviews.js.map +7 -0
  219. package/dist/modules/sales/message-objects.js +57 -0
  220. package/dist/modules/sales/message-objects.js.map +7 -0
  221. package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js +51 -0
  222. package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js.map +7 -0
  223. package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js +36 -0
  224. package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js.map +7 -0
  225. package/dist/modules/sales/widgets/messages/index.js +7 -0
  226. package/dist/modules/sales/widgets/messages/index.js.map +7 -0
  227. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +55 -1
  228. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
  229. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +60 -1
  230. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
  231. package/dist/modules/staff/backend/staff/team-members/[id]/page.js +2 -19
  232. package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
  233. package/dist/modules/staff/components/LeaveRequestDetail.js +112 -0
  234. package/dist/modules/staff/components/LeaveRequestDetail.js.map +7 -0
  235. package/dist/modules/staff/components/LeaveRequestForm.js +3 -1
  236. package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
  237. package/dist/modules/staff/components/LeaveRequestPreview.js +43 -0
  238. package/dist/modules/staff/components/LeaveRequestPreview.js.map +7 -0
  239. package/dist/modules/staff/lib/messageObjectPreviews.js +148 -0
  240. package/dist/modules/staff/lib/messageObjectPreviews.js.map +7 -0
  241. package/dist/modules/staff/message-objects.js +104 -0
  242. package/dist/modules/staff/message-objects.js.map +7 -0
  243. package/dist/modules/staff/message-types.js +23 -0
  244. package/dist/modules/staff/message-types.js.map +7 -0
  245. package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js +51 -0
  246. package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js.map +7 -0
  247. package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js +34 -0
  248. package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js.map +7 -0
  249. package/dist/modules/staff/widgets/messages/index.js +7 -0
  250. package/dist/modules/staff/widgets/messages/index.js.map +7 -0
  251. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +6 -6
  252. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  253. package/generated/entities/message/index.ts +31 -0
  254. package/generated/entities/message_access_token/index.ts +8 -0
  255. package/generated/entities/message_confirmation/index.ts +9 -0
  256. package/generated/entities/message_object/index.ts +10 -0
  257. package/generated/entities/message_recipient/index.ts +14 -0
  258. package/generated/entities.ids.generated.ts +8 -0
  259. package/generated/entity-fields-registry.ts +10 -0
  260. package/jest.setup.ts +5 -0
  261. package/package.json +2 -2
  262. package/src/modules/attachments/i18n/de.json +4 -0
  263. package/src/modules/attachments/i18n/en.json +4 -0
  264. package/src/modules/attachments/i18n/es.json +4 -0
  265. package/src/modules/attachments/i18n/pl.json +4 -0
  266. package/src/modules/auth/components/AclEditor.tsx +4 -2
  267. package/src/modules/auth/frontend/reset.tsx +3 -3
  268. package/src/modules/auth/i18n/de.json +5 -0
  269. package/src/modules/auth/i18n/en.json +5 -0
  270. package/src/modules/auth/i18n/es.json +5 -0
  271. package/src/modules/auth/i18n/pl.json +5 -0
  272. package/src/modules/catalog/i18n/de.json +21 -0
  273. package/src/modules/catalog/i18n/en.json +21 -0
  274. package/src/modules/catalog/i18n/es.json +21 -0
  275. package/src/modules/catalog/i18n/pl.json +21 -0
  276. package/src/modules/currencies/i18n/de.json +6 -0
  277. package/src/modules/currencies/i18n/en.json +6 -0
  278. package/src/modules/currencies/i18n/es.json +6 -0
  279. package/src/modules/currencies/i18n/pl.json +6 -0
  280. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +20 -4
  281. package/src/modules/customers/i18n/de.json +26 -1
  282. package/src/modules/customers/i18n/en.json +25 -0
  283. package/src/modules/customers/i18n/es.json +25 -0
  284. package/src/modules/customers/i18n/pl.json +25 -0
  285. package/src/modules/customers/lib/messageObjectPreviews.ts +154 -0
  286. package/src/modules/customers/message-objects.ts +70 -0
  287. package/src/modules/customers/widgets/messages/CustomerMessageObjectDetail.tsx +57 -0
  288. package/src/modules/customers/widgets/messages/CustomerMessageObjectPreview.tsx +49 -0
  289. package/src/modules/customers/widgets/messages/index.ts +2 -0
  290. package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +41 -5
  291. package/src/modules/dashboards/i18n/de.json +5 -1
  292. package/src/modules/dashboards/i18n/en.json +5 -1
  293. package/src/modules/dashboards/i18n/es.json +5 -1
  294. package/src/modules/dashboards/i18n/pl.json +5 -1
  295. package/src/modules/dictionaries/i18n/de.json +14 -1
  296. package/src/modules/dictionaries/i18n/en.json +14 -1
  297. package/src/modules/dictionaries/i18n/es.json +14 -1
  298. package/src/modules/dictionaries/i18n/pl.json +14 -1
  299. package/src/modules/feature_toggles/i18n/de.json +3 -0
  300. package/src/modules/feature_toggles/i18n/en.json +3 -0
  301. package/src/modules/feature_toggles/i18n/es.json +3 -0
  302. package/src/modules/feature_toggles/i18n/pl.json +3 -0
  303. package/src/modules/messages/acl.ts +11 -0
  304. package/src/modules/messages/api/[id]/actions/[actionId]/route.ts +103 -0
  305. package/src/modules/messages/api/[id]/archive/route.ts +138 -0
  306. package/src/modules/messages/api/[id]/attachments/route.ts +217 -0
  307. package/src/modules/messages/api/[id]/confirmation/route.ts +73 -0
  308. package/src/modules/messages/api/[id]/conversation/archive/route.ts +69 -0
  309. package/src/modules/messages/api/[id]/conversation/read/route.ts +69 -0
  310. package/src/modules/messages/api/[id]/conversation/route.ts +69 -0
  311. package/src/modules/messages/api/[id]/forward/route.ts +87 -0
  312. package/src/modules/messages/api/[id]/forward-preview/route.ts +75 -0
  313. package/src/modules/messages/api/[id]/read/route.ts +138 -0
  314. package/src/modules/messages/api/[id]/reply/route.ts +89 -0
  315. package/src/modules/messages/api/[id]/route.ts +401 -0
  316. package/src/modules/messages/api/object-types/route.ts +54 -0
  317. package/src/modules/messages/api/openapi.ts +261 -0
  318. package/src/modules/messages/api/route.ts +374 -0
  319. package/src/modules/messages/api/token/[token]/route.ts +103 -0
  320. package/src/modules/messages/api/types/route.ts +39 -0
  321. package/src/modules/messages/api/unread-count/route.ts +55 -0
  322. package/src/modules/messages/backend/messages/[id]/page.meta.ts +12 -0
  323. package/src/modules/messages/backend/messages/[id]/page.tsx +12 -0
  324. package/src/modules/messages/backend/messages/compose/page.meta.ts +13 -0
  325. package/src/modules/messages/backend/messages/compose/page.tsx +12 -0
  326. package/src/modules/messages/backend/page.meta.ts +31 -0
  327. package/src/modules/messages/backend/page.tsx +12 -0
  328. package/src/modules/messages/commands/actions.ts +307 -0
  329. package/src/modules/messages/commands/attachments.ts +227 -0
  330. package/src/modules/messages/commands/confirmations.ts +183 -0
  331. package/src/modules/messages/commands/conversation.ts +292 -0
  332. package/src/modules/messages/commands/messages.ts +845 -0
  333. package/src/modules/messages/commands/recipients.ts +281 -0
  334. package/src/modules/messages/commands/shared.ts +350 -0
  335. package/src/modules/messages/commands/tokens.ts +80 -0
  336. package/src/modules/messages/components/ComposeMessagePageClient.tsx +23 -0
  337. package/src/modules/messages/components/MessageDetailPageClient.tsx +287 -0
  338. package/src/modules/messages/components/MessagesInboxPageClient.tsx +469 -0
  339. package/src/modules/messages/components/confirmation/MessageConfirmationActions.tsx +35 -0
  340. package/src/modules/messages/components/confirmation/MessageConfirmationContent.tsx +88 -0
  341. package/src/modules/messages/components/defaults/DefaultMessageActions.tsx +37 -0
  342. package/src/modules/messages/components/defaults/DefaultMessageContent.tsx +21 -0
  343. package/src/modules/messages/components/defaults/DefaultMessageListItem.tsx +102 -0
  344. package/src/modules/messages/components/defaults/MessageRecordObjectDetail.tsx +114 -0
  345. package/src/modules/messages/components/defaults/MessageRecordObjectPreview.tsx +74 -0
  346. package/src/modules/messages/components/message-detail/detail-panels.ts +13 -0
  347. package/src/modules/messages/components/message-detail/hooks/useMessageDetails.ts +56 -0
  348. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsActions.ts +367 -0
  349. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +134 -0
  350. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.ts +102 -0
  351. package/src/modules/messages/components/message-detail/panels/MainMessageHeader.tsx +108 -0
  352. package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +144 -0
  353. package/src/modules/messages/components/message-detail/panels/MessageListComponent.tsx +63 -0
  354. package/src/modules/messages/components/message-detail/panels/actions-panel.tsx +66 -0
  355. package/src/modules/messages/components/message-detail/panels/attachments-panel.tsx +86 -0
  356. package/src/modules/messages/components/message-detail/panels/body-panel.tsx +32 -0
  357. package/src/modules/messages/components/message-detail/panels/composer-dialogs.tsx +42 -0
  358. package/src/modules/messages/components/message-detail/panels/dialogs.tsx +107 -0
  359. package/src/modules/messages/components/message-detail/panels/index.ts +11 -0
  360. package/src/modules/messages/components/message-detail/panels/meta-panel.tsx +19 -0
  361. package/src/modules/messages/components/message-detail/panels/objects-panel.tsx +65 -0
  362. package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +65 -0
  363. package/src/modules/messages/components/message-detail/types.ts +114 -0
  364. package/src/modules/messages/components/message-detail/utils.ts +62 -0
  365. package/src/modules/messages/components/utils/PriorityBadge.tsx +63 -0
  366. package/src/modules/messages/components/utils/typeUiRegistry.ts +106 -0
  367. package/src/modules/messages/data/entities.ts +284 -0
  368. package/src/modules/messages/data/validators.ts +297 -0
  369. package/src/modules/messages/emails/MessageEmail.tsx +143 -0
  370. package/src/modules/messages/events.ts +24 -0
  371. package/src/modules/messages/frontend/messages/view/[token]/page.meta.ts +5 -0
  372. package/src/modules/messages/frontend/messages/view/[token]/page.tsx +389 -0
  373. package/src/modules/messages/i18n/de.json +240 -0
  374. package/src/modules/messages/i18n/en.json +240 -0
  375. package/src/modules/messages/i18n/es.json +240 -0
  376. package/src/modules/messages/i18n/pl.json +240 -0
  377. package/src/modules/messages/index.ts +19 -0
  378. package/src/modules/messages/lib/actions.ts +204 -0
  379. package/src/modules/messages/lib/attachments.ts +197 -0
  380. package/src/modules/messages/lib/constants.ts +2 -0
  381. package/src/modules/messages/lib/email-sender.ts +255 -0
  382. package/src/modules/messages/lib/forwarding.ts +240 -0
  383. package/src/modules/messages/lib/message-objects-registry.ts +60 -0
  384. package/src/modules/messages/lib/message-types-registry.ts +48 -0
  385. package/src/modules/messages/lib/object-validation.ts +26 -0
  386. package/src/modules/messages/lib/operationMetadata.ts +43 -0
  387. package/src/modules/messages/lib/priorityUtils.ts +76 -0
  388. package/src/modules/messages/lib/routeHelpers.ts +65 -0
  389. package/src/modules/messages/message-objects.ts +5 -0
  390. package/src/modules/messages/message-types.ts +65 -0
  391. package/src/modules/messages/migrations/.snapshot-open-mercato.json +957 -0
  392. package/src/modules/messages/migrations/Migration20260213181243.ts +34 -0
  393. package/src/modules/messages/migrations/Migration20260215165126.ts +16 -0
  394. package/src/modules/messages/notifications.ts +25 -0
  395. package/src/modules/messages/setup.ts +19 -0
  396. package/src/modules/messages/subscribers/message-notification.ts +138 -0
  397. package/src/modules/messages/workers/send-email.worker.ts +321 -0
  398. package/src/modules/query_index/i18n/es.json +2 -2
  399. package/src/modules/resources/i18n/de.json +57 -0
  400. package/src/modules/resources/i18n/en.json +57 -0
  401. package/src/modules/resources/i18n/es.json +57 -0
  402. package/src/modules/resources/i18n/pl.json +57 -0
  403. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +23 -7
  404. package/src/modules/sales/commands/payments.ts +12 -6
  405. package/src/modules/sales/i18n/de.json +26 -0
  406. package/src/modules/sales/i18n/en.json +26 -0
  407. package/src/modules/sales/i18n/es.json +26 -0
  408. package/src/modules/sales/i18n/pl.json +26 -0
  409. package/src/modules/sales/lib/messageObjectPreviews.ts +150 -0
  410. package/src/modules/sales/message-objects.ts +56 -0
  411. package/src/modules/sales/widgets/messages/SalesDocumentMessageDetail.tsx +57 -0
  412. package/src/modules/sales/widgets/messages/SalesDocumentMessagePreview.tsx +46 -0
  413. package/src/modules/sales/widgets/messages/index.ts +2 -0
  414. package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +54 -0
  415. package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +58 -0
  416. package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +2 -32
  417. package/src/modules/staff/components/LeaveRequestDetail.tsx +135 -0
  418. package/src/modules/staff/components/LeaveRequestForm.tsx +3 -0
  419. package/src/modules/staff/components/LeaveRequestPreview.tsx +74 -0
  420. package/src/modules/staff/i18n/de.json +22 -0
  421. package/src/modules/staff/i18n/en.json +22 -0
  422. package/src/modules/staff/i18n/es.json +22 -0
  423. package/src/modules/staff/i18n/pl.json +22 -0
  424. package/src/modules/staff/lib/messageObjectPreviews.ts +182 -0
  425. package/src/modules/staff/message-objects.ts +102 -0
  426. package/src/modules/staff/message-types.ts +21 -0
  427. package/src/modules/staff/widgets/messages/StaffMessageObjectDetail.tsx +57 -0
  428. package/src/modules/staff/widgets/messages/StaffMessageObjectPreview.tsx +44 -0
  429. package/src/modules/staff/widgets/messages/index.ts +2 -0
  430. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +6 -6
  431. package/src/modules/workflows/i18n/de.json +41 -0
  432. package/src/modules/workflows/i18n/en.json +41 -0
  433. package/src/modules/workflows/i18n/es.json +41 -0
  434. package/src/modules/workflows/i18n/pl.json +41 -0
@@ -102,5 +102,9 @@
102
102
  "dashboards.widgets.loading": "Cargando opciones de widgets…",
103
103
  "dashboards.widgets.mode.hint": "Este usuario hereda los widgets de sus roles asignados. Cambia a sobrescribir para personalizar.",
104
104
  "dashboards.widgets.mode.inherit": "Heredar de los roles",
105
- "dashboards.widgets.mode.override": "Sobrescribir para este usuario"
105
+ "dashboards.widgets.mode.override": "Sobrescribir para este usuario",
106
+ "dashboards.widgets.effective": "Widgets efectivos:",
107
+ "dashboards.widgets.reset": "Restablecer",
108
+ "dashboards.widgets.save": "Guardar widgets",
109
+ "dashboards.widgets.saving": "Guardando…"
106
110
  }
@@ -102,5 +102,9 @@
102
102
  "dashboards.widgets.loading": "Ładowanie opcji widżetów…",
103
103
  "dashboards.widgets.mode.hint": "Ten użytkownik dziedziczy widżety z przypisanych ról. Wybierz nadpisanie, aby je dostosować.",
104
104
  "dashboards.widgets.mode.inherit": "Dziedzicz po rolach",
105
- "dashboards.widgets.mode.override": "Nadpisz dla tego użytkownika"
105
+ "dashboards.widgets.mode.override": "Nadpisz dla tego użytkownika",
106
+ "dashboards.widgets.effective": "Aktywne widżety:",
107
+ "dashboards.widgets.reset": "Resetuj",
108
+ "dashboards.widgets.save": "Zapisz widżety",
109
+ "dashboards.widgets.saving": "Zapisywanie…"
106
110
  }
@@ -91,10 +91,23 @@
91
91
  "dictionaries.entries.update": "Wörterbucheintrag aktualisieren",
92
92
  "dictionaries.errors.currency_protected": "Das Währungswörterbuch ist erforderlich und kann nicht geändert oder gelöscht werden.",
93
93
  "dictionaries.errors.duplicate": "Ein Wörterbuch mit diesem Schlüssel existiert bereits",
94
+ "dictionaries.errors.entry_create_failed": "Wörterbucheintrag konnte nicht erstellt werden.",
94
95
  "dictionaries.errors.entry_duplicate": "Ein Eintrag mit diesem Wert existiert bereits",
95
96
  "dictionaries.errors.entry_not_found": "Wörterbucheintrag nicht gefunden",
96
97
  "dictionaries.errors.entry_required": "Wert ist erforderlich",
98
+ "dictionaries.errors.entry_update_failed": "Wörterbucheintrag konnte nicht aktualisiert werden.",
97
99
  "dictionaries.errors.not_found": "Wörterbuch nicht gefunden",
98
100
  "dictionaries.errors.organization_required": "Organisationskontext ist erforderlich",
99
- "dictionaries.errors.unauthorized": "Nicht autorisiert"
101
+ "dictionaries.errors.unauthorized": "Nicht autorisiert",
102
+ "dictionaries.form.colorClear": "Farbe entfernen",
103
+ "dictionaries.form.colorHelp": "Hervorhebungsfarbe für diesen Eintrag wählen.",
104
+ "dictionaries.form.colorLabel": "Farbe",
105
+ "dictionaries.form.iconClearLabel": "Symbol entfernen",
106
+ "dictionaries.form.iconLabel": "Symbol",
107
+ "dictionaries.form.iconPickerTriggerLabel": "Symbole durchsuchen",
108
+ "dictionaries.form.iconPlaceholder": "Emoji oder Symbolname eingeben",
109
+ "dictionaries.form.iconSearchEmptyLabel": "Keine Symbole entsprechen Ihrer Suche",
110
+ "dictionaries.form.iconSearchPlaceholder": "Symbole oder Emojis suchen…",
111
+ "dictionaries.form.iconSuggestionsLabel": "Vorschläge",
112
+ "dictionaries.form.previewEmptyLabel": "Keine Darstellung ausgewählt"
100
113
  }
@@ -91,10 +91,23 @@
91
91
  "dictionaries.entries.update": "Update dictionary entry",
92
92
  "dictionaries.errors.currency_protected": "The currency dictionary is required and cannot be modified or deleted.",
93
93
  "dictionaries.errors.duplicate": "A dictionary with this key already exists",
94
+ "dictionaries.errors.entry_create_failed": "Failed to create dictionary entry.",
94
95
  "dictionaries.errors.entry_duplicate": "An entry with this value already exists",
95
96
  "dictionaries.errors.entry_not_found": "Dictionary entry not found",
96
97
  "dictionaries.errors.entry_required": "Value is required",
98
+ "dictionaries.errors.entry_update_failed": "Failed to update dictionary entry.",
97
99
  "dictionaries.errors.not_found": "Dictionary not found",
98
100
  "dictionaries.errors.organization_required": "Organization context is required",
99
- "dictionaries.errors.unauthorized": "Unauthorized"
101
+ "dictionaries.errors.unauthorized": "Unauthorized",
102
+ "dictionaries.form.colorClear": "Clear color",
103
+ "dictionaries.form.colorHelp": "Pick a highlight color for this entry.",
104
+ "dictionaries.form.colorLabel": "Color",
105
+ "dictionaries.form.iconClearLabel": "Clear icon",
106
+ "dictionaries.form.iconLabel": "Icon",
107
+ "dictionaries.form.iconPickerTriggerLabel": "Browse icons",
108
+ "dictionaries.form.iconPlaceholder": "Type an emoji or icon name",
109
+ "dictionaries.form.iconSearchEmptyLabel": "No icons match your search",
110
+ "dictionaries.form.iconSearchPlaceholder": "Search icons or emojis…",
111
+ "dictionaries.form.iconSuggestionsLabel": "Suggestions",
112
+ "dictionaries.form.previewEmptyLabel": "No appearance selected"
100
113
  }
@@ -91,10 +91,23 @@
91
91
  "dictionaries.entries.update": "Actualizar entrada de diccionario",
92
92
  "dictionaries.errors.currency_protected": "El diccionario de monedas es obligatorio y no puede modificarse ni eliminarse.",
93
93
  "dictionaries.errors.duplicate": "Ya existe un diccionario con esta clave",
94
+ "dictionaries.errors.entry_create_failed": "Error al crear la entrada de diccionario.",
94
95
  "dictionaries.errors.entry_duplicate": "Ya existe una entrada con este valor",
95
96
  "dictionaries.errors.entry_not_found": "Entrada de diccionario no encontrada",
96
97
  "dictionaries.errors.entry_required": "El valor es obligatorio",
98
+ "dictionaries.errors.entry_update_failed": "Error al actualizar la entrada de diccionario.",
97
99
  "dictionaries.errors.not_found": "Diccionario no encontrado",
98
100
  "dictionaries.errors.organization_required": "Se requiere un contexto de organización",
99
- "dictionaries.errors.unauthorized": "No autorizado"
101
+ "dictionaries.errors.unauthorized": "No autorizado",
102
+ "dictionaries.form.colorClear": "Limpiar color",
103
+ "dictionaries.form.colorHelp": "Seleccione un color de resaltado para esta entrada.",
104
+ "dictionaries.form.colorLabel": "Color",
105
+ "dictionaries.form.iconClearLabel": "Limpiar icono",
106
+ "dictionaries.form.iconLabel": "Icono",
107
+ "dictionaries.form.iconPickerTriggerLabel": "Explorar iconos",
108
+ "dictionaries.form.iconPlaceholder": "Escriba un emoji o nombre de icono",
109
+ "dictionaries.form.iconSearchEmptyLabel": "Ningún icono coincide con su búsqueda",
110
+ "dictionaries.form.iconSearchPlaceholder": "Buscar iconos o emojis…",
111
+ "dictionaries.form.iconSuggestionsLabel": "Sugerencias",
112
+ "dictionaries.form.previewEmptyLabel": "No se ha seleccionado apariencia"
100
113
  }
@@ -91,10 +91,23 @@
91
91
  "dictionaries.entries.update": "Zaktualizuj wpis słownika",
92
92
  "dictionaries.errors.currency_protected": "Słownik walut jest wymagany i nie może być modyfikowany ani usuwany.",
93
93
  "dictionaries.errors.duplicate": "Słownik o tym kluczu już istnieje",
94
+ "dictionaries.errors.entry_create_failed": "Nie udało się utworzyć wpisu słownikowego.",
94
95
  "dictionaries.errors.entry_duplicate": "Wpis o tej wartości już istnieje",
95
96
  "dictionaries.errors.entry_not_found": "Nie znaleziono wpisu słownika",
96
97
  "dictionaries.errors.entry_required": "Wartość jest wymagana",
98
+ "dictionaries.errors.entry_update_failed": "Nie udało się zaktualizować wpisu słownikowego.",
97
99
  "dictionaries.errors.not_found": "Nie znaleziono słownika",
98
100
  "dictionaries.errors.organization_required": "Wymagany jest kontekst organizacji",
99
- "dictionaries.errors.unauthorized": "Brak autoryzacji"
101
+ "dictionaries.errors.unauthorized": "Brak autoryzacji",
102
+ "dictionaries.form.colorClear": "Wyczyść kolor",
103
+ "dictionaries.form.colorHelp": "Wybierz kolor wyróżnienia dla tego wpisu.",
104
+ "dictionaries.form.colorLabel": "Kolor",
105
+ "dictionaries.form.iconClearLabel": "Wyczyść ikonę",
106
+ "dictionaries.form.iconLabel": "Ikona",
107
+ "dictionaries.form.iconPickerTriggerLabel": "Przeglądaj ikony",
108
+ "dictionaries.form.iconPlaceholder": "Wpisz emoji lub nazwę ikony",
109
+ "dictionaries.form.iconSearchEmptyLabel": "Żadne ikony nie pasują do wyszukiwania",
110
+ "dictionaries.form.iconSearchPlaceholder": "Szukaj ikon lub emoji…",
111
+ "dictionaries.form.iconSuggestionsLabel": "Sugestie",
112
+ "dictionaries.form.previewEmptyLabel": "Nie wybrano wyglądu"
100
113
  }
@@ -11,6 +11,7 @@
11
11
  "feature_toggles.detail.fields.failMode": "Fehlermodus",
12
12
  "feature_toggles.detail.fields.identifier": "Kennung",
13
13
  "feature_toggles.detail.fields.name": "Name",
14
+ "feature_toggles.form.action.save": "Speichern",
14
15
  "feature_toggles.form.errors.load": "Feature-Schalter-Überschreibungen konnten nicht geladen werden",
15
16
  "feature_toggles.form.fields.category.label": "Kategorie",
16
17
  "feature_toggles.form.fields.defaultState.disabled": "Deaktiviert",
@@ -30,6 +31,8 @@
30
31
  "feature_toggles.form.groups.basic": "Grundinformationen",
31
32
  "feature_toggles.form.groups.defaultValue": "Standardwert",
32
33
  "feature_toggles.form.groups.type": "Typkonfiguration",
34
+ "feature_toggles.form.loading": "Wird geladen…",
35
+ "feature_toggles.form.title.edit": "Feature-Toggle bearbeiten",
33
36
  "feature_toggles.global.help.title": "Feature-Schalter",
34
37
  "feature_toggles.list.confirmDelete": "Feature-Schalter \"{identifier}\" löschen?",
35
38
  "feature_toggles.list.error.load": "Feature-Schalter konnten nicht geladen werden",
@@ -11,6 +11,7 @@
11
11
  "feature_toggles.detail.fields.failMode": "Fail Mode",
12
12
  "feature_toggles.detail.fields.identifier": "Identifier",
13
13
  "feature_toggles.detail.fields.name": "Name",
14
+ "feature_toggles.form.action.save": "Save",
14
15
  "feature_toggles.form.errors.load": "Failed to load feature toggle overrides",
15
16
  "feature_toggles.form.fields.category.label": "Category",
16
17
  "feature_toggles.form.fields.defaultState.disabled": "Disabled",
@@ -30,6 +31,8 @@
30
31
  "feature_toggles.form.groups.basic": "Basic Information",
31
32
  "feature_toggles.form.groups.defaultValue": "Default Value",
32
33
  "feature_toggles.form.groups.type": "Type Configuration",
34
+ "feature_toggles.form.loading": "Loading…",
35
+ "feature_toggles.form.title.edit": "Edit Feature Toggle",
33
36
  "feature_toggles.global.help.title": "Feature Toggles",
34
37
  "feature_toggles.list.confirmDelete": "Delete feature toggle \"{identifier}\"?",
35
38
  "feature_toggles.list.error.load": "Failed to load feature toggles",
@@ -11,6 +11,7 @@
11
11
  "feature_toggles.detail.fields.failMode": "Modo de Fallo",
12
12
  "feature_toggles.detail.fields.identifier": "Identificador",
13
13
  "feature_toggles.detail.fields.name": "Nombre",
14
+ "feature_toggles.form.action.save": "Guardar",
14
15
  "feature_toggles.form.errors.load": "Error al cargar las anulaciones de interruptores de funciones",
15
16
  "feature_toggles.form.fields.category.label": "Categoría",
16
17
  "feature_toggles.form.fields.defaultState.disabled": "Deshabilitado",
@@ -30,6 +31,8 @@
30
31
  "feature_toggles.form.groups.basic": "Información Básica",
31
32
  "feature_toggles.form.groups.defaultValue": "Valor Predeterminado",
32
33
  "feature_toggles.form.groups.type": "Configuración de Tipo",
34
+ "feature_toggles.form.loading": "Cargando…",
35
+ "feature_toggles.form.title.edit": "Editar alternancia de característica",
33
36
  "feature_toggles.global.help.title": "Interruptores de Funciones",
34
37
  "feature_toggles.list.confirmDelete": "¿Eliminar interruptor de función \"{identifier}\"?",
35
38
  "feature_toggles.list.error.load": "Error al cargar los interruptores de funciones",
@@ -11,6 +11,7 @@
11
11
  "feature_toggles.detail.fields.failMode": "Tryb Awaryjny",
12
12
  "feature_toggles.detail.fields.identifier": "Identyfikator",
13
13
  "feature_toggles.detail.fields.name": "Nazwa",
14
+ "feature_toggles.form.action.save": "Zapisz",
14
15
  "feature_toggles.form.errors.load": "Nie udało się załadować nadpisań przełącznika funkcji",
15
16
  "feature_toggles.form.fields.category.label": "Kategoria",
16
17
  "feature_toggles.form.fields.defaultState.disabled": "Wyłączony",
@@ -30,6 +31,8 @@
30
31
  "feature_toggles.form.groups.basic": "Informacje podstawowe",
31
32
  "feature_toggles.form.groups.defaultValue": "Wartość domyślna",
32
33
  "feature_toggles.form.groups.type": "Konfiguracja typu",
34
+ "feature_toggles.form.loading": "Ładowanie…",
35
+ "feature_toggles.form.title.edit": "Edytuj przełącznik funkcji",
33
36
  "feature_toggles.global.help.title": "Przełączniki funkcji",
34
37
  "feature_toggles.list.confirmDelete": "Usunąć przełącznik funkcji \"{identifier}\"?",
35
38
  "feature_toggles.list.error.load": "Nie udało się załadować przełączników funkcji",
@@ -0,0 +1,11 @@
1
+ export const features = [
2
+ 'messages.view',
3
+ 'messages.compose',
4
+ 'messages.attach',
5
+ 'messages.attach_files',
6
+ 'messages.email',
7
+ 'messages.actions',
8
+ 'messages.manage',
9
+ ]
10
+
11
+ export default features
@@ -0,0 +1,103 @@
1
+ import { z } from 'zod'
2
+ import type { CommandBus } from '@open-mercato/shared/lib/commands/command-bus'
3
+ import { attachOperationMetadataHeader, type OperationLogEntryLike } from '../../../../lib/operationMetadata'
4
+ import { resolveMessageContext } from '../../../../lib/routeHelpers'
5
+ import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'
6
+ import { actionResultResponseSchema } from '../../../openapi'
7
+
8
+ export const metadata = {
9
+ POST: { requireAuth: true, requireFeatures: ['messages.actions'] },
10
+ }
11
+
12
+ export async function POST(
13
+ req: Request,
14
+ { params }: { params: { id: string; actionId: string } }
15
+ ) {
16
+ const { ctx, scope } = await resolveMessageContext(req)
17
+ const commandBus = ctx.container.resolve('commandBus') as CommandBus
18
+
19
+ const rawBody = await req.json().catch(() => ({}))
20
+ const body = (typeof rawBody === 'object' && rawBody && !Array.isArray(rawBody)
21
+ ? rawBody
22
+ : {}) as Record<string, unknown>
23
+ try {
24
+ const commandResult = await commandBus.execute('messages.actions.execute', {
25
+ input: {
26
+ messageId: params.id,
27
+ actionId: params.actionId,
28
+ payload: body,
29
+ tenantId: scope.tenantId,
30
+ organizationId: scope.organizationId,
31
+ userId: scope.userId,
32
+ },
33
+ ctx: {
34
+ container: ctx.container,
35
+ auth: ctx.auth ?? null,
36
+ organizationScope: null,
37
+ selectedOrganizationId: scope.organizationId,
38
+ organizationIds: scope.organizationId ? [scope.organizationId] : null,
39
+ request: req,
40
+ },
41
+ })
42
+
43
+ const result = commandResult.result as {
44
+ ok: boolean
45
+ actionId: string
46
+ result: Record<string, unknown>
47
+ operationLogEntry?: OperationLogEntryLike | null
48
+ }
49
+ const response = Response.json({
50
+ ok: result.ok,
51
+ actionId: result.actionId,
52
+ result: result.result,
53
+ })
54
+ attachOperationMetadataHeader(response, result.operationLogEntry ?? null, {
55
+ resourceKind: 'messages.message',
56
+ resourceId: params.id,
57
+ })
58
+ return response
59
+ } catch (error) {
60
+ if (error instanceof Error) {
61
+ if (error.message === 'Message not found') {
62
+ return Response.json({ error: 'Message not found' }, { status: 404 })
63
+ }
64
+ if (error.message === 'Access denied') {
65
+ return Response.json({ error: 'Access denied' }, { status: 403 })
66
+ }
67
+ if (error.message === 'Action not found') {
68
+ return Response.json({ error: 'Action not found' }, { status: 404 })
69
+ }
70
+ if (error.message === 'Action already taken') {
71
+ const actionTaken = (error as Error & { actionTaken?: string }).actionTaken ?? null
72
+ return Response.json({ error: 'Action already taken', actionTaken }, { status: 409 })
73
+ }
74
+ if (error.message === 'Actions have expired') {
75
+ return Response.json({ error: 'Actions have expired' }, { status: 410 })
76
+ }
77
+ if (error.message === 'Action has no executable target') {
78
+ return Response.json({ error: 'Action has no executable target' }, { status: 409 })
79
+ }
80
+ if (error.message === 'Action failed') {
81
+ return Response.json({ error: 'Action failed' }, { status: 500 })
82
+ }
83
+ }
84
+ throw error
85
+ }
86
+ }
87
+
88
+ export const openApi: OpenApiRouteDoc = {
89
+ tag: 'Messages',
90
+ methods: {
91
+ POST: {
92
+ summary: 'Execute message action',
93
+ requestBody: { schema: z.record(z.string(), z.unknown()).optional() },
94
+ responses: [
95
+ { status: 200, description: 'Action executed', schema: actionResultResponseSchema },
96
+ { status: 403, description: 'Access denied' },
97
+ { status: 404, description: 'Action not found' },
98
+ { status: 409, description: 'Action already taken' },
99
+ { status: 410, description: 'Action expired' },
100
+ ],
101
+ },
102
+ },
103
+ }
@@ -0,0 +1,138 @@
1
+ import type { EntityManager } from '@mikro-orm/core'
2
+ import type { CommandBus } from '@open-mercato/shared/lib/commands/command-bus'
3
+ import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'
4
+ import { Message, MessageRecipient } from '../../../data/entities'
5
+ import { attachOperationMetadataHeader } from '../../../lib/operationMetadata'
6
+ import { hasOrganizationAccess, resolveMessageContext } from '../../../lib/routeHelpers'
7
+ import type { MessageScope } from '../../../lib/routeHelpers'
8
+ import { errorResponseSchema, okResponseSchema } from '../../openapi'
9
+
10
+ export const metadata = {
11
+ PUT: { requireAuth: true, requireFeatures: ['messages.view'] },
12
+ DELETE: { requireAuth: true, requireFeatures: ['messages.view'] },
13
+ }
14
+
15
+ type ResolvedCtx = Awaited<ReturnType<typeof resolveMessageContext>>['ctx']
16
+
17
+ async function resolveRecipientContext(
18
+ req: Request,
19
+ id: string,
20
+ ): Promise<
21
+ | { ctx: ResolvedCtx; scope: MessageScope; em: EntityManager; recipient: MessageRecipient }
22
+ | { response: Response }
23
+ > {
24
+ const { ctx, scope } = await resolveMessageContext(req)
25
+ const em = (ctx.container.resolve('em') as EntityManager).fork()
26
+
27
+ const message = await em.findOne(Message, {
28
+ id,
29
+ tenantId: scope.tenantId,
30
+ deletedAt: null,
31
+ })
32
+
33
+ if (!message) {
34
+ return { response: Response.json({ error: 'Message not found' }, { status: 404 }) }
35
+ }
36
+
37
+ if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {
38
+ return { response: Response.json({ error: 'Access denied' }, { status: 403 }) }
39
+ }
40
+
41
+ const recipient = await em.findOne(MessageRecipient, {
42
+ messageId: id,
43
+ recipientUserId: scope.userId,
44
+ deletedAt: null,
45
+ })
46
+
47
+ if (!recipient) {
48
+ return { response: Response.json({ error: 'Access denied' }, { status: 403 }) }
49
+ }
50
+
51
+ return { ctx, scope, em, recipient }
52
+ }
53
+
54
+ export async function PUT(req: Request, { params }: { params: { id: string } }) {
55
+ const context = await resolveRecipientContext(req, params.id)
56
+ if ('response' in context) return context.response
57
+ const { ctx, scope } = context
58
+ const commandBus = ctx.container.resolve('commandBus') as CommandBus
59
+ const { logEntry } = await commandBus.execute('messages.recipients.archive', {
60
+ input: {
61
+ messageId: params.id,
62
+ tenantId: scope.tenantId,
63
+ organizationId: scope.organizationId,
64
+ userId: scope.userId,
65
+ },
66
+ ctx: {
67
+ container: ctx.container,
68
+ auth: ctx.auth ?? null,
69
+ organizationScope: null,
70
+ selectedOrganizationId: scope.organizationId,
71
+ organizationIds: scope.organizationId ? [scope.organizationId] : null,
72
+ request: req,
73
+ },
74
+ })
75
+
76
+ const response = Response.json({ ok: true })
77
+ attachOperationMetadataHeader(response, logEntry, {
78
+ resourceKind: 'messages.message',
79
+ resourceId: params.id,
80
+ })
81
+ return response
82
+ }
83
+
84
+ export async function DELETE(req: Request, { params }: { params: { id: string } }) {
85
+ const context = await resolveRecipientContext(req, params.id)
86
+ if ('response' in context) return context.response
87
+ const { ctx, scope } = context
88
+ const commandBus = ctx.container.resolve('commandBus') as CommandBus
89
+ const { logEntry } = await commandBus.execute('messages.recipients.unarchive', {
90
+ input: {
91
+ messageId: params.id,
92
+ tenantId: scope.tenantId,
93
+ organizationId: scope.organizationId,
94
+ userId: scope.userId,
95
+ },
96
+ ctx: {
97
+ container: ctx.container,
98
+ auth: ctx.auth ?? null,
99
+ organizationScope: null,
100
+ selectedOrganizationId: scope.organizationId,
101
+ organizationIds: scope.organizationId ? [scope.organizationId] : null,
102
+ request: req,
103
+ },
104
+ })
105
+
106
+ const response = Response.json({ ok: true })
107
+ attachOperationMetadataHeader(response, logEntry, {
108
+ resourceKind: 'messages.message',
109
+ resourceId: params.id,
110
+ })
111
+ return response
112
+ }
113
+
114
+ export const openApi: OpenApiRouteDoc = {
115
+ tag: 'Messages',
116
+ methods: {
117
+ PUT: {
118
+ summary: 'Archive message',
119
+ responses: [
120
+ { status: 200, description: 'Message archived', schema: okResponseSchema },
121
+ ],
122
+ errors: [
123
+ { status: 403, description: 'Access denied', schema: errorResponseSchema },
124
+ { status: 404, description: 'Message not found', schema: errorResponseSchema },
125
+ ],
126
+ },
127
+ DELETE: {
128
+ summary: 'Unarchive message',
129
+ responses: [
130
+ { status: 200, description: 'Message unarchived', schema: okResponseSchema },
131
+ ],
132
+ errors: [
133
+ { status: 403, description: 'Access denied', schema: errorResponseSchema },
134
+ { status: 404, description: 'Message not found', schema: errorResponseSchema },
135
+ ],
136
+ },
137
+ },
138
+ }
@@ -0,0 +1,217 @@
1
+ import type { EntityManager } from '@mikro-orm/core'
2
+ import type { CommandBus } from '@open-mercato/shared/lib/commands/command-bus'
3
+ import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'
4
+ import { parseUnlinkAttachmentIds } from '../../../commands/attachments'
5
+ import { Message, MessageRecipient } from '../../../data/entities'
6
+ import { attachmentIdsPayloadSchema, unlinkAttachmentPayloadSchema } from '../../../data/validators'
7
+ import { getMessageAttachments, linkAttachmentsToMessage } from '../../../lib/attachments'
8
+ import { attachOperationMetadataHeader } from '../../../lib/operationMetadata'
9
+ import { resolveMessageContext } from '../../../lib/routeHelpers'
10
+ import {
11
+ attachmentIdsPayloadSchema as attachmentIdsOpenApiSchema,
12
+ errorResponseSchema,
13
+ messageAttachmentResponseSchema,
14
+ okResponseSchema,
15
+ unlinkAttachmentPayloadSchema as unlinkAttachmentOpenApiSchema,
16
+ } from '../../openapi'
17
+
18
+ export const metadata = {
19
+ GET: { requireAuth: true, requireFeatures: ['messages.view'] },
20
+ POST: { requireAuth: true, requireFeatures: ['messages.attach_files'] },
21
+ DELETE: { requireAuth: true, requireFeatures: ['messages.attach_files'] },
22
+ }
23
+
24
+ function hasOrganizationAccess(scopeOrganizationId: string | null, messageOrganizationId: string | null | undefined): boolean {
25
+ if (scopeOrganizationId) {
26
+ return messageOrganizationId === scopeOrganizationId
27
+ }
28
+ return messageOrganizationId == null
29
+ }
30
+
31
+ export async function GET(req: Request, { params }: { params: { id: string } }) {
32
+ const { ctx, scope } = await resolveMessageContext(req)
33
+ const em = ctx.container.resolve('em') as EntityManager
34
+
35
+ const message = await em.findOne(Message, {
36
+ id: params.id,
37
+ tenantId: scope.tenantId,
38
+ deletedAt: null,
39
+ })
40
+
41
+ if (!message) {
42
+ return Response.json({ error: 'Message not found' }, { status: 404 })
43
+ }
44
+
45
+ if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {
46
+ return Response.json({ error: 'Access denied' }, { status: 403 })
47
+ }
48
+
49
+ const recipient = await em.findOne(MessageRecipient, {
50
+ messageId: params.id,
51
+ recipientUserId: scope.userId,
52
+ deletedAt: null,
53
+ })
54
+
55
+ if (message.senderUserId !== scope.userId && !recipient) {
56
+ return Response.json({ error: 'Access denied' }, { status: 403 })
57
+ }
58
+
59
+ const attachments = await getMessageAttachments(
60
+ em,
61
+ params.id,
62
+ scope.organizationId,
63
+ scope.tenantId
64
+ )
65
+
66
+ return Response.json({ attachments })
67
+ }
68
+
69
+ export async function POST(req: Request, { params }: { params: { id: string } }) {
70
+ const { ctx, scope } = await resolveMessageContext(req)
71
+ const em = (ctx.container.resolve('em') as EntityManager).fork()
72
+ const body = await req.json().catch(() => ({}))
73
+ const input = attachmentIdsPayloadSchema.parse(body)
74
+
75
+ const message = await em.findOne(Message, {
76
+ id: params.id,
77
+ tenantId: scope.tenantId,
78
+ deletedAt: null,
79
+ })
80
+
81
+ if (!message) {
82
+ return Response.json({ error: 'Message not found' }, { status: 404 })
83
+ }
84
+
85
+ if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {
86
+ return Response.json({ error: 'Access denied' }, { status: 403 })
87
+ }
88
+
89
+ if (message.senderUserId !== scope.userId) {
90
+ return Response.json({ error: 'Access denied' }, { status: 403 })
91
+ }
92
+
93
+ if (!message.isDraft) {
94
+ return Response.json({ error: 'Attachments can only be modified on drafts' }, { status: 409 })
95
+ }
96
+
97
+ const commandBus = ctx.container.resolve('commandBus') as CommandBus
98
+ const { logEntry } = await commandBus.execute('messages.attachments.link_to_draft', {
99
+ input: {
100
+ messageId: message.id,
101
+ tenantId: scope.tenantId,
102
+ organizationId: scope.organizationId,
103
+ userId: scope.userId,
104
+ attachmentIds: input.attachmentIds,
105
+ },
106
+ ctx: {
107
+ container: ctx.container,
108
+ auth: ctx.auth ?? null,
109
+ organizationScope: null,
110
+ selectedOrganizationId: scope.organizationId,
111
+ organizationIds: scope.organizationId ? [scope.organizationId] : null,
112
+ request: req,
113
+ },
114
+ })
115
+
116
+ const response = Response.json({ ok: true })
117
+ attachOperationMetadataHeader(response, logEntry, {
118
+ resourceKind: 'messages.message',
119
+ resourceId: params.id,
120
+ })
121
+ return response
122
+ }
123
+
124
+ export async function DELETE(req: Request, { params }: { params: { id: string } }) {
125
+ const { ctx, scope } = await resolveMessageContext(req)
126
+ const em = (ctx.container.resolve('em') as EntityManager).fork()
127
+ const body = await req.json().catch(() => ({}))
128
+ const input = unlinkAttachmentPayloadSchema.parse(body)
129
+
130
+ const message = await em.findOne(Message, {
131
+ id: params.id,
132
+ tenantId: scope.tenantId,
133
+ deletedAt: null,
134
+ })
135
+
136
+ if (!message) {
137
+ return Response.json({ error: 'Message not found' }, { status: 404 })
138
+ }
139
+
140
+ if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {
141
+ return Response.json({ error: 'Access denied' }, { status: 403 })
142
+ }
143
+
144
+ if (message.senderUserId !== scope.userId) {
145
+ return Response.json({ error: 'Access denied' }, { status: 403 })
146
+ }
147
+
148
+ if (!message.isDraft) {
149
+ return Response.json({ error: 'Attachments can only be modified on drafts' }, { status: 409 })
150
+ }
151
+
152
+ const commandBus = ctx.container.resolve('commandBus') as CommandBus
153
+ const { logEntry } = await commandBus.execute('messages.attachments.unlink_from_draft', {
154
+ input: {
155
+ messageId: message.id,
156
+ tenantId: scope.tenantId,
157
+ organizationId: scope.organizationId,
158
+ userId: scope.userId,
159
+ attachmentIds: parseUnlinkAttachmentIds(input),
160
+ },
161
+ ctx: {
162
+ container: ctx.container,
163
+ auth: ctx.auth ?? null,
164
+ organizationScope: null,
165
+ selectedOrganizationId: scope.organizationId,
166
+ organizationIds: scope.organizationId ? [scope.organizationId] : null,
167
+ request: req,
168
+ },
169
+ })
170
+
171
+ const response = Response.json({ ok: true })
172
+ attachOperationMetadataHeader(response, logEntry, {
173
+ resourceKind: 'messages.message',
174
+ resourceId: params.id,
175
+ })
176
+ return response
177
+ }
178
+
179
+ export const openApi: OpenApiRouteDoc = {
180
+ tag: 'Messages',
181
+ methods: {
182
+ GET: {
183
+ summary: 'List message attachments',
184
+ responses: [
185
+ { status: 200, description: 'Attachments', schema: messageAttachmentResponseSchema },
186
+ ],
187
+ errors: [
188
+ { status: 403, description: 'Access denied', schema: errorResponseSchema },
189
+ { status: 404, description: 'Message not found', schema: errorResponseSchema },
190
+ ],
191
+ },
192
+ POST: {
193
+ summary: 'Link attachments to draft message',
194
+ requestBody: { schema: attachmentIdsOpenApiSchema },
195
+ responses: [
196
+ { status: 200, description: 'Attachments linked', schema: okResponseSchema },
197
+ ],
198
+ errors: [
199
+ { status: 403, description: 'Access denied', schema: errorResponseSchema },
200
+ { status: 404, description: 'Message not found', schema: errorResponseSchema },
201
+ { status: 409, description: 'Only draft messages can be edited', schema: errorResponseSchema },
202
+ ],
203
+ },
204
+ DELETE: {
205
+ summary: 'Unlink attachments from draft message',
206
+ requestBody: { schema: unlinkAttachmentOpenApiSchema },
207
+ responses: [
208
+ { status: 200, description: 'Attachments unlinked', schema: okResponseSchema },
209
+ ],
210
+ errors: [
211
+ { status: 403, description: 'Access denied', schema: errorResponseSchema },
212
+ { status: 404, description: 'Message not found', schema: errorResponseSchema },
213
+ { status: 409, description: 'Only draft messages can be edited', schema: errorResponseSchema },
214
+ ],
215
+ },
216
+ },
217
+ }