@open-mercato/core 0.6.5-develop.4384.1.ce2ec6eaaa → 0.6.5-develop.4393.1.de282b5dfd

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 (533) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/channel_ingest_dead_letter/index.js +25 -0
  3. package/dist/generated/entities/channel_ingest_dead_letter/index.js.map +7 -0
  4. package/dist/generated/entities/channel_thread_mapping/index.js +25 -0
  5. package/dist/generated/entities/channel_thread_mapping/index.js.map +7 -0
  6. package/dist/generated/entities/channel_thread_token/index.js +17 -0
  7. package/dist/generated/entities/channel_thread_token/index.js.map +7 -0
  8. package/dist/generated/entities/communication_channel/index.js +43 -0
  9. package/dist/generated/entities/communication_channel/index.js.map +7 -0
  10. package/dist/generated/entities/customer_interaction/index.js +4 -0
  11. package/dist/generated/entities/customer_interaction/index.js.map +2 -2
  12. package/dist/generated/entities/external_conversation/index.js +25 -0
  13. package/dist/generated/entities/external_conversation/index.js.map +7 -0
  14. package/dist/generated/entities/external_message/index.js +25 -0
  15. package/dist/generated/entities/external_message/index.js.map +7 -0
  16. package/dist/generated/entities/integration_credentials/index.js +3 -1
  17. package/dist/generated/entities/integration_credentials/index.js.map +2 -2
  18. package/dist/generated/entities/message/index.js +2 -0
  19. package/dist/generated/entities/message/index.js.map +2 -2
  20. package/dist/generated/entities/message_channel_link/index.js +33 -0
  21. package/dist/generated/entities/message_channel_link/index.js.map +7 -0
  22. package/dist/generated/entities/message_reaction/index.js +25 -0
  23. package/dist/generated/entities/message_reaction/index.js.map +7 -0
  24. package/dist/generated/entities.ids.generated.js +11 -0
  25. package/dist/generated/entities.ids.generated.js.map +2 -2
  26. package/dist/generated/entity-fields-registry.js +117 -0
  27. package/dist/generated/entity-fields-registry.js.map +2 -2
  28. package/dist/helpers/integration/authFixtures.js +2 -1
  29. package/dist/helpers/integration/authFixtures.js.map +2 -2
  30. package/dist/helpers/integration/communicationChannelsFixtures.js +58 -0
  31. package/dist/helpers/integration/communicationChannelsFixtures.js.map +7 -0
  32. package/dist/modules/communication_channels/acl.js +47 -0
  33. package/dist/modules/communication_channels/acl.js.map +7 -0
  34. package/dist/modules/communication_channels/api/delete/channels/[id]/route.js +133 -0
  35. package/dist/modules/communication_channels/api/delete/channels/[id]/route.js.map +7 -0
  36. package/dist/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.js +113 -0
  37. package/dist/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.js.map +7 -0
  38. package/dist/modules/communication_channels/api/get/channels/[id]/health/route.js +138 -0
  39. package/dist/modules/communication_channels/api/get/channels/[id]/health/route.js.map +7 -0
  40. package/dist/modules/communication_channels/api/get/channels/[id]/route.js +93 -0
  41. package/dist/modules/communication_channels/api/get/channels/[id]/route.js.map +7 -0
  42. package/dist/modules/communication_channels/api/get/channels/route.js +96 -0
  43. package/dist/modules/communication_channels/api/get/channels/route.js.map +7 -0
  44. package/dist/modules/communication_channels/api/get/me/channels/route.js +82 -0
  45. package/dist/modules/communication_channels/api/get/me/channels/route.js.map +7 -0
  46. package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js +274 -0
  47. package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js.map +7 -0
  48. package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js +168 -0
  49. package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js.map +7 -0
  50. package/dist/modules/communication_channels/api/post/channels/[id]/poll-now/route.js +143 -0
  51. package/dist/modules/communication_channels/api/post/channels/[id]/poll-now/route.js.map +7 -0
  52. package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js +127 -0
  53. package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js.map +7 -0
  54. package/dist/modules/communication_channels/api/post/channels/[id]/set-primary/route.js +99 -0
  55. package/dist/modules/communication_channels/api/post/channels/[id]/set-primary/route.js.map +7 -0
  56. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +197 -0
  57. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +7 -0
  58. package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js +124 -0
  59. package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js.map +7 -0
  60. package/dist/modules/communication_channels/api/post/messages/[messageId]/reactions/route.js +120 -0
  61. package/dist/modules/communication_channels/api/post/messages/[messageId]/reactions/route.js.map +7 -0
  62. package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js +157 -0
  63. package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js.map +7 -0
  64. package/dist/modules/communication_channels/api/post/send-as-user/route.js +115 -0
  65. package/dist/modules/communication_channels/api/post/send-as-user/route.js.map +7 -0
  66. package/dist/modules/communication_channels/api/post/test-seed/route.js +217 -0
  67. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +7 -0
  68. package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js +175 -0
  69. package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js.map +7 -0
  70. package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js +123 -0
  71. package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js.map +7 -0
  72. package/dist/modules/communication_channels/api/put/threads/[threadId]/assign/route.js +117 -0
  73. package/dist/modules/communication_channels/api/put/threads/[threadId]/assign/route.js.map +7 -0
  74. package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js +180 -0
  75. package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js.map +7 -0
  76. package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.js +36 -0
  77. package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.js.map +7 -0
  78. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +107 -0
  79. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +7 -0
  80. package/dist/modules/communication_channels/backend/communication_channels/channels/page.meta.js +38 -0
  81. package/dist/modules/communication_channels/backend/communication_channels/channels/page.meta.js.map +7 -0
  82. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +727 -0
  83. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +7 -0
  84. package/dist/modules/communication_channels/backend/profile/communication-channels/page.meta.js +38 -0
  85. package/dist/modules/communication_channels/backend/profile/communication-channels/page.meta.js.map +7 -0
  86. package/dist/modules/communication_channels/commands/connect-credential-channel.js +154 -0
  87. package/dist/modules/communication_channels/commands/connect-credential-channel.js.map +7 -0
  88. package/dist/modules/communication_channels/commands/delete-channel.js +137 -0
  89. package/dist/modules/communication_channels/commands/delete-channel.js.map +7 -0
  90. package/dist/modules/communication_channels/commands/deliver-outbound-message.js +400 -0
  91. package/dist/modules/communication_channels/commands/deliver-outbound-message.js.map +7 -0
  92. package/dist/modules/communication_channels/commands/disconnect-channel.js +163 -0
  93. package/dist/modules/communication_channels/commands/disconnect-channel.js.map +7 -0
  94. package/dist/modules/communication_channels/commands/ingest-inbound-message.js +413 -0
  95. package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +7 -0
  96. package/dist/modules/communication_channels/commands/interceptors.js +68 -0
  97. package/dist/modules/communication_channels/commands/interceptors.js.map +7 -0
  98. package/dist/modules/communication_channels/commands/process-inbound-reaction.js +198 -0
  99. package/dist/modules/communication_channels/commands/process-inbound-reaction.js.map +7 -0
  100. package/dist/modules/communication_channels/commands/push-register.js +146 -0
  101. package/dist/modules/communication_channels/commands/push-register.js.map +7 -0
  102. package/dist/modules/communication_channels/commands/push-renew.js +23 -0
  103. package/dist/modules/communication_channels/commands/push-renew.js.map +7 -0
  104. package/dist/modules/communication_channels/commands/push-unregister.js +108 -0
  105. package/dist/modules/communication_channels/commands/push-unregister.js.map +7 -0
  106. package/dist/modules/communication_channels/commands/queue-import-history.js +113 -0
  107. package/dist/modules/communication_channels/commands/queue-import-history.js.map +7 -0
  108. package/dist/modules/communication_channels/commands/reassign-conversation.js +193 -0
  109. package/dist/modules/communication_channels/commands/reassign-conversation.js.map +7 -0
  110. package/dist/modules/communication_channels/commands/set-primary-channel.js +114 -0
  111. package/dist/modules/communication_channels/commands/set-primary-channel.js.map +7 -0
  112. package/dist/modules/communication_channels/commands/toggle-outbound-reaction.js +260 -0
  113. package/dist/modules/communication_channels/commands/toggle-outbound-reaction.js.map +7 -0
  114. package/dist/modules/communication_channels/data/enrichers.js +286 -0
  115. package/dist/modules/communication_channels/data/enrichers.js.map +7 -0
  116. package/dist/modules/communication_channels/data/entities.js +447 -0
  117. package/dist/modules/communication_channels/data/entities.js.map +7 -0
  118. package/dist/modules/communication_channels/data/extensions.js +67 -0
  119. package/dist/modules/communication_channels/data/extensions.js.map +7 -0
  120. package/dist/modules/communication_channels/data/validators.js +123 -0
  121. package/dist/modules/communication_channels/data/validators.js.map +7 -0
  122. package/dist/modules/communication_channels/di.js +35 -0
  123. package/dist/modules/communication_channels/di.js.map +7 -0
  124. package/dist/modules/communication_channels/encryption.js +12 -0
  125. package/dist/modules/communication_channels/encryption.js.map +7 -0
  126. package/dist/modules/communication_channels/events.js +124 -0
  127. package/dist/modules/communication_channels/events.js.map +7 -0
  128. package/dist/modules/communication_channels/index.js +20 -0
  129. package/dist/modules/communication_channels/index.js.map +7 -0
  130. package/dist/modules/communication_channels/lib/access-control.js +43 -0
  131. package/dist/modules/communication_channels/lib/access-control.js.map +7 -0
  132. package/dist/modules/communication_channels/lib/adapter-compat.js +36 -0
  133. package/dist/modules/communication_channels/lib/adapter-compat.js.map +7 -0
  134. package/dist/modules/communication_channels/lib/adapter-registry-singleton.js +22 -0
  135. package/dist/modules/communication_channels/lib/adapter-registry-singleton.js.map +7 -0
  136. package/dist/modules/communication_channels/lib/adapter.js +1 -0
  137. package/dist/modules/communication_channels/lib/adapter.js.map +7 -0
  138. package/dist/modules/communication_channels/lib/connect-channel.js +95 -0
  139. package/dist/modules/communication_channels/lib/connect-channel.js.map +7 -0
  140. package/dist/modules/communication_channels/lib/contact-resolver.js +79 -0
  141. package/dist/modules/communication_channels/lib/contact-resolver.js.map +7 -0
  142. package/dist/modules/communication_channels/lib/credential-refresh.js +97 -0
  143. package/dist/modules/communication_channels/lib/credential-refresh.js.map +7 -0
  144. package/dist/modules/communication_channels/lib/dead-letter.js +62 -0
  145. package/dist/modules/communication_channels/lib/dead-letter.js.map +7 -0
  146. package/dist/modules/communication_channels/lib/email-capabilities.js +47 -0
  147. package/dist/modules/communication_channels/lib/email-capabilities.js.map +7 -0
  148. package/dist/modules/communication_channels/lib/email-contact.js +14 -0
  149. package/dist/modules/communication_channels/lib/email-contact.js.map +7 -0
  150. package/dist/modules/communication_channels/lib/email-mime.js +259 -0
  151. package/dist/modules/communication_channels/lib/email-mime.js.map +7 -0
  152. package/dist/modules/communication_channels/lib/error-classification.js +101 -0
  153. package/dist/modules/communication_channels/lib/error-classification.js.map +7 -0
  154. package/dist/modules/communication_channels/lib/gmail-pubsub-jwt.js +185 -0
  155. package/dist/modules/communication_channels/lib/gmail-pubsub-jwt.js.map +7 -0
  156. package/dist/modules/communication_channels/lib/mutation-guards.js +114 -0
  157. package/dist/modules/communication_channels/lib/mutation-guards.js.map +7 -0
  158. package/dist/modules/communication_channels/lib/oauth-client-config.js +32 -0
  159. package/dist/modules/communication_channels/lib/oauth-client-config.js.map +7 -0
  160. package/dist/modules/communication_channels/lib/oauth-state.js +128 -0
  161. package/dist/modules/communication_channels/lib/oauth-state.js.map +7 -0
  162. package/dist/modules/communication_channels/lib/oauth-token.js +45 -0
  163. package/dist/modules/communication_channels/lib/oauth-token.js.map +7 -0
  164. package/dist/modules/communication_channels/lib/pg-errors.js +11 -0
  165. package/dist/modules/communication_channels/lib/pg-errors.js.map +7 -0
  166. package/dist/modules/communication_channels/lib/provider-health.js +24 -0
  167. package/dist/modules/communication_channels/lib/provider-health.js.map +7 -0
  168. package/dist/modules/communication_channels/lib/push-state.js +19 -0
  169. package/dist/modules/communication_channels/lib/push-state.js.map +7 -0
  170. package/dist/modules/communication_channels/lib/queue.js +54 -0
  171. package/dist/modules/communication_channels/lib/queue.js.map +7 -0
  172. package/dist/modules/communication_channels/lib/reaction-processor-types.js +5 -0
  173. package/dist/modules/communication_channels/lib/reaction-processor-types.js.map +7 -0
  174. package/dist/modules/communication_channels/lib/reaction-semantics.js +11 -0
  175. package/dist/modules/communication_channels/lib/reaction-semantics.js.map +7 -0
  176. package/dist/modules/communication_channels/lib/registry.js +67 -0
  177. package/dist/modules/communication_channels/lib/registry.js.map +7 -0
  178. package/dist/modules/communication_channels/lib/route-mutation-guard.js +43 -0
  179. package/dist/modules/communication_channels/lib/route-mutation-guard.js.map +7 -0
  180. package/dist/modules/communication_channels/lib/sanitize-channel-html.js +96 -0
  181. package/dist/modules/communication_channels/lib/sanitize-channel-html.js.map +7 -0
  182. package/dist/modules/communication_channels/lib/send-as-user.js +194 -0
  183. package/dist/modules/communication_channels/lib/send-as-user.js.map +7 -0
  184. package/dist/modules/communication_channels/lib/system-user.js +22 -0
  185. package/dist/modules/communication_channels/lib/system-user.js.map +7 -0
  186. package/dist/modules/communication_channels/lib/test-seed.js +68 -0
  187. package/dist/modules/communication_channels/lib/test-seed.js.map +7 -0
  188. package/dist/modules/communication_channels/lib/thread-matcher.js +263 -0
  189. package/dist/modules/communication_channels/lib/thread-matcher.js.map +7 -0
  190. package/dist/modules/communication_channels/lib/thread-token.js +219 -0
  191. package/dist/modules/communication_channels/lib/thread-token.js.map +7 -0
  192. package/dist/modules/communication_channels/lib/use-connect-channel.js +61 -0
  193. package/dist/modules/communication_channels/lib/use-connect-channel.js.map +7 -0
  194. package/dist/modules/communication_channels/migrations/Migration20260526134719_communication_channels.js +50 -0
  195. package/dist/modules/communication_channels/migrations/Migration20260526134719_communication_channels.js.map +7 -0
  196. package/dist/modules/communication_channels/migrations/Migration20260527195446_communication_channels.js +19 -0
  197. package/dist/modules/communication_channels/migrations/Migration20260527195446_communication_channels.js.map +7 -0
  198. package/dist/modules/communication_channels/migrations/Migration20260529231848_communication_channels.js +13 -0
  199. package/dist/modules/communication_channels/migrations/Migration20260529231848_communication_channels.js.map +7 -0
  200. package/dist/modules/communication_channels/migrations/Migration20260531120000_communication_channels.js +17 -0
  201. package/dist/modules/communication_channels/migrations/Migration20260531120000_communication_channels.js.map +7 -0
  202. package/dist/modules/communication_channels/notifications.client.js +51 -0
  203. package/dist/modules/communication_channels/notifications.client.js.map +7 -0
  204. package/dist/modules/communication_channels/notifications.handlers.js +53 -0
  205. package/dist/modules/communication_channels/notifications.handlers.js.map +7 -0
  206. package/dist/modules/communication_channels/notifications.js +56 -0
  207. package/dist/modules/communication_channels/notifications.js.map +7 -0
  208. package/dist/modules/communication_channels/setup.js +105 -0
  209. package/dist/modules/communication_channels/setup.js.map +7 -0
  210. package/dist/modules/communication_channels/subscribers/channel-requires-reauth-notification.js +71 -0
  211. package/dist/modules/communication_channels/subscribers/channel-requires-reauth-notification.js.map +7 -0
  212. package/dist/modules/communication_channels/subscribers/outbound-bridge.js +103 -0
  213. package/dist/modules/communication_channels/subscribers/outbound-bridge.js.map +7 -0
  214. package/dist/modules/communication_channels/subscribers/user-deleted-cascade.js +51 -0
  215. package/dist/modules/communication_channels/subscribers/user-deleted-cascade.js.map +7 -0
  216. package/dist/modules/communication_channels/widgets/components.js +7 -0
  217. package/dist/modules/communication_channels/widgets/components.js.map +7 -0
  218. package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.client.js +18 -0
  219. package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.client.js.map +7 -0
  220. package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.js +30 -0
  221. package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.js.map +7 -0
  222. package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.js +185 -0
  223. package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.js.map +7 -0
  224. package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.js +17 -0
  225. package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.js.map +7 -0
  226. package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js +44 -0
  227. package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js.map +7 -0
  228. package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.js +17 -0
  229. package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.js.map +7 -0
  230. package/dist/modules/communication_channels/widgets/injection/profile-channels-menu/widget.js +23 -0
  231. package/dist/modules/communication_channels/widgets/injection/profile-channels-menu/widget.js.map +7 -0
  232. package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.client.js +141 -0
  233. package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.client.js.map +7 -0
  234. package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.js +17 -0
  235. package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.js.map +7 -0
  236. package/dist/modules/communication_channels/widgets/injection-table.js +38 -0
  237. package/dist/modules/communication_channels/widgets/injection-table.js.map +7 -0
  238. package/dist/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.js +25 -0
  239. package/dist/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.js.map +7 -0
  240. package/dist/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.js +19 -0
  241. package/dist/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.js.map +7 -0
  242. package/dist/modules/communication_channels/widgets/notifications/index.js +7 -0
  243. package/dist/modules/communication_channels/widgets/notifications/index.js.map +7 -0
  244. package/dist/modules/communication_channels/workers/channel-import-history.js +185 -0
  245. package/dist/modules/communication_channels/workers/channel-import-history.js.map +7 -0
  246. package/dist/modules/communication_channels/workers/gmail-history-sync.js +154 -0
  247. package/dist/modules/communication_channels/workers/gmail-history-sync.js.map +7 -0
  248. package/dist/modules/communication_channels/workers/gmail-renew-watch.js +95 -0
  249. package/dist/modules/communication_channels/workers/gmail-renew-watch.js.map +7 -0
  250. package/dist/modules/communication_channels/workers/inbound-processor.js +56 -0
  251. package/dist/modules/communication_channels/workers/inbound-processor.js.map +7 -0
  252. package/dist/modules/communication_channels/workers/outbound-delivery.js +85 -0
  253. package/dist/modules/communication_channels/workers/outbound-delivery.js.map +7 -0
  254. package/dist/modules/communication_channels/workers/poll-channel.js +240 -0
  255. package/dist/modules/communication_channels/workers/poll-channel.js.map +7 -0
  256. package/dist/modules/communication_channels/workers/poll-tick.js +132 -0
  257. package/dist/modules/communication_channels/workers/poll-tick.js.map +7 -0
  258. package/dist/modules/communication_channels/workers/reaction-processor.js +192 -0
  259. package/dist/modules/communication_channels/workers/reaction-processor.js.map +7 -0
  260. package/dist/modules/customers/acl.js +18 -0
  261. package/dist/modules/customers/acl.js.map +2 -2
  262. package/dist/modules/customers/api/activities/route.js +9 -0
  263. package/dist/modules/customers/api/activities/route.js.map +2 -2
  264. package/dist/modules/customers/api/companies/[id]/route.js +18 -7
  265. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  266. package/dist/modules/customers/api/interactions/[id]/visibility/route.js +151 -0
  267. package/dist/modules/customers/api/interactions/[id]/visibility/route.js.map +7 -0
  268. package/dist/modules/customers/api/interactions/counts/route.js +6 -0
  269. package/dist/modules/customers/api/interactions/counts/route.js.map +2 -2
  270. package/dist/modules/customers/api/interactions/route.js +26 -7
  271. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  272. package/dist/modules/customers/api/people/[id]/email-threads/route.js +82 -0
  273. package/dist/modules/customers/api/people/[id]/email-threads/route.js.map +7 -0
  274. package/dist/modules/customers/api/people/[id]/emails/route.js +157 -0
  275. package/dist/modules/customers/api/people/[id]/emails/route.js.map +7 -0
  276. package/dist/modules/customers/api/people/[id]/route.js +12 -4
  277. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  278. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +10 -0
  279. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  280. package/dist/modules/customers/commands/deals.js +46 -5
  281. package/dist/modules/customers/commands/deals.js.map +2 -2
  282. package/dist/modules/customers/commands/interactions.js +16 -0
  283. package/dist/modules/customers/commands/interactions.js.map +2 -2
  284. package/dist/modules/customers/components/detail/ActivityCard.js +32 -0
  285. package/dist/modules/customers/components/detail/ActivityCard.js.map +2 -2
  286. package/dist/modules/customers/components/detail/ComposeEmailDialog.js +242 -0
  287. package/dist/modules/customers/components/detail/ComposeEmailDialog.js.map +7 -0
  288. package/dist/modules/customers/components/detail/DealForm.js +2 -1
  289. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  290. package/dist/modules/customers/components/detail/DealsSection.js +10 -0
  291. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  292. package/dist/modules/customers/components/detail/EmailCardActions.js +179 -0
  293. package/dist/modules/customers/components/detail/EmailCardActions.js.map +7 -0
  294. package/dist/modules/customers/components/detail/EmailReplyForwardActions.js +52 -0
  295. package/dist/modules/customers/components/detail/EmailReplyForwardActions.js.map +7 -0
  296. package/dist/modules/customers/components/detail/PersonDetailTabs.js +7 -1
  297. package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
  298. package/dist/modules/customers/components/detail/PersonEmailThreadsTab.js +366 -0
  299. package/dist/modules/customers/components/detail/PersonEmailThreadsTab.js.map +7 -0
  300. package/dist/modules/customers/data/enrichers.js +133 -2
  301. package/dist/modules/customers/data/enrichers.js.map +2 -2
  302. package/dist/modules/customers/data/entities.js +18 -0
  303. package/dist/modules/customers/data/entities.js.map +2 -2
  304. package/dist/modules/customers/data/extensions.js +16 -0
  305. package/dist/modules/customers/data/extensions.js.map +7 -0
  306. package/dist/modules/customers/encryption.js +11 -0
  307. package/dist/modules/customers/encryption.js.map +2 -2
  308. package/dist/modules/customers/events.js +4 -1
  309. package/dist/modules/customers/events.js.map +2 -2
  310. package/dist/modules/customers/lib/findPeopleByAddresses.js +64 -0
  311. package/dist/modules/customers/lib/findPeopleByAddresses.js.map +7 -0
  312. package/dist/modules/customers/lib/kysely.js.map +2 -2
  313. package/dist/modules/customers/lib/link-channel-message-handler.js +303 -0
  314. package/dist/modules/customers/lib/link-channel-message-handler.js.map +7 -0
  315. package/dist/modules/customers/lib/personEmailThreads.js +205 -0
  316. package/dist/modules/customers/lib/personEmailThreads.js.map +7 -0
  317. package/dist/modules/customers/lib/visibilityFilter.js +51 -0
  318. package/dist/modules/customers/lib/visibilityFilter.js.map +7 -0
  319. package/dist/modules/customers/migrations/Migration20260527012240_customers.js +20 -0
  320. package/dist/modules/customers/migrations/Migration20260527012240_customers.js.map +7 -0
  321. package/dist/modules/customers/setup.js +2 -1
  322. package/dist/modules/customers/setup.js.map +2 -2
  323. package/dist/modules/customers/subscribers/link-channel-message-received.js +12 -0
  324. package/dist/modules/customers/subscribers/link-channel-message-received.js.map +7 -0
  325. package/dist/modules/customers/subscribers/link-channel-message-sent.js +12 -0
  326. package/dist/modules/customers/subscribers/link-channel-message-sent.js.map +7 -0
  327. package/dist/modules/integrations/data/entities.js +8 -1
  328. package/dist/modules/integrations/data/entities.js.map +2 -2
  329. package/dist/modules/integrations/lib/credentials-service.js +29 -14
  330. package/dist/modules/integrations/lib/credentials-service.js.map +2 -2
  331. package/dist/modules/integrations/migrations/Migration20260526154136_integrations.js +15 -0
  332. package/dist/modules/integrations/migrations/Migration20260526154136_integrations.js.map +7 -0
  333. package/dist/modules/messages/commands/messages.js +70 -8
  334. package/dist/modules/messages/commands/messages.js.map +2 -2
  335. package/dist/modules/messages/components/ComposeMessagePageClient.js +24 -13
  336. package/dist/modules/messages/components/ComposeMessagePageClient.js.map +2 -2
  337. package/dist/modules/messages/components/MessageDetailPageClient.js +39 -2
  338. package/dist/modules/messages/components/MessageDetailPageClient.js.map +2 -2
  339. package/dist/modules/messages/components/MessagesInboxPageClient.js +1 -0
  340. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  341. package/dist/modules/messages/data/entities.js +8 -1
  342. package/dist/modules/messages/data/entities.js.map +2 -2
  343. package/dist/modules/messages/migrations/Migration20260531130000.js +15 -0
  344. package/dist/modules/messages/migrations/Migration20260531130000.js.map +7 -0
  345. package/dist/modules/messages/widgets/injection-table.js +7 -0
  346. package/dist/modules/messages/widgets/injection-table.js.map +7 -0
  347. package/generated/entities/channel_ingest_dead_letter/index.ts +11 -0
  348. package/generated/entities/channel_thread_mapping/index.ts +11 -0
  349. package/generated/entities/channel_thread_token/index.ts +7 -0
  350. package/generated/entities/communication_channel/index.ts +20 -0
  351. package/generated/entities/customer_interaction/index.ts +2 -0
  352. package/generated/entities/external_conversation/index.ts +11 -0
  353. package/generated/entities/external_message/index.ts +11 -0
  354. package/generated/entities/integration_credentials/index.ts +1 -0
  355. package/generated/entities/message/index.ts +1 -0
  356. package/generated/entities/message_channel_link/index.ts +15 -0
  357. package/generated/entities/message_reaction/index.ts +11 -0
  358. package/generated/entities.ids.generated.ts +11 -0
  359. package/generated/entity-fields-registry.ts +117 -0
  360. package/package.json +9 -7
  361. package/src/helpers/integration/authFixtures.ts +4 -1
  362. package/src/helpers/integration/communicationChannelsFixtures.ts +124 -0
  363. package/src/modules/communication_channels/acl.ts +43 -0
  364. package/src/modules/communication_channels/api/delete/channels/[id]/route.ts +163 -0
  365. package/src/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.ts +143 -0
  366. package/src/modules/communication_channels/api/get/channels/[id]/health/route.ts +173 -0
  367. package/src/modules/communication_channels/api/get/channels/[id]/route.ts +111 -0
  368. package/src/modules/communication_channels/api/get/channels/route.ts +109 -0
  369. package/src/modules/communication_channels/api/get/me/channels/route.ts +100 -0
  370. package/src/modules/communication_channels/api/get/oauth/[provider]/callback/route.ts +355 -0
  371. package/src/modules/communication_channels/api/post/channels/[id]/import-history/route.ts +206 -0
  372. package/src/modules/communication_channels/api/post/channels/[id]/poll-now/route.ts +174 -0
  373. package/src/modules/communication_channels/api/post/channels/[id]/push/register/route.ts +158 -0
  374. package/src/modules/communication_channels/api/post/channels/[id]/set-primary/route.ts +114 -0
  375. package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +241 -0
  376. package/src/modules/communication_channels/api/post/channels/connect/credentials/route.ts +134 -0
  377. package/src/modules/communication_channels/api/post/messages/[messageId]/reactions/route.ts +143 -0
  378. package/src/modules/communication_channels/api/post/oauth/[provider]/initiate/route.ts +192 -0
  379. package/src/modules/communication_channels/api/post/send-as-user/route.ts +125 -0
  380. package/src/modules/communication_channels/api/post/test-seed/route.ts +267 -0
  381. package/src/modules/communication_channels/api/post/webhook/[provider]/route.ts +227 -0
  382. package/src/modules/communication_channels/api/post/webhooks/gmail/route.ts +161 -0
  383. package/src/modules/communication_channels/api/put/threads/[threadId]/assign/route.ts +132 -0
  384. package/src/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.ts +34 -0
  385. package/src/modules/communication_channels/backend/communication_channels/channels/[id]/page.tsx +250 -0
  386. package/src/modules/communication_channels/backend/communication_channels/channels/page.meta.ts +36 -0
  387. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +137 -0
  388. package/src/modules/communication_channels/backend/profile/communication-channels/page.meta.ts +36 -0
  389. package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +907 -0
  390. package/src/modules/communication_channels/commands/connect-credential-channel.ts +243 -0
  391. package/src/modules/communication_channels/commands/delete-channel.ts +193 -0
  392. package/src/modules/communication_channels/commands/deliver-outbound-message.ts +579 -0
  393. package/src/modules/communication_channels/commands/disconnect-channel.ts +241 -0
  394. package/src/modules/communication_channels/commands/ingest-inbound-message.ts +602 -0
  395. package/src/modules/communication_channels/commands/interceptors.ts +104 -0
  396. package/src/modules/communication_channels/commands/process-inbound-reaction.ts +265 -0
  397. package/src/modules/communication_channels/commands/push-register.ts +203 -0
  398. package/src/modules/communication_channels/commands/push-renew.ts +49 -0
  399. package/src/modules/communication_channels/commands/push-unregister.ts +168 -0
  400. package/src/modules/communication_channels/commands/queue-import-history.ts +180 -0
  401. package/src/modules/communication_channels/commands/reassign-conversation.ts +273 -0
  402. package/src/modules/communication_channels/commands/set-primary-channel.ts +154 -0
  403. package/src/modules/communication_channels/commands/toggle-outbound-reaction.ts +347 -0
  404. package/src/modules/communication_channels/data/enrichers.ts +413 -0
  405. package/src/modules/communication_channels/data/entities.ts +546 -0
  406. package/src/modules/communication_channels/data/extensions.ts +76 -0
  407. package/src/modules/communication_channels/data/validators.ts +138 -0
  408. package/src/modules/communication_channels/di.ts +40 -0
  409. package/src/modules/communication_channels/encryption.ts +44 -0
  410. package/src/modules/communication_channels/events.ts +122 -0
  411. package/src/modules/communication_channels/i18n/de.json +138 -0
  412. package/src/modules/communication_channels/i18n/en.json +138 -0
  413. package/src/modules/communication_channels/i18n/es.json +138 -0
  414. package/src/modules/communication_channels/i18n/pl.json +138 -0
  415. package/src/modules/communication_channels/index.ts +19 -0
  416. package/src/modules/communication_channels/lib/access-control.ts +110 -0
  417. package/src/modules/communication_channels/lib/adapter-compat.ts +57 -0
  418. package/src/modules/communication_channels/lib/adapter-registry-singleton.ts +35 -0
  419. package/src/modules/communication_channels/lib/adapter.ts +605 -0
  420. package/src/modules/communication_channels/lib/connect-channel.ts +163 -0
  421. package/src/modules/communication_channels/lib/contact-resolver.ts +162 -0
  422. package/src/modules/communication_channels/lib/credential-refresh.ts +197 -0
  423. package/src/modules/communication_channels/lib/dead-letter.ts +87 -0
  424. package/src/modules/communication_channels/lib/email-capabilities.ts +60 -0
  425. package/src/modules/communication_channels/lib/email-contact.ts +17 -0
  426. package/src/modules/communication_channels/lib/email-mime.ts +425 -0
  427. package/src/modules/communication_channels/lib/error-classification.ts +144 -0
  428. package/src/modules/communication_channels/lib/gmail-pubsub-jwt.ts +278 -0
  429. package/src/modules/communication_channels/lib/mutation-guards.ts +215 -0
  430. package/src/modules/communication_channels/lib/oauth-client-config.ts +79 -0
  431. package/src/modules/communication_channels/lib/oauth-state.ts +228 -0
  432. package/src/modules/communication_channels/lib/oauth-token.ts +81 -0
  433. package/src/modules/communication_channels/lib/pg-errors.ts +12 -0
  434. package/src/modules/communication_channels/lib/provider-health.ts +47 -0
  435. package/src/modules/communication_channels/lib/push-state.ts +38 -0
  436. package/src/modules/communication_channels/lib/queue.ts +66 -0
  437. package/src/modules/communication_channels/lib/reaction-processor-types.ts +51 -0
  438. package/src/modules/communication_channels/lib/reaction-semantics.ts +48 -0
  439. package/src/modules/communication_channels/lib/registry.ts +99 -0
  440. package/src/modules/communication_channels/lib/route-mutation-guard.ts +68 -0
  441. package/src/modules/communication_channels/lib/sanitize-channel-html.ts +129 -0
  442. package/src/modules/communication_channels/lib/send-as-user.ts +284 -0
  443. package/src/modules/communication_channels/lib/system-user.ts +74 -0
  444. package/src/modules/communication_channels/lib/test-seed.ts +140 -0
  445. package/src/modules/communication_channels/lib/thread-matcher.ts +430 -0
  446. package/src/modules/communication_channels/lib/thread-token.ts +355 -0
  447. package/src/modules/communication_channels/lib/use-connect-channel.ts +73 -0
  448. package/src/modules/communication_channels/migrations/.snapshot-open-mercato.json +2142 -0
  449. package/src/modules/communication_channels/migrations/Migration20260526134719_communication_channels.ts +55 -0
  450. package/src/modules/communication_channels/migrations/Migration20260527195446_communication_channels.ts +20 -0
  451. package/src/modules/communication_channels/migrations/Migration20260529231848_communication_channels.ts +13 -0
  452. package/src/modules/communication_channels/migrations/Migration20260531120000_communication_channels.ts +24 -0
  453. package/src/modules/communication_channels/notifications.client.ts +50 -0
  454. package/src/modules/communication_channels/notifications.handlers.ts +86 -0
  455. package/src/modules/communication_channels/notifications.ts +52 -0
  456. package/src/modules/communication_channels/setup.ts +158 -0
  457. package/src/modules/communication_channels/subscribers/channel-requires-reauth-notification.ts +118 -0
  458. package/src/modules/communication_channels/subscribers/outbound-bridge.ts +175 -0
  459. package/src/modules/communication_channels/subscribers/user-deleted-cascade.ts +100 -0
  460. package/src/modules/communication_channels/widgets/components.ts +36 -0
  461. package/src/modules/communication_channels/widgets/injection/channel-badge/widget.client.tsx +38 -0
  462. package/src/modules/communication_channels/widgets/injection/channel-badge/widget.ts +51 -0
  463. package/src/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.tsx +278 -0
  464. package/src/modules/communication_channels/widgets/injection/channel-info-panel/widget.ts +24 -0
  465. package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.tsx +63 -0
  466. package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.ts +29 -0
  467. package/src/modules/communication_channels/widgets/injection/profile-channels-menu/widget.ts +34 -0
  468. package/src/modules/communication_channels/widgets/injection/reaction-bar/widget.client.tsx +177 -0
  469. package/src/modules/communication_channels/widgets/injection/reaction-bar/widget.ts +26 -0
  470. package/src/modules/communication_channels/widgets/injection-table.ts +47 -0
  471. package/src/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.tsx +48 -0
  472. package/src/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.tsx +45 -0
  473. package/src/modules/communication_channels/widgets/notifications/index.ts +2 -0
  474. package/src/modules/communication_channels/workers/channel-import-history.ts +252 -0
  475. package/src/modules/communication_channels/workers/gmail-history-sync.ts +223 -0
  476. package/src/modules/communication_channels/workers/gmail-renew-watch.ts +141 -0
  477. package/src/modules/communication_channels/workers/inbound-processor.ts +114 -0
  478. package/src/modules/communication_channels/workers/outbound-delivery.ts +155 -0
  479. package/src/modules/communication_channels/workers/poll-channel.ts +391 -0
  480. package/src/modules/communication_channels/workers/poll-tick.ts +210 -0
  481. package/src/modules/communication_channels/workers/reaction-processor.ts +264 -0
  482. package/src/modules/customers/acl.ts +18 -0
  483. package/src/modules/customers/api/activities/route.ts +13 -0
  484. package/src/modules/customers/api/companies/[id]/route.ts +21 -1
  485. package/src/modules/customers/api/interactions/[id]/visibility/route.ts +179 -0
  486. package/src/modules/customers/api/interactions/counts/route.ts +10 -0
  487. package/src/modules/customers/api/interactions/route.ts +51 -5
  488. package/src/modules/customers/api/people/[id]/email-threads/route.ts +92 -0
  489. package/src/modules/customers/api/people/[id]/emails/route.ts +184 -0
  490. package/src/modules/customers/api/people/[id]/route.ts +17 -2
  491. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +11 -1
  492. package/src/modules/customers/commands/deals.ts +65 -6
  493. package/src/modules/customers/commands/interactions.ts +30 -0
  494. package/src/modules/customers/components/detail/ActivityCard.tsx +48 -0
  495. package/src/modules/customers/components/detail/ComposeEmailDialog.tsx +329 -0
  496. package/src/modules/customers/components/detail/DealForm.tsx +2 -1
  497. package/src/modules/customers/components/detail/DealsSection.tsx +26 -0
  498. package/src/modules/customers/components/detail/EmailCardActions.tsx +258 -0
  499. package/src/modules/customers/components/detail/EmailReplyForwardActions.tsx +53 -0
  500. package/src/modules/customers/components/detail/PersonDetailTabs.tsx +8 -1
  501. package/src/modules/customers/components/detail/PersonEmailThreadsTab.tsx +448 -0
  502. package/src/modules/customers/data/enrichers.ts +252 -1
  503. package/src/modules/customers/data/entities.ts +46 -1
  504. package/src/modules/customers/data/extensions.ts +26 -0
  505. package/src/modules/customers/encryption.ts +11 -0
  506. package/src/modules/customers/events.ts +4 -0
  507. package/src/modules/customers/i18n/de.json +41 -0
  508. package/src/modules/customers/i18n/en.json +41 -0
  509. package/src/modules/customers/i18n/es.json +41 -0
  510. package/src/modules/customers/i18n/pl.json +41 -0
  511. package/src/modules/customers/lib/findPeopleByAddresses.ts +107 -0
  512. package/src/modules/customers/lib/kysely.ts +16 -0
  513. package/src/modules/customers/lib/link-channel-message-handler.ts +571 -0
  514. package/src/modules/customers/lib/personEmailThreads.ts +325 -0
  515. package/src/modules/customers/lib/visibilityFilter.ts +152 -0
  516. package/src/modules/customers/migrations/.snapshot-open-mercato.json +61 -0
  517. package/src/modules/customers/migrations/Migration20260527012240_customers.ts +23 -0
  518. package/src/modules/customers/setup.ts +1 -0
  519. package/src/modules/customers/subscribers/link-channel-message-received.ts +21 -0
  520. package/src/modules/customers/subscribers/link-channel-message-sent.ts +21 -0
  521. package/src/modules/integrations/AGENTS.md +9 -0
  522. package/src/modules/integrations/data/entities.ts +21 -1
  523. package/src/modules/integrations/lib/credentials-service.ts +49 -13
  524. package/src/modules/integrations/migrations/.snapshot-open-mercato.json +26 -1
  525. package/src/modules/integrations/migrations/Migration20260526154136_integrations.ts +15 -0
  526. package/src/modules/messages/commands/messages.ts +101 -8
  527. package/src/modules/messages/components/ComposeMessagePageClient.tsx +17 -0
  528. package/src/modules/messages/components/MessageDetailPageClient.tsx +43 -0
  529. package/src/modules/messages/components/MessagesInboxPageClient.tsx +4 -0
  530. package/src/modules/messages/data/entities.ts +11 -0
  531. package/src/modules/messages/migrations/.snapshot-open-mercato.json +18 -0
  532. package/src/modules/messages/migrations/Migration20260531130000.ts +15 -0
  533. package/src/modules/messages/widgets/injection-table.ts +29 -0
@@ -0,0 +1,138 @@
1
+ import { z } from 'zod'
2
+
3
+ /**
4
+ * Zod schemas for adapter inputs and API request/response bodies.
5
+ *
6
+ * These mirror the TypeScript interfaces in `lib/adapter.ts`. They are used by:
7
+ * - API route handlers to validate incoming requests
8
+ * - Adapter implementations that prefer runtime validation over TypeScript-only types
9
+ * - `validateCredentials?(...)` flow on credential-based providers
10
+ */
11
+
12
+ export const tenantScopeSchema = z.object({
13
+ organizationId: z.string().uuid().nullable().optional(),
14
+ tenantId: z.string().uuid(),
15
+ })
16
+
17
+ export const channelCapabilitiesSchema = z.object({
18
+ threading: z.boolean(),
19
+ richText: z.boolean(),
20
+ fileSharing: z.boolean(),
21
+ maxFileSize: z.number().int().nonnegative().optional(),
22
+ supportedMimeTypes: z.array(z.string()).optional(),
23
+ readReceipts: z.boolean(),
24
+ deliveryReceipts: z.boolean(),
25
+ typingIndicators: z.boolean(),
26
+ reactions: z.boolean(),
27
+ multiReactionPerUser: z.boolean(),
28
+ editMessage: z.boolean(),
29
+ deleteMessage: z.boolean(),
30
+ presence: z.boolean(),
31
+ richBlocks: z.boolean(),
32
+ interactiveComponents: z.boolean(),
33
+ inlineImages: z.boolean(),
34
+ conversationHistory: z.boolean(),
35
+ contactCards: z.boolean(),
36
+ locationSharing: z.boolean(),
37
+ voiceNotes: z.boolean(),
38
+ stickers: z.boolean(),
39
+ supportedBodyFormats: z.array(z.enum(['text', 'markdown', 'html'])),
40
+ maxBodyLength: z.number().int().positive().optional(),
41
+ realtimePush: z.boolean().optional(),
42
+ })
43
+
44
+ export const normalizedAttachmentSchema = z.object({
45
+ url: z.string().url(),
46
+ mimeType: z.string().min(1),
47
+ fileName: z.string().min(1),
48
+ fileSize: z.number().int().nonnegative().optional(),
49
+ inline: z.boolean().optional(),
50
+ })
51
+
52
+ export const messageContentSchema = z.object({
53
+ text: z.string().optional(),
54
+ html: z.string().optional(),
55
+ bodyFormat: z.enum(['text', 'markdown', 'html']).optional(),
56
+ attachments: z.array(normalizedAttachmentSchema).optional(),
57
+ raw: z.record(z.string(), z.unknown()).optional(),
58
+ })
59
+
60
+ export const sendMessageInputSchema = z.object({
61
+ conversationId: z.string().optional(),
62
+ content: messageContentSchema,
63
+ credentials: z.record(z.string(), z.unknown()),
64
+ scope: tenantScopeSchema,
65
+ metadata: z.record(z.string(), z.unknown()).optional(),
66
+ })
67
+
68
+ export const validateCredentialsInputSchema = z.object({
69
+ providerKey: z.string().min(1),
70
+ credentials: z.record(z.string(), z.unknown()),
71
+ scope: tenantScopeSchema,
72
+ })
73
+
74
+ export const validateCredentialsResultSchema = z.object({
75
+ ok: z.boolean(),
76
+ errors: z.record(z.string(), z.string()).optional(),
77
+ })
78
+
79
+ export const refreshCredentialsInputSchema = z.object({
80
+ channelId: z.string().uuid(),
81
+ credentials: z.record(z.string(), z.unknown()),
82
+ scope: tenantScopeSchema,
83
+ })
84
+
85
+ export const refreshedCredentialsSchema = z.object({
86
+ credentials: z.record(z.string(), z.unknown()),
87
+ expiresAt: z.date().optional(),
88
+ })
89
+
90
+ export const inboundReactionSchema = z.object({
91
+ emoji: z.string().min(1),
92
+ userIdentifier: z.string().min(1),
93
+ userDisplayName: z.string().optional(),
94
+ timestamp: z.date().optional(),
95
+ })
96
+
97
+ /**
98
+ * Canonical normalized inbound reaction event — matches `InboundReactionEvent`
99
+ * in `lib/adapter.ts`. Used by the reactions queue for type-safe payloads.
100
+ */
101
+ export const inboundReactionEventSchema = z.object({
102
+ externalMessageId: z.string().min(1),
103
+ externalConversationId: z.string().min(1).optional(),
104
+ externalReactionId: z.string().min(1).optional(),
105
+ emoji: z.string().min(1).max(64),
106
+ userIdentifier: z.string().min(1),
107
+ userDisplayName: z.string().optional(),
108
+ action: z.enum(['added', 'removed']),
109
+ timestamp: z.date().optional(),
110
+ raw: z.record(z.string(), z.unknown()).optional(),
111
+ })
112
+
113
+ export const normalizedInboundMessageSchema = z.object({
114
+ externalMessageId: z.string().min(1),
115
+ externalConversationId: z.string().min(1),
116
+ senderIdentifier: z.string().min(1),
117
+ senderDisplayName: z.string().optional(),
118
+ senderAvatarUrl: z.string().url().optional(),
119
+ subject: z.string().optional(),
120
+ body: z.string(),
121
+ bodyFormat: z.enum(['text', 'markdown', 'html']),
122
+ attachments: z.array(normalizedAttachmentSchema).optional(),
123
+ timestamp: z.date(),
124
+ replyToExternalId: z.string().optional(),
125
+ channelPayload: z.record(z.string(), z.unknown()),
126
+ channelContentType: z.string().min(1),
127
+ channelMetadata: z.record(z.string(), z.unknown()),
128
+ reactions: z.array(inboundReactionSchema).optional(),
129
+ })
130
+
131
+ export const reactionApiBodySchema = z.object({
132
+ emoji: z.string().min(1).max(64),
133
+ })
134
+
135
+ export type SendMessageInputDto = z.infer<typeof sendMessageInputSchema>
136
+ export type NormalizedInboundMessageDto = z.infer<typeof normalizedInboundMessageSchema>
137
+ export type ChannelCapabilitiesDto = z.infer<typeof channelCapabilitiesSchema>
138
+ export type ReactionApiBodyDto = z.infer<typeof reactionApiBodySchema>
@@ -0,0 +1,40 @@
1
+ import { asValue } from 'awilix'
2
+ import type { AppContainer } from '@open-mercato/shared/lib/di/container'
3
+ import {
4
+ CommunicationChannel,
5
+ ExternalConversation,
6
+ ExternalMessage,
7
+ MessageChannelLink,
8
+ ChannelThreadMapping,
9
+ MessageReaction,
10
+ } from './data/entities'
11
+ import { getChannelAdapterRegistry } from './lib/adapter-registry-singleton'
12
+ import { ensureTestSeedAdapterRegistered } from './lib/test-seed'
13
+ import { sendAsUser } from './lib/send-as-user'
14
+
15
+ export function register(container: AppContainer) {
16
+ // Test-only: register the network-free stub channel adapter when
17
+ // `OM_ENABLE_TEST_CHANNEL_SEEDING` is set (no-op in production). Lets the
18
+ // integration harness connect a channel + complete the outbound send chain.
19
+ // See lib/test-seed.ts.
20
+ ensureTestSeedAdapterRegistered()
21
+
22
+ container.register({
23
+ // Entity class registrations (for EntityManager lookups by string)
24
+ CommunicationChannel: asValue(CommunicationChannel),
25
+ ExternalConversation: asValue(ExternalConversation),
26
+ ExternalMessage: asValue(ExternalMessage),
27
+ MessageChannelLink: asValue(MessageChannelLink),
28
+ ChannelThreadMapping: asValue(ChannelThreadMapping),
29
+ MessageReaction: asValue(MessageReaction),
30
+
31
+ // Channel adapter registry — process-wide singleton backed by globalThis so
32
+ // the auth-less webhook route resolves the same registry as DI consumers.
33
+ // See lib/adapter-registry-singleton.ts.
34
+ channelAdapterRegistry: asValue(getChannelAdapterRegistry()),
35
+
36
+ // In-process send-as-user facade. Cross-module callers (e.g. the customers
37
+ // compose route) resolve this instead of making an HTTP self-call.
38
+ communicationChannelsSendAsUser: asValue(sendAsUser),
39
+ })
40
+ }
@@ -0,0 +1,44 @@
1
+ import type { ModuleEncryptionMap } from '@open-mercato/shared/modules/encryption'
2
+
3
+ /**
4
+ * Per-entity encryption maps for the communication_channels module.
5
+ *
6
+ * Credential encryption for `IntegrationCredentials.credentials` is owned by
7
+ * the `integrations` module (see packages/core/src/modules/integrations/encryption.ts).
8
+ *
9
+ * `ChannelIngestDeadLetter.raw_body` holds truncated MIME bodies of
10
+ * permanently-failed inbound messages. MIME bodies routinely contain PII
11
+ * (sender/recipient addresses, quoted prior emails, attachments), so the
12
+ * column is encrypted at rest. Reads use `findWithDecryption` per the
13
+ * `packages/core/AGENTS.md` Encryption section.
14
+ *
15
+ * At-rest posture for the OTHER PII-bearing hub columns (deliberate, reviewed):
16
+ * - The canonical email content is already encrypted in its PRIMARY stores —
17
+ * `messages.message` (subject/body/external_email+hash; see
18
+ * messages/encryption.ts) and `customers.customer_interaction` (title/body).
19
+ * - The hub keeps SECONDARY copies that are currently PLAINTEXT at rest:
20
+ * `external_messages.sender_identifier`/`sender_display_name`,
21
+ * `external_conversations.subject`, and `message_channel_links.channel_payload`.
22
+ * The per-user access-control layer governs who can READ these; at-rest
23
+ * encryption is a separate concern tracked as a follow-up (it requires
24
+ * auditing every read path — the `_channelPayload` enricher and the
25
+ * channel-payload renderer read these — to route through `findWithDecryption`).
26
+ * - `message_channel_links.channel_metadata` MUST stay plaintext: the thread
27
+ * matcher and sent-folder dedup query `channel_metadata->>'messageId'` BY
28
+ * VALUE, and an encrypted column is not queryable by value (§16 footgun).
29
+ * - `external_messages.sender_identifier` similarly needs a deterministic
30
+ * `*_hash` blind-index column before it can be encrypted, because inbound
31
+ * contact resolution looks addresses up by value (see the address blind-index
32
+ * follow-up in customers/lib/findPeopleByAddresses.ts).
33
+ *
34
+ * See `.ai/specs/2026-05-27-email-integration-inbound-reliability-and-threading.md`
35
+ * (§ 3 Encryption posture).
36
+ */
37
+ export const defaultEncryptionMaps: ModuleEncryptionMap[] = [
38
+ {
39
+ entityId: 'communication_channels:channel_ingest_dead_letter',
40
+ fields: [{ field: 'raw_body' }],
41
+ },
42
+ ]
43
+
44
+ export default defaultEncryptionMaps
@@ -0,0 +1,122 @@
1
+ import { createModuleEvents } from '@open-mercato/shared/modules/events'
2
+
3
+ const events = [
4
+ // ── Bridge events ────────────────────────────────────────
5
+ {
6
+ id: 'communication_channels.message.received',
7
+ label: 'External Message Received',
8
+ entity: 'external_message',
9
+ category: 'custom',
10
+ clientBroadcast: true,
11
+ },
12
+ {
13
+ id: 'communication_channels.message.sent',
14
+ label: 'External Message Sent (Outbound)',
15
+ entity: 'external_message',
16
+ category: 'custom',
17
+ clientBroadcast: true,
18
+ },
19
+ {
20
+ id: 'communication_channels.message.delivery_failed',
21
+ label: 'External Message Delivery Failed',
22
+ entity: 'external_message',
23
+ category: 'custom',
24
+ clientBroadcast: true,
25
+ },
26
+ {
27
+ id: 'communication_channels.conversation.created',
28
+ label: 'External Conversation Created',
29
+ entity: 'external_conversation',
30
+ category: 'custom',
31
+ },
32
+ {
33
+ id: 'communication_channels.conversation.reassigned',
34
+ label: 'External Conversation Reassigned',
35
+ entity: 'external_conversation',
36
+ category: 'custom',
37
+ },
38
+ {
39
+ id: 'communication_channels.contact.resolved',
40
+ label: 'External Contact Resolved to CRM Person',
41
+ entity: 'external_conversation',
42
+ category: 'custom',
43
+ },
44
+ // ── Channel lifecycle events ─────────────────────────────
45
+ {
46
+ id: 'communication_channels.channel.requires_reauth',
47
+ label: 'Channel Requires Re-authentication',
48
+ entity: 'communication_channel',
49
+ category: 'lifecycle',
50
+ clientBroadcast: true,
51
+ },
52
+ {
53
+ id: 'communication_channels.channel.disconnected',
54
+ label: 'Channel Disconnected',
55
+ entity: 'communication_channel',
56
+ category: 'lifecycle',
57
+ clientBroadcast: true,
58
+ },
59
+ {
60
+ id: 'communication_channels.channel.deleted',
61
+ label: 'Channel Deleted',
62
+ entity: 'communication_channel',
63
+ category: 'lifecycle',
64
+ clientBroadcast: true,
65
+ },
66
+ {
67
+ id: 'communication_channels.channel.primary_changed',
68
+ label: 'Primary Channel Changed',
69
+ entity: 'communication_channel',
70
+ category: 'lifecycle',
71
+ clientBroadcast: true,
72
+ },
73
+ // ── Reaction events ──────────────────────────────────────
74
+ {
75
+ id: 'communication_channels.reaction.added',
76
+ label: 'Reaction Added',
77
+ entity: 'message_reaction',
78
+ category: 'custom',
79
+ clientBroadcast: true,
80
+ },
81
+ {
82
+ id: 'communication_channels.reaction.removed',
83
+ label: 'Reaction Removed',
84
+ entity: 'message_reaction',
85
+ category: 'custom',
86
+ clientBroadcast: true,
87
+ },
88
+ // ── Push delivery lifecycle (Spec C) ─────────────────────
89
+ {
90
+ id: 'communication_channels.push.registered',
91
+ label: 'Push Delivery Registered',
92
+ entity: 'communication_channel',
93
+ category: 'lifecycle',
94
+ clientBroadcast: true,
95
+ },
96
+ {
97
+ id: 'communication_channels.push.failed',
98
+ label: 'Push Delivery Failed (Falling Back to Polling)',
99
+ entity: 'communication_channel',
100
+ category: 'lifecycle',
101
+ clientBroadcast: true,
102
+ },
103
+ {
104
+ id: 'communication_channels.push.renewed',
105
+ label: 'Push Delivery Renewed',
106
+ entity: 'communication_channel',
107
+ category: 'lifecycle',
108
+ },
109
+ {
110
+ id: 'communication_channels.push.deactivated',
111
+ label: 'Push Delivery Deactivated',
112
+ entity: 'communication_channel',
113
+ category: 'lifecycle',
114
+ clientBroadcast: true,
115
+ },
116
+ ] as const
117
+
118
+ export const eventsConfig = createModuleEvents({ moduleId: 'communication_channels', events })
119
+ export const emitCommunicationChannelsEvent = eventsConfig.emit
120
+ export type CommunicationChannelsEventId = (typeof events)[number]['id']
121
+
122
+ export default eventsConfig
@@ -0,0 +1,138 @@
1
+ {
2
+ "communication_channels.channel.providers.gmail": "Gmail",
3
+ "communication_channels.channel.providers.imap": "IMAP",
4
+ "communication_channels.channel.providers.slack": "Slack",
5
+ "communication_channels.channel.providers.whatsapp": "WhatsApp",
6
+ "communication_channels.channelPayload.aria": "Kanalinhalt",
7
+ "communication_channels.channelPayload.email.aria": "E-Mail-Inhalt",
8
+ "communication_channels.channelPayload.types.email/mime": "E-Mail (MIME)",
9
+ "communication_channels.columns.displayName": "Kanal",
10
+ "communication_channels.columns.identifier": "Externe ID",
11
+ "communication_channels.columns.provider": "Anbieter",
12
+ "communication_channels.columns.status": "Status",
13
+ "communication_channels.columns.type": "Typ",
14
+ "communication_channels.detail.capabilities": "Funktionen",
15
+ "communication_channels.detail.health": "Zustellungszustand (letzte 24 Std.)",
16
+ "communication_channels.detail.loading": "Kanal wird geladen...",
17
+ "communication_channels.detail.messages": "Nachrichten",
18
+ "communication_channels.detail.noCapabilities": "Für diesen Kanal wurde noch keine Funktionsübersicht erfasst.",
19
+ "communication_channels.detail.noHealth": "Keine Zustandsdaten verfügbar.",
20
+ "communication_channels.detail.notFound": "Kanal nicht gefunden",
21
+ "communication_channels.detail.recentFailures": "Letzte Fehler",
22
+ "communication_channels.detail.title": "Kanaldetails",
23
+ "communication_channels.emptyState": "Noch keine gemeinsamen Kanäle. Diese Seite listet gemeinsame, mandantenweite Kanäle auf. Ihr persönliches E-Mail-Postfach ist privat – verbinden und verwalten Sie es unter Profil → Kommunikationskanäle.",
24
+ "communication_channels.errors.loadDetail": "Kanal konnte nicht geladen werden",
25
+ "communication_channels.errors.loadList": "Kanäle konnten nicht geladen werden",
26
+ "communication_channels.errors.reactionFailed": "Reaktion fehlgeschlagen",
27
+ "communication_channels.errors.undoBlockedPrimaryConflict": "Ein anderer Kanal ist jetzt für diesen Benutzer als primär festgelegt. Setze ihn auf nicht-primär, bevor du den getrennten Kanal wieder als primär festlegst.",
28
+ "communication_channels.infoPanel.aria": "Kanalinfo",
29
+ "communication_channels.infoPanel.assignedTo": "Zugewiesen an",
30
+ "communication_channels.infoPanel.contactPerson": "CRM-Kontakt",
31
+ "communication_channels.infoPanel.direction": "Richtung",
32
+ "communication_channels.infoPanel.noThread": "Diese Nachricht gehört zu keinem Thread; Neuzuweisung nicht verfügbar.",
33
+ "communication_channels.infoPanel.provider": "Anbieter",
34
+ "communication_channels.infoPanel.reassignError": "Neuzuweisung fehlgeschlagen",
35
+ "communication_channels.infoPanel.reassignSuccess": "Konversation neu zugewiesen.",
36
+ "communication_channels.infoPanel.status": "Status",
37
+ "communication_channels.infoPanel.subject": "Betreff",
38
+ "communication_channels.infoPanel.title": "Kanalinfo",
39
+ "communication_channels.infoPanel.type": "Typ",
40
+ "communication_channels.infoPanel.unassigned": "Nicht zugewiesen",
41
+ "communication_channels.nav.group": "Integrationen",
42
+ "communication_channels.nav.title": "Kommunikationskanäle",
43
+ "communication_channels.notifications.channel_requires_reauth.body": "Authentifizierung abgelaufen. Verbinden Sie diesen Kanal erneut, um das Senden und Empfangen von Nachrichten fortzusetzen.",
44
+ "communication_channels.notifications.channel_requires_reauth.reconnect": "Erneut verbinden",
45
+ "communication_channels.notifications.channel_requires_reauth.title": "Kanal muss erneut verbunden werden",
46
+ "communication_channels.notifications.channel_requires_reauth.unknownChannel": "Ein Kanal",
47
+ "communication_channels.notifications.message_received.body": "Sie haben eine neue Nachricht über {{providerKey}} erhalten.",
48
+ "communication_channels.notifications.message_received.title": "Neue externe Nachricht",
49
+ "communication_channels.notifications.message_received.unknownSender": "Unbekannter Absender",
50
+ "communication_channels.profile.actions.disconnect": "Trennen",
51
+ "communication_channels.profile.actions.disconnectFailed": "Kanal konnte nicht getrennt werden",
52
+ "communication_channels.profile.actions.disconnectSuccess": "Kanal getrennt. Sie können ihn jederzeit erneut verbinden.",
53
+ "communication_channels.profile.actions.importHistory": "Verlauf importieren",
54
+ "communication_channels.profile.actions.pollNow": "Jetzt abrufen",
55
+ "communication_channels.profile.actions.pollNowFailed": "Abruf konnte nicht ausgelöst werden",
56
+ "communication_channels.profile.actions.pollNowSuccess": "Abruf ausgelöst — neue Nachrichten erscheinen in wenigen Sekunden auf den verknüpften Personen-Zeitleisten.",
57
+ "communication_channels.profile.actions.retryPoll": "Wiederholen",
58
+ "communication_channels.profile.actions.setPrimary": "Als primär festlegen",
59
+ "communication_channels.profile.actions.setPrimaryFailed": "Festlegen als primär fehlgeschlagen",
60
+ "communication_channels.profile.actions.setPrimarySuccess": "Als primär markiert.",
61
+ "communication_channels.profile.alerts.requiresReauth": "{count} Kanäle müssen erneut verbunden werden. Klicken Sie unten beim betroffenen Kanal auf \"Erneut verbinden\".",
62
+ "communication_channels.profile.columns.disconnect": "Verbindung",
63
+ "communication_channels.profile.columns.importHistory": "Verlauf",
64
+ "communication_channels.profile.columns.lastPolled": "Zuletzt synchronisiert",
65
+ "communication_channels.profile.columns.pollNow": "Synchronisieren",
66
+ "communication_channels.profile.columns.primary": "Primär",
67
+ "communication_channels.profile.connect.blocked": "Verbindung durch Validierung blockiert",
68
+ "communication_channels.profile.connect.cancel": "Abbrechen",
69
+ "communication_channels.profile.connect.connected": "Kanal verbunden.",
70
+ "communication_channels.profile.connect.connecting": "Wird verbunden...",
71
+ "communication_channels.profile.connect.credentialsFailed": "Postfach konnte nicht verbunden werden.",
72
+ "communication_channels.profile.connect.fields.displayName": "Anzeigename",
73
+ "communication_channels.profile.connect.fields.fromAddress": "Absenderadresse",
74
+ "communication_channels.profile.connect.fields.imapHost": "IMAP-Host",
75
+ "communication_channels.profile.connect.fields.imapPassword": "IMAP-Passwort",
76
+ "communication_channels.profile.connect.fields.imapPort": "IMAP-Port",
77
+ "communication_channels.profile.connect.fields.imapTls": "IMAP-Sicherheit",
78
+ "communication_channels.profile.connect.fields.imapUser": "IMAP-Benutzername",
79
+ "communication_channels.profile.connect.fields.smtpHost": "SMTP-Host",
80
+ "communication_channels.profile.connect.fields.smtpPassword": "SMTP-Passwort",
81
+ "communication_channels.profile.connect.fields.smtpPort": "SMTP-Port",
82
+ "communication_channels.profile.connect.fields.smtpTls": "SMTP-Sicherheit",
83
+ "communication_channels.profile.connect.fields.smtpUser": "SMTP-Benutzername",
84
+ "communication_channels.profile.connect.gmail": "Gmail verbinden",
85
+ "communication_channels.profile.connect.imap": "IMAP verbinden",
86
+ "communication_channels.profile.connect.imapTitle": "IMAP-Postfach verbinden",
87
+ "communication_channels.profile.connect.mailboxAlreadyConnected": "Dieses Postfach ist bereits über einen anderen Anbieter verbunden. Trennen Sie es zuerst, um es mit einem anderen Anbieter erneut zu verbinden.",
88
+ "communication_channels.profile.connect.notConfigured": "Dieser Anbieter ist noch nicht konfiguriert. Bitten Sie einen Administrator, die OAuth-Client-ID und das Secret unter Integrationen zu hinterlegen, bevor ein Postfach verbunden wird.",
89
+ "communication_channels.profile.connect.oauthFailed": "OAuth-Verbindung konnte nicht gestartet werden.",
90
+ "communication_channels.profile.connect.save": "Verbinden",
91
+ "communication_channels.profile.connect.tls.none": "Keine",
92
+ "communication_channels.profile.connect.tls.starttls": "STARTTLS",
93
+ "communication_channels.profile.connect.tls.tls": "TLS",
94
+ "communication_channels.profile.disconnect.cancel": "Abbrechen",
95
+ "communication_channels.profile.disconnect.confirm": "Trennen",
96
+ "communication_channels.profile.disconnect.description": "Dies entfernt die Verbindung und stoppt die Synchronisierung. Bereits importierte E-Mails bleiben in Ihren Timelines. Sie können den Kanal jederzeit erneut verbinden.",
97
+ "communication_channels.profile.disconnect.submitting": "Wird getrennt…",
98
+ "communication_channels.profile.disconnect.title": "Kanal trennen",
99
+ "communication_channels.profile.empty": "Sie haben noch keine verbundenen Kanäle. Verwenden Sie oben den Eintrag \"Kanal verbinden\", um Gmail oder IMAP hinzuzufügen.",
100
+ "communication_channels.profile.flash.connected": "Kanal verbunden.",
101
+ "communication_channels.profile.flash.connectedWithProvider": "Kanal verbunden ({provider}).",
102
+ "communication_channels.profile.flash.error": "Kanal konnte nicht verbunden werden.",
103
+ "communication_channels.profile.flash.errorWithCode": "Kanal konnte nicht verbunden werden — {code}.",
104
+ "communication_channels.profile.group": "Profil",
105
+ "communication_channels.profile.importHistory.cancel": "Abbrechen",
106
+ "communication_channels.profile.importHistory.description": "Ältere Nachrichten abrufen, die dieser Kanal beim Verbinden noch nicht gesehen hat. Filter schränken die Suche serverseitig ein.",
107
+ "communication_channels.profile.importHistory.errors.contactEmails": "Mindestens ein Eintrag ist keine gültige E-Mail-Adresse.",
108
+ "communication_channels.profile.importHistory.errors.maxMessages": "Wählen Sie eine Zahl zwischen 1 und 5000 Nachrichten.",
109
+ "communication_channels.profile.importHistory.errors.sinceDays": "Wählen Sie eine Zahl zwischen 1 und 365 Tagen.",
110
+ "communication_channels.profile.importHistory.fields.contactEmails": "Nach Absender filtern (optional)",
111
+ "communication_channels.profile.importHistory.fields.contactEmailsHint": "Leer lassen, um alle Absender im Zeitraum zu scannen.",
112
+ "communication_channels.profile.importHistory.fields.contactEmailsPlaceholder": "alice@example.com, bob@example.com",
113
+ "communication_channels.profile.importHistory.fields.maxMessages": "Maximale Nachrichten",
114
+ "communication_channels.profile.importHistory.fields.sinceDays": "Zurückblicken (Tage)",
115
+ "communication_channels.profile.importHistory.flash.error": "Verlaufsimport konnte nicht in die Warteschlange gestellt werden.",
116
+ "communication_channels.profile.importHistory.flash.success": "Verlaufsimport in der Warteschlange — Fortschritt oben verfolgen.",
117
+ "communication_channels.profile.importHistory.submit": "Import starten",
118
+ "communication_channels.profile.importHistory.submitting": "Wird eingereiht…",
119
+ "communication_channels.profile.importHistory.title": "Kanalverlauf importieren",
120
+ "communication_channels.profile.primary": "Primär",
121
+ "communication_channels.profile.subtitle": "Verbinden Sie Ihr persönliches Postfach, damit ausgehende Nachrichten von Ihrer Adresse stammen und eingehende E-Mails in Ihrem einheitlichen Posteingang landen.",
122
+ "communication_channels.profile.tableTitle": "Ihre Kanäle",
123
+ "communication_channels.profile.title": "Meine Kommunikationskanäle",
124
+ "communication_channels.push.button.reregister": "Push neu registrieren",
125
+ "communication_channels.push.flash.registerFailed": "Push-Registrierung fehlgeschlagen",
126
+ "communication_channels.push.status.active": "Push aktiv",
127
+ "communication_channels.push.status.failed": "Push fehlgeschlagen — nutze Polling",
128
+ "communication_channels.push.status.inactive": "Nur Polling",
129
+ "communication_channels.reaction.bar.aria": "Reaktionen",
130
+ "communication_channels.reaction.cannotRemoveExternal": "Reaktionen externer Teilnehmer können nur in der Anbieter-App entfernt werden.",
131
+ "communication_channels.reaction.toggleAria": "Reaktion {emoji} umschalten",
132
+ "communication_channels.status.active": "Aktiv",
133
+ "communication_channels.status.connected": "Verbunden",
134
+ "communication_channels.status.disconnected": "Getrennt",
135
+ "communication_channels.status.error": "Fehler",
136
+ "communication_channels.status.inactive": "Inaktiv",
137
+ "communication_channels.status.requiresReauth": "Erneutes Verbinden erforderlich"
138
+ }
@@ -0,0 +1,138 @@
1
+ {
2
+ "communication_channels.channel.providers.gmail": "Gmail",
3
+ "communication_channels.channel.providers.imap": "IMAP",
4
+ "communication_channels.channel.providers.slack": "Slack",
5
+ "communication_channels.channel.providers.whatsapp": "WhatsApp",
6
+ "communication_channels.channelPayload.aria": "Channel payload",
7
+ "communication_channels.channelPayload.email.aria": "Email payload",
8
+ "communication_channels.channelPayload.types.email/mime": "Email (MIME)",
9
+ "communication_channels.columns.displayName": "Channel",
10
+ "communication_channels.columns.identifier": "External ID",
11
+ "communication_channels.columns.provider": "Provider",
12
+ "communication_channels.columns.status": "Status",
13
+ "communication_channels.columns.type": "Type",
14
+ "communication_channels.detail.capabilities": "Capabilities",
15
+ "communication_channels.detail.health": "Delivery health (last 24h)",
16
+ "communication_channels.detail.loading": "Loading channel...",
17
+ "communication_channels.detail.messages": "messages",
18
+ "communication_channels.detail.noCapabilities": "No capabilities snapshot recorded for this channel yet.",
19
+ "communication_channels.detail.noHealth": "No health data available.",
20
+ "communication_channels.detail.notFound": "Channel not found",
21
+ "communication_channels.detail.recentFailures": "Recent failures",
22
+ "communication_channels.detail.title": "Channel detail",
23
+ "communication_channels.emptyState": "No shared channels yet. This page lists shared, tenant-wide channels. Your personal email mailbox is private — connect and manage it under Profile → Communication Channels.",
24
+ "communication_channels.errors.loadDetail": "Failed to load channel",
25
+ "communication_channels.errors.loadList": "Failed to load channels",
26
+ "communication_channels.errors.reactionFailed": "Reaction failed",
27
+ "communication_channels.errors.undoBlockedPrimaryConflict": "Another channel is now primary for this user. Set it as non-primary before restoring the disconnected channel as primary.",
28
+ "communication_channels.infoPanel.aria": "Channel info",
29
+ "communication_channels.infoPanel.assignedTo": "Assigned to",
30
+ "communication_channels.infoPanel.contactPerson": "CRM contact",
31
+ "communication_channels.infoPanel.direction": "Direction",
32
+ "communication_channels.infoPanel.noThread": "This message is not on a thread; reassignment unavailable.",
33
+ "communication_channels.infoPanel.provider": "Provider",
34
+ "communication_channels.infoPanel.reassignError": "Reassignment failed",
35
+ "communication_channels.infoPanel.reassignSuccess": "Conversation reassigned.",
36
+ "communication_channels.infoPanel.status": "Status",
37
+ "communication_channels.infoPanel.subject": "Subject",
38
+ "communication_channels.infoPanel.title": "Channel info",
39
+ "communication_channels.infoPanel.type": "Type",
40
+ "communication_channels.infoPanel.unassigned": "Unassigned",
41
+ "communication_channels.nav.group": "Integrations",
42
+ "communication_channels.nav.title": "Communication Channels",
43
+ "communication_channels.notifications.channel_requires_reauth.body": "Authentication expired. Reconnect this channel to resume sending and receiving messages.",
44
+ "communication_channels.notifications.channel_requires_reauth.reconnect": "Reconnect",
45
+ "communication_channels.notifications.channel_requires_reauth.title": "Channel needs reconnection",
46
+ "communication_channels.notifications.channel_requires_reauth.unknownChannel": "A channel",
47
+ "communication_channels.notifications.message_received.body": "You received a new message via {{providerKey}}.",
48
+ "communication_channels.notifications.message_received.title": "New external message",
49
+ "communication_channels.notifications.message_received.unknownSender": "Unknown sender",
50
+ "communication_channels.profile.actions.disconnect": "Disconnect",
51
+ "communication_channels.profile.actions.disconnectFailed": "Failed to disconnect channel",
52
+ "communication_channels.profile.actions.disconnectSuccess": "Channel disconnected. You can reconnect it anytime.",
53
+ "communication_channels.profile.actions.importHistory": "Import history",
54
+ "communication_channels.profile.actions.pollNow": "Poll now",
55
+ "communication_channels.profile.actions.pollNowFailed": "Failed to trigger poll",
56
+ "communication_channels.profile.actions.pollNowSuccess": "Poll triggered — new messages will appear on linked Person timelines in a few seconds.",
57
+ "communication_channels.profile.actions.retryPoll": "Retry",
58
+ "communication_channels.profile.actions.setPrimary": "Set as primary",
59
+ "communication_channels.profile.actions.setPrimaryFailed": "Failed to set as primary",
60
+ "communication_channels.profile.actions.setPrimarySuccess": "Marked as primary.",
61
+ "communication_channels.profile.alerts.requiresReauth": "{count} channel(s) need reconnection. Click \"Reconnect\" on the affected channel below.",
62
+ "communication_channels.profile.columns.disconnect": "Connection",
63
+ "communication_channels.profile.columns.importHistory": "History",
64
+ "communication_channels.profile.columns.lastPolled": "Last synced",
65
+ "communication_channels.profile.columns.pollNow": "Sync",
66
+ "communication_channels.profile.columns.primary": "Primary",
67
+ "communication_channels.profile.connect.blocked": "Connection blocked by validation",
68
+ "communication_channels.profile.connect.cancel": "Cancel",
69
+ "communication_channels.profile.connect.connected": "Channel connected.",
70
+ "communication_channels.profile.connect.connecting": "Connecting...",
71
+ "communication_channels.profile.connect.credentialsFailed": "Could not connect mailbox.",
72
+ "communication_channels.profile.connect.fields.displayName": "Display name",
73
+ "communication_channels.profile.connect.fields.fromAddress": "From address",
74
+ "communication_channels.profile.connect.fields.imapHost": "IMAP host",
75
+ "communication_channels.profile.connect.fields.imapPassword": "IMAP password",
76
+ "communication_channels.profile.connect.fields.imapPort": "IMAP port",
77
+ "communication_channels.profile.connect.fields.imapTls": "IMAP security",
78
+ "communication_channels.profile.connect.fields.imapUser": "IMAP username",
79
+ "communication_channels.profile.connect.fields.smtpHost": "SMTP host",
80
+ "communication_channels.profile.connect.fields.smtpPassword": "SMTP password",
81
+ "communication_channels.profile.connect.fields.smtpPort": "SMTP port",
82
+ "communication_channels.profile.connect.fields.smtpTls": "SMTP security",
83
+ "communication_channels.profile.connect.fields.smtpUser": "SMTP username",
84
+ "communication_channels.profile.connect.gmail": "Connect Gmail",
85
+ "communication_channels.profile.connect.imap": "Connect IMAP",
86
+ "communication_channels.profile.connect.imapTitle": "Connect IMAP mailbox",
87
+ "communication_channels.profile.connect.mailboxAlreadyConnected": "This mailbox is already connected through another provider. Disconnect it first to reconnect it with a different one.",
88
+ "communication_channels.profile.connect.notConfigured": "This provider is not configured yet. Ask an administrator to add the OAuth Client ID and Secret under Integrations before connecting a mailbox.",
89
+ "communication_channels.profile.connect.oauthFailed": "Could not start OAuth connection.",
90
+ "communication_channels.profile.connect.save": "Connect",
91
+ "communication_channels.profile.connect.tls.none": "None",
92
+ "communication_channels.profile.connect.tls.starttls": "STARTTLS",
93
+ "communication_channels.profile.connect.tls.tls": "TLS",
94
+ "communication_channels.profile.disconnect.cancel": "Cancel",
95
+ "communication_channels.profile.disconnect.confirm": "Disconnect",
96
+ "communication_channels.profile.disconnect.description": "This removes the connection and stops syncing. Emails already imported stay on your timelines. You can reconnect anytime.",
97
+ "communication_channels.profile.disconnect.submitting": "Disconnecting…",
98
+ "communication_channels.profile.disconnect.title": "Disconnect channel",
99
+ "communication_channels.profile.empty": "You have no connected channels yet. Use the \"Connect channel\" entry above to add Gmail or IMAP.",
100
+ "communication_channels.profile.flash.connected": "Channel connected.",
101
+ "communication_channels.profile.flash.connectedWithProvider": "Channel connected ({provider}).",
102
+ "communication_channels.profile.flash.error": "Failed to connect channel.",
103
+ "communication_channels.profile.flash.errorWithCode": "Failed to connect channel — {code}.",
104
+ "communication_channels.profile.group": "Profile",
105
+ "communication_channels.profile.importHistory.cancel": "Cancel",
106
+ "communication_channels.profile.importHistory.description": "Pull older messages this channel never observed at connect-time. Filters narrow the search server-side.",
107
+ "communication_channels.profile.importHistory.errors.contactEmails": "One or more entries is not a valid email address.",
108
+ "communication_channels.profile.importHistory.errors.maxMessages": "Choose a number between 1 and 5000 messages.",
109
+ "communication_channels.profile.importHistory.errors.sinceDays": "Choose a number between 1 and 365 days.",
110
+ "communication_channels.profile.importHistory.fields.contactEmails": "Filter by sender (optional)",
111
+ "communication_channels.profile.importHistory.fields.contactEmailsHint": "Leave empty to scan all senders in the window.",
112
+ "communication_channels.profile.importHistory.fields.contactEmailsPlaceholder": "alice@example.com, bob@example.com",
113
+ "communication_channels.profile.importHistory.fields.maxMessages": "Maximum messages",
114
+ "communication_channels.profile.importHistory.fields.sinceDays": "Look back (days)",
115
+ "communication_channels.profile.importHistory.flash.error": "Failed to queue history import.",
116
+ "communication_channels.profile.importHistory.flash.success": "History import queued — track progress in the top bar.",
117
+ "communication_channels.profile.importHistory.submit": "Start import",
118
+ "communication_channels.profile.importHistory.submitting": "Queueing…",
119
+ "communication_channels.profile.importHistory.title": "Import channel history",
120
+ "communication_channels.profile.primary": "Primary",
121
+ "communication_channels.profile.subtitle": "Connect your personal mailbox so outbound messages come from your address and inbound emails land in your unified inbox.",
122
+ "communication_channels.profile.tableTitle": "Your channels",
123
+ "communication_channels.profile.title": "My communication channels",
124
+ "communication_channels.push.button.reregister": "Re-register push",
125
+ "communication_channels.push.flash.registerFailed": "Failed to register push",
126
+ "communication_channels.push.status.active": "Push active",
127
+ "communication_channels.push.status.failed": "Push failed — using polling",
128
+ "communication_channels.push.status.inactive": "Polling only",
129
+ "communication_channels.reaction.bar.aria": "Reactions",
130
+ "communication_channels.reaction.cannotRemoveExternal": "Reactions from external participants can only be removed in the provider app.",
131
+ "communication_channels.reaction.toggleAria": "Toggle {emoji} reaction",
132
+ "communication_channels.status.active": "Active",
133
+ "communication_channels.status.connected": "Connected",
134
+ "communication_channels.status.disconnected": "Disconnected",
135
+ "communication_channels.status.error": "Error",
136
+ "communication_channels.status.inactive": "Inactive",
137
+ "communication_channels.status.requiresReauth": "Needs reconnection"
138
+ }