@open-mercato/core 0.7.0 → 0.7.1-develop.7102.1.b41f7e3e51

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 (847) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/helpers/integration/api.js +13 -1
  3. package/dist/helpers/integration/api.js.map +2 -2
  4. package/dist/helpers/integration/communicationChannelsFixtures.js +19 -0
  5. package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
  6. package/dist/modules/api_keys/api/keys/route.js +1 -1
  7. package/dist/modules/api_keys/api/keys/route.js.map +2 -2
  8. package/dist/modules/api_keys/backend/api-keys/page.js +3 -1
  9. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  10. package/dist/modules/api_keys/di.js +9 -0
  11. package/dist/modules/api_keys/di.js.map +7 -0
  12. package/dist/modules/api_keys/services/principalService.js +31 -0
  13. package/dist/modules/api_keys/services/principalService.js.map +7 -0
  14. package/dist/modules/attachments/api/route.js +2 -2
  15. package/dist/modules/attachments/api/route.js.map +2 -2
  16. package/dist/modules/attachments/components/AttachmentLibrary.js +2 -0
  17. package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
  18. package/dist/modules/attachments/di.js +11 -1
  19. package/dist/modules/attachments/di.js.map +2 -2
  20. package/dist/modules/attachments/index.js.map +1 -1
  21. package/dist/modules/attachments/lib/attachment-service.js +313 -0
  22. package/dist/modules/attachments/lib/attachment-service.js.map +7 -0
  23. package/dist/modules/attachments/lib/scoped-upload-service.js +15 -2
  24. package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
  25. package/dist/modules/attachments/lib/upload-limits.js +6 -2
  26. package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
  27. package/dist/modules/audit_logs/backend/audit-logs/page.js +6 -0
  28. package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
  29. package/dist/modules/audit_logs/lib/display-helpers.js +19 -11
  30. package/dist/modules/audit_logs/lib/display-helpers.js.map +2 -2
  31. package/dist/modules/audit_logs/services/actionLogService.js +57 -12
  32. package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
  33. package/dist/modules/auth/acl.js +30 -5
  34. package/dist/modules/auth/acl.js.map +2 -2
  35. package/dist/modules/auth/api/feature-check.js +8 -2
  36. package/dist/modules/auth/api/feature-check.js.map +2 -2
  37. package/dist/modules/auth/api/login.js +4 -1
  38. package/dist/modules/auth/api/login.js.map +2 -2
  39. package/dist/modules/auth/api/reset/validate.js +55 -0
  40. package/dist/modules/auth/api/reset/validate.js.map +7 -0
  41. package/dist/modules/auth/api/roles/acl/route.js +28 -33
  42. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  43. package/dist/modules/auth/api/session/refresh.js +25 -1
  44. package/dist/modules/auth/api/session/refresh.js.map +2 -2
  45. package/dist/modules/auth/api/users/acl/route.js +96 -51
  46. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  47. package/dist/modules/auth/api/users/route.js +13 -5
  48. package/dist/modules/auth/api/users/route.js.map +2 -2
  49. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js +5 -1
  50. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js.map +2 -2
  51. package/dist/modules/auth/backend/roles/page.js +3 -1
  52. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  53. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js +5 -1
  54. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js.map +2 -2
  55. package/dist/modules/auth/backend/users/page.js +2 -1
  56. package/dist/modules/auth/backend/users/page.js.map +2 -2
  57. package/dist/modules/auth/commands/acl.js +254 -0
  58. package/dist/modules/auth/commands/acl.js.map +7 -0
  59. package/dist/modules/auth/components/AclEditor.js +39 -30
  60. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  61. package/dist/modules/auth/data/entities.js.map +2 -2
  62. package/dist/modules/auth/data/validators.js +5 -1
  63. package/dist/modules/auth/data/validators.js.map +2 -2
  64. package/dist/modules/auth/di.js +35 -9
  65. package/dist/modules/auth/di.js.map +2 -2
  66. package/dist/modules/auth/frontend/reset/[token]/page.js +46 -0
  67. package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
  68. package/dist/modules/auth/lib/grantChecks.js.map +2 -2
  69. package/dist/modules/auth/lib/userIdFilter.js +16 -0
  70. package/dist/modules/auth/lib/userIdFilter.js.map +7 -0
  71. package/dist/modules/auth/services/authService.js +16 -2
  72. package/dist/modules/auth/services/authService.js.map +2 -2
  73. package/dist/modules/auth/services/principalService.js +200 -0
  74. package/dist/modules/auth/services/principalService.js.map +7 -0
  75. package/dist/modules/auth/services/rbacService.js +67 -24
  76. package/dist/modules/auth/services/rbacService.js.map +3 -3
  77. package/dist/modules/auth/services/roleOrganizationScope.js +41 -0
  78. package/dist/modules/auth/services/roleOrganizationScope.js.map +7 -0
  79. package/dist/modules/business_rules/backend/logs/page.js +3 -1
  80. package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
  81. package/dist/modules/business_rules/backend/rules/page.js +3 -1
  82. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  83. package/dist/modules/business_rules/backend/sets/page.js +3 -1
  84. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  85. package/dist/modules/business_rules/lib/expression-evaluator.js +9 -9
  86. package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
  87. package/dist/modules/business_rules/lib/rule-evaluator.js +10 -9
  88. package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
  89. package/dist/modules/catalog/ai-agents.js +1 -1
  90. package/dist/modules/catalog/ai-agents.js.map +1 -1
  91. package/dist/modules/catalog/ai-tools/merchandising-pack.js +2 -2
  92. package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
  93. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +5 -2
  94. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
  95. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -0
  96. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  97. package/dist/modules/catalog/components/products/ProductsDataTable.js +7 -1
  98. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  99. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js +2 -0
  100. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js.map +2 -2
  101. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +9 -1
  102. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +2 -2
  103. package/dist/modules/communication_channels/api/post/test-seed/route.js +95 -10
  104. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  105. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +3 -0
  106. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
  107. package/dist/modules/communication_channels/commands/ingest-inbound-message.js +14 -1
  108. package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
  109. package/dist/modules/communication_channels/di.js +7 -1
  110. package/dist/modules/communication_channels/di.js.map +2 -2
  111. package/dist/modules/communication_channels/lib/email-capabilities.js +4 -1
  112. package/dist/modules/communication_channels/lib/email-capabilities.js.map +2 -2
  113. package/dist/modules/communication_channels/lib/outbound-recipient.js +33 -0
  114. package/dist/modules/communication_channels/lib/outbound-recipient.js.map +7 -0
  115. package/dist/modules/communication_channels/lib/resolve-channel-type.js +51 -0
  116. package/dist/modules/communication_channels/lib/resolve-channel-type.js.map +7 -0
  117. package/dist/modules/communication_channels/lib/test-seed.js +41 -2
  118. package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
  119. package/dist/modules/configs/lib/system-status.js +9 -0
  120. package/dist/modules/configs/lib/system-status.js.map +2 -2
  121. package/dist/modules/currencies/backend/currencies/page.js +3 -1
  122. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  123. package/dist/modules/currencies/backend/exchange-rates/page.js +3 -1
  124. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  125. package/dist/modules/currencies/services/rateFetchingService.js +6 -1
  126. package/dist/modules/currencies/services/rateFetchingService.js.map +2 -2
  127. package/dist/modules/customer_accounts/api/admin/domain-mappings.js +9 -0
  128. package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +2 -2
  129. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +3 -1
  130. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  131. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +3 -1
  132. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +2 -2
  133. package/dist/modules/customer_accounts/services/domainMappingService.js +10 -0
  134. package/dist/modules/customer_accounts/services/domainMappingService.js.map +2 -2
  135. package/dist/modules/customers/ai-tools/companies-pack.js +4 -1
  136. package/dist/modules/customers/ai-tools/companies-pack.js.map +2 -2
  137. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +13 -2
  138. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +2 -2
  139. package/dist/modules/customers/ai-tools/deals-pack.js +52 -6
  140. package/dist/modules/customers/ai-tools/deals-pack.js.map +2 -2
  141. package/dist/modules/customers/ai-tools/people-pack.js +4 -1
  142. package/dist/modules/customers/ai-tools/people-pack.js.map +2 -2
  143. package/dist/modules/customers/api/activities/route.js +48 -6
  144. package/dist/modules/customers/api/activities/route.js.map +2 -2
  145. package/dist/modules/customers/api/companies/[id]/people/route.js +20 -64
  146. package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
  147. package/dist/modules/customers/api/companies/[id]/route.js +17 -94
  148. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  149. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +8 -5
  150. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
  151. package/dist/modules/customers/api/deals/[id]/companies/route.js +1 -1
  152. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
  153. package/dist/modules/customers/api/deals/[id]/people/route.js +1 -1
  154. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  155. package/dist/modules/customers/api/deals/[id]/route.js +8 -25
  156. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  157. package/dist/modules/customers/api/deals/[id]/stats/route.js +3 -22
  158. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +2 -2
  159. package/dist/modules/customers/api/deals/aggregate/route.js +11 -4
  160. package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
  161. package/dist/modules/customers/api/deals/map/route.js +2 -1
  162. package/dist/modules/customers/api/deals/map/route.js.map +2 -2
  163. package/dist/modules/customers/api/deals/route.js +38 -1
  164. package/dist/modules/customers/api/deals/route.js.map +2 -2
  165. package/dist/modules/customers/api/entity-roles-factory.js +4 -4
  166. package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
  167. package/dist/modules/customers/api/interactions/route.js +3 -1
  168. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  169. package/dist/modules/customers/api/interactions/tasks/route.js +27 -4
  170. package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
  171. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +4 -3
  172. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
  173. package/dist/modules/customers/api/people/[id]/companies/context.js +1 -1
  174. package/dist/modules/customers/api/people/[id]/companies/context.js.map +2 -2
  175. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +1 -1
  176. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
  177. package/dist/modules/customers/api/people/[id]/route.js +11 -10
  178. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  179. package/dist/modules/customers/api/people/check-phone/route.js +51 -9
  180. package/dist/modules/customers/api/people/check-phone/route.js.map +2 -2
  181. package/dist/modules/customers/api/todos/route.js +30 -5
  182. package/dist/modules/customers/api/todos/route.js.map +2 -2
  183. package/dist/modules/customers/backend/customers/companies/page.js +4 -2
  184. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  185. package/dist/modules/customers/backend/customers/deals/[id]/page.js +6 -1
  186. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  187. package/dist/modules/customers/backend/customers/deals/page.js +5 -2
  188. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  189. package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js +4 -13
  190. package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js.map +2 -2
  191. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js +85 -14
  192. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js.map +2 -2
  193. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js +18 -0
  194. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js.map +7 -0
  195. package/dist/modules/customers/backend/customers/people/page.js +4 -2
  196. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  197. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js +9 -3
  198. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js.map +2 -2
  199. package/dist/modules/customers/commands/deals.js +21 -34
  200. package/dist/modules/customers/commands/deals.js.map +2 -2
  201. package/dist/modules/customers/commands/interactions.js.map +1 -1
  202. package/dist/modules/customers/commands/personCompanyLinks.js +131 -2
  203. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  204. package/dist/modules/customers/components/CustomerTodosTable.js +1 -0
  205. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  206. package/dist/modules/customers/components/DealsKpiStrip.js +7 -6
  207. package/dist/modules/customers/components/DealsKpiStrip.js.map +2 -2
  208. package/dist/modules/customers/components/calendar/AgendaList.js +2 -2
  209. package/dist/modules/customers/components/calendar/AgendaList.js.map +2 -2
  210. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -1
  211. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
  212. package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
  213. package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
  214. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +1 -1
  215. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
  216. package/dist/modules/customers/components/calendar/EventBlock.js +1 -1
  217. package/dist/modules/customers/components/calendar/EventBlock.js.map +2 -2
  218. package/dist/modules/customers/components/calendar/EventPeekPopover.js +3 -2
  219. package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +2 -2
  220. package/dist/modules/customers/components/calendar/editor/PeopleField.js +40 -5
  221. package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
  222. package/dist/modules/customers/components/calendar/editor/hooks.js +2 -1
  223. package/dist/modules/customers/components/calendar/editor/hooks.js.map +2 -2
  224. package/dist/modules/customers/components/calendar/types.js +1 -1
  225. package/dist/modules/customers/components/calendar/types.js.map +2 -2
  226. package/dist/modules/customers/components/detail/CompanyKpiBar.js +5 -4
  227. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
  228. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +3 -1
  229. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  230. package/dist/modules/customers/components/detail/DealForm.js +19 -7
  231. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  232. package/dist/modules/customers/components/detail/DealsSection.js +6 -5
  233. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  234. package/dist/modules/customers/components/detail/EntityTagsDialog.js +35 -11
  235. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  236. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +3 -1
  237. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
  238. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +19 -13
  239. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
  240. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +4 -4
  241. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
  242. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +3 -3
  243. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  244. package/dist/modules/customers/components/detail/utils.js +5 -5
  245. package/dist/modules/customers/components/detail/utils.js.map +2 -2
  246. package/dist/modules/customers/data/entities.js.map +1 -1
  247. package/dist/modules/customers/data/validators.js +32 -3
  248. package/dist/modules/customers/data/validators.js.map +2 -2
  249. package/dist/modules/customers/events.js +5 -0
  250. package/dist/modules/customers/events.js.map +2 -2
  251. package/dist/modules/customers/lib/calendar/conflicts.js +8 -2
  252. package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
  253. package/dist/modules/customers/lib/calendar/editorPayload.js +3 -2
  254. package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
  255. package/dist/modules/customers/lib/calendar/mapItem.js +8 -3
  256. package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
  257. package/dist/modules/customers/lib/calendar/participantIdentity.js +9 -0
  258. package/dist/modules/customers/lib/calendar/participantIdentity.js.map +7 -0
  259. package/dist/modules/customers/lib/closureStage.js +45 -0
  260. package/dist/modules/customers/lib/closureStage.js.map +7 -0
  261. package/dist/modules/customers/lib/dealStatus.js +30 -0
  262. package/dist/modules/customers/lib/dealStatus.js.map +2 -2
  263. package/dist/modules/customers/lib/detailReadAccess.js +12 -0
  264. package/dist/modules/customers/lib/detailReadAccess.js.map +7 -0
  265. package/dist/modules/customers/lib/findPeopleByAddresses.js +1 -0
  266. package/dist/modules/customers/lib/findPeopleByAddresses.js.map +2 -2
  267. package/dist/modules/customers/lib/personCompanies.js +100 -2
  268. package/dist/modules/customers/lib/personCompanies.js.map +2 -2
  269. package/dist/modules/customers/lib/todoCompatibility.js +12 -0
  270. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  271. package/dist/modules/dashboards/lib/widgetScope.js +6 -1
  272. package/dist/modules/dashboards/lib/widgetScope.js.map +2 -2
  273. package/dist/modules/data_sync/backend/data-sync/page.js +3 -1
  274. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  275. package/dist/modules/data_sync/lib/abandoned-run.js +19 -0
  276. package/dist/modules/data_sync/lib/abandoned-run.js.map +7 -0
  277. package/dist/modules/data_sync/lib/sync-engine.js +72 -6
  278. package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
  279. package/dist/modules/data_sync/workers/sync-export.js +5 -1
  280. package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
  281. package/dist/modules/data_sync/workers/sync-import.js +5 -1
  282. package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
  283. package/dist/modules/devices/acl.js +9 -1
  284. package/dist/modules/devices/acl.js.map +2 -2
  285. package/dist/modules/devices/api/admin/devices/[id]/route.js +5 -32
  286. package/dist/modules/devices/api/admin/devices/[id]/route.js.map +2 -2
  287. package/dist/modules/devices/api/admin/devices/route.js +14 -1
  288. package/dist/modules/devices/api/admin/devices/route.js.map +2 -2
  289. package/dist/modules/devices/api/deviceList.js +99 -12
  290. package/dist/modules/devices/api/deviceList.js.map +2 -2
  291. package/dist/modules/devices/api/deviceSerialization.js +46 -0
  292. package/dist/modules/devices/api/deviceSerialization.js.map +7 -0
  293. package/dist/modules/devices/api/openapi.js +3 -1
  294. package/dist/modules/devices/api/openapi.js.map +2 -2
  295. package/dist/modules/devices/api/route.js +9 -1
  296. package/dist/modules/devices/api/route.js.map +2 -2
  297. package/dist/modules/devices/backend/devices/[id]/page.js +10 -26
  298. package/dist/modules/devices/backend/devices/[id]/page.js.map +2 -2
  299. package/dist/modules/devices/backend/devices/create/page.js +17 -1
  300. package/dist/modules/devices/backend/devices/create/page.js.map +2 -2
  301. package/dist/modules/devices/backend/devices/page.js +28 -34
  302. package/dist/modules/devices/backend/devices/page.js.map +2 -2
  303. package/dist/modules/devices/backend/devices/useDeviceUserLabels.js +34 -0
  304. package/dist/modules/devices/backend/devices/useDeviceUserLabels.js.map +7 -0
  305. package/dist/modules/devices/backend/devices/userOptions.js +52 -0
  306. package/dist/modules/devices/backend/devices/userOptions.js.map +7 -0
  307. package/dist/modules/devices/setup.js +6 -2
  308. package/dist/modules/devices/setup.js.map +2 -2
  309. package/dist/modules/directory/backend/directory/organizations/page.js +2 -1
  310. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  311. package/dist/modules/directory/backend/directory/tenants/page.js +2 -1
  312. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  313. package/dist/modules/directory/di.js +9 -0
  314. package/dist/modules/directory/di.js.map +2 -2
  315. package/dist/modules/directory/services/organizationHierarchyService.js +29 -0
  316. package/dist/modules/directory/services/organizationHierarchyService.js.map +7 -0
  317. package/dist/modules/directory/services/organizationScopeService.js +56 -0
  318. package/dist/modules/directory/services/organizationScopeService.js.map +7 -0
  319. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  320. package/dist/modules/entities/api/records.js +4 -2
  321. package/dist/modules/entities/api/records.js.map +2 -2
  322. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +3 -1
  323. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  324. package/dist/modules/eudr/api/plots/route.js +5 -1
  325. package/dist/modules/eudr/api/plots/route.js.map +2 -2
  326. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +3 -0
  327. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
  328. package/dist/modules/eudr/backend/eudr/plots/page.js +3 -0
  329. package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
  330. package/dist/modules/eudr/backend/eudr/product-mappings/page.js +3 -0
  331. package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
  332. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +3 -0
  333. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
  334. package/dist/modules/eudr/backend/eudr/statements/page.js +3 -0
  335. package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
  336. package/dist/modules/eudr/commands/statements.js +0 -3
  337. package/dist/modules/eudr/commands/statements.js.map +2 -2
  338. package/dist/modules/eudr/data/validators.js +4 -1
  339. package/dist/modules/eudr/data/validators.js.map +2 -2
  340. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +1 -0
  341. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  342. package/dist/modules/feature_toggles/components/OverridesTable.js +1 -0
  343. package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
  344. package/dist/modules/feature_toggles/defaults.json +0 -8
  345. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +3 -0
  346. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
  347. package/dist/modules/inbox_ops/backend/inbox-ops/page.js +3 -0
  348. package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
  349. package/dist/modules/inbox_ops/lib/htmlToPlainText.js +1 -12
  350. package/dist/modules/inbox_ops/lib/htmlToPlainText.js.map +2 -2
  351. package/dist/modules/integrations/api/[id]/credentials/route.js +6 -1
  352. package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
  353. package/dist/modules/integrations/backend/integrations/[id]/page.js +38 -29
  354. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  355. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +36 -9
  356. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  357. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js +55 -0
  358. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js.map +7 -0
  359. package/dist/modules/integrations/data/validators.js +11 -3
  360. package/dist/modules/integrations/data/validators.js.map +2 -2
  361. package/dist/modules/integrations/lib/credentials-masking.js +6 -2
  362. package/dist/modules/integrations/lib/credentials-masking.js.map +2 -2
  363. package/dist/modules/messages/api/[id]/route.js +29 -1
  364. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  365. package/dist/modules/messages/api/openapi.js +17 -2
  366. package/dist/modules/messages/api/openapi.js.map +2 -2
  367. package/dist/modules/messages/api/route.js +17 -2
  368. package/dist/modules/messages/api/route.js.map +2 -2
  369. package/dist/modules/messages/components/MessagesInboxPageClient.js +7 -14
  370. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  371. package/dist/modules/messages/components/inboxFilters.js +15 -0
  372. package/dist/modules/messages/components/inboxFilters.js.map +2 -2
  373. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +11 -1
  374. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +2 -2
  375. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +3 -1
  376. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +2 -2
  377. package/dist/modules/messages/components/message-detail/panels/thread-panel.js +2 -1
  378. package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +2 -2
  379. package/dist/modules/messages/components/messageListLabels.js +14 -2
  380. package/dist/modules/messages/components/messageListLabels.js.map +2 -2
  381. package/dist/modules/messages/data/validators.js +18 -4
  382. package/dist/modules/messages/data/validators.js.map +2 -2
  383. package/dist/modules/messages/lib/channel-sender-identity.js +26 -0
  384. package/dist/modules/messages/lib/channel-sender-identity.js.map +7 -0
  385. package/dist/modules/messages/lib/composeSourceChannelType.js +41 -0
  386. package/dist/modules/messages/lib/composeSourceChannelType.js.map +7 -0
  387. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +4 -6
  388. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
  389. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +3 -1
  390. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  391. package/dist/modules/payment_gateways/lib/webhook-processor.js +7 -0
  392. package/dist/modules/payment_gateways/lib/webhook-processor.js.map +2 -2
  393. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +3 -0
  394. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  395. package/dist/modules/push_notifications/backend/push_notifications/page.js +3 -1
  396. package/dist/modules/push_notifications/backend/push_notifications/page.js.map +2 -2
  397. package/dist/modules/push_notifications/backend/push_notifications/send/page.js +1 -1
  398. package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +2 -2
  399. package/dist/modules/query_index/lib/engine.js +150 -51
  400. package/dist/modules/query_index/lib/engine.js.map +2 -2
  401. package/dist/modules/query_index/lib/search-entity-policy.js +14 -0
  402. package/dist/modules/query_index/lib/search-entity-policy.js.map +7 -0
  403. package/dist/modules/query_index/lib/search-tokens.js +79 -3
  404. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  405. package/dist/modules/resources/backend/resources/resource-types/page.js +3 -1
  406. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  407. package/dist/modules/resources/backend/resources/resources/page.js +3 -1
  408. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  409. package/dist/modules/sales/backend/sales/channels/offers/page.js +3 -0
  410. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  411. package/dist/modules/sales/backend/sales/channels/page.js +3 -0
  412. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  413. package/dist/modules/sales/backend/sales/documents/[id]/page.js +10 -8
  414. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  415. package/dist/modules/sales/commands/documents.js +79 -1
  416. package/dist/modules/sales/commands/documents.js.map +2 -2
  417. package/dist/modules/sales/components/PriceWithCurrency.js +7 -5
  418. package/dist/modules/sales/components/PriceWithCurrency.js.map +2 -2
  419. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +3 -0
  420. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  421. package/dist/modules/sales/components/documents/AdjustmentsSection.js +8 -6
  422. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  423. package/dist/modules/sales/components/documents/ItemsSection.js +51 -22
  424. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  425. package/dist/modules/sales/components/documents/LineItemDialog.js +83 -18
  426. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  427. package/dist/modules/sales/components/documents/PaymentsSection.js +23 -9
  428. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  429. package/dist/modules/sales/components/documents/ReturnsSection.js +8 -6
  430. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  431. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +68 -14
  432. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  433. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +6 -5
  434. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +2 -2
  435. package/dist/modules/sales/components/documents/ShipmentDialog.js +5 -4
  436. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  437. package/dist/modules/sales/components/documents/ShipmentsSection.js +8 -6
  438. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  439. package/dist/modules/sales/components/documents/lineItemShipmentLock.js +54 -0
  440. package/dist/modules/sales/components/documents/lineItemShipmentLock.js.map +7 -0
  441. package/dist/modules/sales/components/documents/lineItemUtils.js +2 -2
  442. package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
  443. package/dist/modules/sales/data/entities.js +8 -2
  444. package/dist/modules/sales/data/entities.js.map +2 -2
  445. package/dist/modules/sales/extension-points.js +1 -0
  446. package/dist/modules/sales/extension-points.js.map +2 -2
  447. package/dist/modules/sales/lib/salesChannelsToggleSeed.js +33 -0
  448. package/dist/modules/sales/lib/salesChannelsToggleSeed.js.map +7 -0
  449. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js +32 -0
  450. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js.map +7 -0
  451. package/dist/modules/sales/setup.js +2 -0
  452. package/dist/modules/sales/setup.js.map +2 -2
  453. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +10 -2
  454. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +2 -2
  455. package/dist/modules/sales/widgets/injection-table.js +4 -7
  456. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  457. package/dist/modules/staff/backend/staff/leave-requests/page.js +3 -0
  458. package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
  459. package/dist/modules/staff/backend/staff/my-leave-requests/page.js +3 -0
  460. package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
  461. package/dist/modules/staff/backend/staff/team-members/page.js +3 -0
  462. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  463. package/dist/modules/staff/backend/staff/team-roles/page.js +3 -0
  464. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  465. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +3 -0
  466. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  467. package/dist/modules/staff/backend/staff/teams/page.js +3 -0
  468. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  469. package/dist/modules/staff/backend/staff/timesheets/page.js +29 -18
  470. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  471. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +3 -0
  472. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  473. package/dist/modules/sync_excel/lib/adapters/customers.js +1 -0
  474. package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
  475. package/dist/modules/warranty_claims/api/assignees/route.js +3 -3
  476. package/dist/modules/warranty_claims/api/assignees/route.js.map +2 -2
  477. package/dist/modules/warranty_claims/api/portal/attachments/route.js +2 -2
  478. package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
  479. package/dist/modules/warranty_claims/api/portal/claims/route.js +12 -9
  480. package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
  481. package/dist/modules/warranty_claims/backend/page.js +3 -0
  482. package/dist/modules/warranty_claims/backend/page.js.map +2 -2
  483. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js +3 -0
  484. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js.map +2 -2
  485. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js +3 -0
  486. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map +2 -2
  487. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js +3 -0
  488. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js.map +2 -2
  489. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +3 -0
  490. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
  491. package/dist/modules/wms/api/warehouseSearch.js +21 -0
  492. package/dist/modules/wms/api/warehouseSearch.js.map +7 -0
  493. package/dist/modules/wms/api/warehouses/route.js +13 -9
  494. package/dist/modules/wms/api/warehouses/route.js.map +2 -2
  495. package/dist/modules/wms/api/zones/route.js +15 -2
  496. package/dist/modules/wms/api/zones/route.js.map +2 -2
  497. package/dist/modules/wms/commands/configuration.js +121 -9
  498. package/dist/modules/wms/commands/configuration.js.map +2 -2
  499. package/dist/modules/wms/commands/inventory-actions.js +3 -0
  500. package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
  501. package/dist/modules/wms/commands/shared.js +9 -1
  502. package/dist/modules/wms/commands/shared.js.map +2 -2
  503. package/dist/modules/wms/components/backend/WarehouseEditDialog.js +158 -0
  504. package/dist/modules/wms/components/backend/WarehouseEditDialog.js.map +7 -0
  505. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +76 -111
  506. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +3 -3
  507. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +1 -0
  508. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
  509. package/dist/modules/wms/components/backend/WmsLotsListPage.js +1 -0
  510. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
  511. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +27 -20
  512. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
  513. package/dist/modules/wms/components/backend/warehouseFormOptions.js +66 -0
  514. package/dist/modules/wms/components/backend/warehouseFormOptions.js.map +7 -0
  515. package/dist/modules/workflows/backend/definitions/page.js +3 -1
  516. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  517. package/dist/modules/workflows/backend/events/page.js +3 -1
  518. package/dist/modules/workflows/backend/events/page.js.map +2 -2
  519. package/dist/modules/workflows/backend/instances/page.js +3 -1
  520. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  521. package/dist/modules/workflows/backend/tasks/page.js +3 -1
  522. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  523. package/dist/modules/workflows/lib/activity-executor.js +4 -0
  524. package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
  525. package/package.json +9 -10
  526. package/src/helpers/integration/api.ts +33 -1
  527. package/src/helpers/integration/communicationChannelsFixtures.ts +69 -1
  528. package/src/modules/api_keys/api/keys/route.ts +3 -1
  529. package/src/modules/api_keys/backend/api-keys/page.tsx +4 -1
  530. package/src/modules/api_keys/di.ts +7 -0
  531. package/src/modules/api_keys/services/principalService.ts +33 -0
  532. package/src/modules/attachments/AGENTS.md +15 -0
  533. package/src/modules/attachments/api/route.ts +2 -2
  534. package/src/modules/attachments/components/AttachmentLibrary.tsx +3 -0
  535. package/src/modules/attachments/di.ts +16 -0
  536. package/src/modules/attachments/i18n/de.json +5 -0
  537. package/src/modules/attachments/i18n/en.json +5 -0
  538. package/src/modules/attachments/i18n/es.json +5 -0
  539. package/src/modules/attachments/i18n/ko.json +5 -0
  540. package/src/modules/attachments/i18n/pl.json +5 -0
  541. package/src/modules/attachments/index.ts +10 -0
  542. package/src/modules/attachments/lib/attachment-service.ts +468 -0
  543. package/src/modules/attachments/lib/scoped-upload-service.ts +46 -0
  544. package/src/modules/attachments/lib/upload-limits.ts +6 -2
  545. package/src/modules/audit_logs/backend/audit-logs/page.tsx +8 -0
  546. package/src/modules/audit_logs/lib/display-helpers.tsx +42 -32
  547. package/src/modules/audit_logs/services/actionLogService.ts +74 -11
  548. package/src/modules/auth/acl.ts +30 -6
  549. package/src/modules/auth/api/feature-check.ts +10 -3
  550. package/src/modules/auth/api/login.ts +9 -1
  551. package/src/modules/auth/api/reset/validate.ts +57 -0
  552. package/src/modules/auth/api/roles/acl/route.ts +42 -39
  553. package/src/modules/auth/api/session/refresh.ts +32 -1
  554. package/src/modules/auth/api/users/acl/route.ts +177 -53
  555. package/src/modules/auth/api/users/route.ts +18 -5
  556. package/src/modules/auth/backend/roles/[id]/edit/page.meta.ts +5 -2
  557. package/src/modules/auth/backend/roles/page.tsx +4 -2
  558. package/src/modules/auth/backend/users/[id]/edit/page.meta.ts +5 -2
  559. package/src/modules/auth/backend/users/page.tsx +3 -2
  560. package/src/modules/auth/commands/acl.ts +495 -0
  561. package/src/modules/auth/components/AclEditor.tsx +63 -33
  562. package/src/modules/auth/data/entities.ts +4 -1
  563. package/src/modules/auth/data/validators.ts +5 -0
  564. package/src/modules/auth/di.ts +46 -16
  565. package/src/modules/auth/frontend/reset/[token]/page.tsx +74 -0
  566. package/src/modules/auth/i18n/de.json +389 -0
  567. package/src/modules/auth/i18n/en.json +389 -0
  568. package/src/modules/auth/i18n/es.json +389 -0
  569. package/src/modules/auth/i18n/ko.json +389 -0
  570. package/src/modules/auth/i18n/pl.json +391 -2
  571. package/src/modules/auth/lib/grantChecks.ts +6 -0
  572. package/src/modules/auth/lib/userIdFilter.ts +31 -0
  573. package/src/modules/auth/services/authService.ts +18 -2
  574. package/src/modules/auth/services/principalService.ts +266 -0
  575. package/src/modules/auth/services/rbacService.ts +110 -24
  576. package/src/modules/auth/services/roleOrganizationScope.ts +70 -0
  577. package/src/modules/business_rules/backend/logs/page.tsx +4 -1
  578. package/src/modules/business_rules/backend/rules/page.tsx +4 -1
  579. package/src/modules/business_rules/backend/sets/page.tsx +4 -1
  580. package/src/modules/business_rules/lib/expression-evaluator.ts +9 -9
  581. package/src/modules/business_rules/lib/rule-evaluator.ts +10 -9
  582. package/src/modules/catalog/ai-agents.ts +1 -1
  583. package/src/modules/catalog/ai-tools/merchandising-pack.ts +2 -2
  584. package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +12 -5
  585. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +3 -0
  586. package/src/modules/catalog/components/products/ProductsDataTable.tsx +7 -0
  587. package/src/modules/catalog/i18n/de.json +1 -0
  588. package/src/modules/catalog/i18n/en.json +1 -0
  589. package/src/modules/catalog/i18n/es.json +1 -0
  590. package/src/modules/catalog/i18n/ko.json +1 -0
  591. package/src/modules/catalog/i18n/pl.json +1 -0
  592. package/src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx +4 -0
  593. package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +17 -1
  594. package/src/modules/communication_channels/api/post/test-seed/route.ts +155 -16
  595. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +4 -0
  596. package/src/modules/communication_channels/commands/ingest-inbound-message.ts +38 -1
  597. package/src/modules/communication_channels/di.ts +7 -0
  598. package/src/modules/communication_channels/lib/adapter.ts +14 -0
  599. package/src/modules/communication_channels/lib/email-capabilities.ts +4 -0
  600. package/src/modules/communication_channels/lib/outbound-recipient.ts +71 -0
  601. package/src/modules/communication_channels/lib/resolve-channel-type.ts +99 -0
  602. package/src/modules/communication_channels/lib/test-seed.ts +64 -4
  603. package/src/modules/configs/i18n/de.json +2 -0
  604. package/src/modules/configs/i18n/en.json +2 -0
  605. package/src/modules/configs/i18n/es.json +2 -0
  606. package/src/modules/configs/i18n/ko.json +2 -0
  607. package/src/modules/configs/i18n/pl.json +2 -0
  608. package/src/modules/configs/lib/system-status.ts +9 -0
  609. package/src/modules/currencies/AGENTS.md +3 -0
  610. package/src/modules/currencies/backend/currencies/page.tsx +4 -1
  611. package/src/modules/currencies/backend/exchange-rates/page.tsx +4 -1
  612. package/src/modules/currencies/services/README.md +45 -0
  613. package/src/modules/currencies/services/rateFetchingService.ts +6 -1
  614. package/src/modules/customer_accounts/api/admin/domain-mappings.ts +7 -0
  615. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +4 -1
  616. package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +4 -1
  617. package/src/modules/customer_accounts/services/domainMappingService.ts +10 -0
  618. package/src/modules/customers/ai-tools/companies-pack.ts +4 -1
  619. package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +17 -2
  620. package/src/modules/customers/ai-tools/deals-pack.ts +66 -1
  621. package/src/modules/customers/ai-tools/people-pack.ts +4 -1
  622. package/src/modules/customers/api/activities/route.ts +45 -0
  623. package/src/modules/customers/api/companies/[id]/people/route.ts +24 -73
  624. package/src/modules/customers/api/companies/[id]/route.ts +24 -107
  625. package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +16 -8
  626. package/src/modules/customers/api/deals/[id]/companies/route.ts +4 -1
  627. package/src/modules/customers/api/deals/[id]/people/route.ts +4 -1
  628. package/src/modules/customers/api/deals/[id]/route.ts +17 -28
  629. package/src/modules/customers/api/deals/[id]/stats/route.ts +10 -25
  630. package/src/modules/customers/api/deals/aggregate/route.ts +14 -4
  631. package/src/modules/customers/api/deals/map/route.ts +1 -0
  632. package/src/modules/customers/api/deals/route.ts +50 -1
  633. package/src/modules/customers/api/entity-roles-factory.ts +8 -4
  634. package/src/modules/customers/api/interactions/route.ts +8 -2
  635. package/src/modules/customers/api/interactions/tasks/route.ts +24 -1
  636. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +12 -4
  637. package/src/modules/customers/api/people/[id]/companies/context.ts +4 -1
  638. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +4 -1
  639. package/src/modules/customers/api/people/[id]/route.ts +16 -11
  640. package/src/modules/customers/api/people/check-phone/route.ts +75 -10
  641. package/src/modules/customers/api/todos/route.ts +27 -2
  642. package/src/modules/customers/backend/customers/companies/page.tsx +5 -2
  643. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +7 -2
  644. package/src/modules/customers/backend/customers/deals/page.tsx +8 -2
  645. package/src/modules/customers/backend/customers/deals/pipeline/components/Lane.tsx +5 -14
  646. package/src/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.tsx +109 -27
  647. package/src/modules/customers/backend/customers/deals/pipeline/components/toneClasses.ts +21 -0
  648. package/src/modules/customers/backend/customers/people/page.tsx +5 -2
  649. package/src/modules/customers/backend/hooks/useEmailDuplicateCheck.ts +12 -4
  650. package/src/modules/customers/commands/deals.ts +34 -59
  651. package/src/modules/customers/commands/interactions.ts +1 -1
  652. package/src/modules/customers/commands/personCompanyLinks.ts +224 -8
  653. package/src/modules/customers/components/CustomerTodosTable.tsx +2 -0
  654. package/src/modules/customers/components/DealsKpiStrip.tsx +7 -7
  655. package/src/modules/customers/components/calendar/AgendaList.tsx +3 -3
  656. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -1
  657. package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
  658. package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +1 -1
  659. package/src/modules/customers/components/calendar/EventBlock.tsx +2 -2
  660. package/src/modules/customers/components/calendar/EventPeekPopover.tsx +4 -2
  661. package/src/modules/customers/components/calendar/editor/PeopleField.tsx +61 -5
  662. package/src/modules/customers/components/calendar/editor/hooks.ts +7 -1
  663. package/src/modules/customers/components/calendar/types.ts +2 -2
  664. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +5 -4
  665. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +8 -1
  666. package/src/modules/customers/components/detail/DealForm.tsx +22 -2
  667. package/src/modules/customers/components/detail/DealsSection.tsx +11 -5
  668. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +58 -12
  669. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +8 -1
  670. package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +23 -14
  671. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +5 -5
  672. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +5 -5
  673. package/src/modules/customers/components/detail/types.ts +1 -1
  674. package/src/modules/customers/components/detail/utils.ts +15 -5
  675. package/src/modules/customers/data/entities.ts +1 -1
  676. package/src/modules/customers/data/validators.ts +50 -9
  677. package/src/modules/customers/events.ts +5 -0
  678. package/src/modules/customers/i18n/de.json +9 -1
  679. package/src/modules/customers/i18n/en.json +9 -1
  680. package/src/modules/customers/i18n/es.json +9 -1
  681. package/src/modules/customers/i18n/ko.json +9 -1
  682. package/src/modules/customers/i18n/pl.json +9 -1
  683. package/src/modules/customers/lib/calendar/conflicts.ts +10 -2
  684. package/src/modules/customers/lib/calendar/editorPayload.ts +4 -3
  685. package/src/modules/customers/lib/calendar/mapItem.ts +8 -3
  686. package/src/modules/customers/lib/calendar/participantIdentity.ts +17 -0
  687. package/src/modules/customers/lib/closureStage.ts +76 -0
  688. package/src/modules/customers/lib/dealStatus.ts +42 -0
  689. package/src/modules/customers/lib/detailReadAccess.ts +35 -0
  690. package/src/modules/customers/lib/findPeopleByAddresses.ts +8 -6
  691. package/src/modules/customers/lib/personCompanies.ts +136 -1
  692. package/src/modules/customers/lib/todoCompatibility.ts +19 -1
  693. package/src/modules/dashboards/i18n/es.json +4 -4
  694. package/src/modules/dashboards/i18n/pl.json +7 -7
  695. package/src/modules/dashboards/lib/widgetScope.ts +6 -0
  696. package/src/modules/data_sync/AGENTS.md +1 -1
  697. package/src/modules/data_sync/backend/data-sync/page.tsx +4 -1
  698. package/src/modules/data_sync/lib/abandoned-run.ts +56 -0
  699. package/src/modules/data_sync/lib/adapter.ts +36 -0
  700. package/src/modules/data_sync/lib/sync-engine.ts +113 -5
  701. package/src/modules/data_sync/workers/sync-export.ts +4 -0
  702. package/src/modules/data_sync/workers/sync-import.ts +4 -0
  703. package/src/modules/devices/AGENTS.md +20 -1
  704. package/src/modules/devices/acl.ts +9 -1
  705. package/src/modules/devices/api/admin/devices/[id]/route.ts +5 -34
  706. package/src/modules/devices/api/admin/devices/route.ts +14 -1
  707. package/src/modules/devices/api/deviceList.ts +135 -11
  708. package/src/modules/devices/api/deviceSerialization.ts +50 -0
  709. package/src/modules/devices/api/openapi.ts +9 -1
  710. package/src/modules/devices/api/route.ts +9 -1
  711. package/src/modules/devices/backend/devices/[id]/page.tsx +18 -32
  712. package/src/modules/devices/backend/devices/create/page.tsx +17 -1
  713. package/src/modules/devices/backend/devices/page.tsx +44 -45
  714. package/src/modules/devices/backend/devices/useDeviceUserLabels.ts +45 -0
  715. package/src/modules/devices/backend/devices/userOptions.ts +99 -0
  716. package/src/modules/devices/i18n/de.json +3 -2
  717. package/src/modules/devices/i18n/en.json +3 -2
  718. package/src/modules/devices/i18n/es.json +3 -2
  719. package/src/modules/devices/i18n/ko.json +3 -2
  720. package/src/modules/devices/i18n/pl.json +3 -2
  721. package/src/modules/devices/setup.ts +6 -2
  722. package/src/modules/directory/backend/directory/organizations/page.tsx +3 -1
  723. package/src/modules/directory/backend/directory/tenants/page.tsx +3 -1
  724. package/src/modules/directory/di.ts +14 -2
  725. package/src/modules/directory/services/organizationHierarchyService.ts +34 -0
  726. package/src/modules/directory/services/organizationScopeService.ts +85 -0
  727. package/src/modules/directory/utils/organizationScope.ts +4 -15
  728. package/src/modules/entities/api/records.ts +2 -0
  729. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +4 -1
  730. package/src/modules/eudr/api/plots/route.ts +4 -0
  731. package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +4 -0
  732. package/src/modules/eudr/backend/eudr/plots/page.tsx +4 -0
  733. package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +4 -0
  734. package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +4 -0
  735. package/src/modules/eudr/backend/eudr/statements/page.tsx +4 -0
  736. package/src/modules/eudr/commands/statements.ts +0 -3
  737. package/src/modules/eudr/data/validators.ts +16 -1
  738. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +2 -1
  739. package/src/modules/feature_toggles/components/OverridesTable.tsx +2 -1
  740. package/src/modules/feature_toggles/defaults.json +0 -8
  741. package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +4 -0
  742. package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +4 -0
  743. package/src/modules/inbox_ops/lib/htmlToPlainText.ts +1 -17
  744. package/src/modules/integrations/api/[id]/credentials/route.ts +6 -4
  745. package/src/modules/integrations/backend/integrations/[id]/page.tsx +61 -31
  746. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +44 -9
  747. package/src/modules/integrations/backend/integrations/credential-secret-fields.ts +84 -0
  748. package/src/modules/integrations/data/validators.ts +12 -2
  749. package/src/modules/integrations/i18n/de.json +1 -0
  750. package/src/modules/integrations/i18n/en.json +1 -0
  751. package/src/modules/integrations/i18n/es.json +1 -0
  752. package/src/modules/integrations/i18n/ko.json +1 -0
  753. package/src/modules/integrations/i18n/pl.json +1 -0
  754. package/src/modules/integrations/lib/credentials-masking.ts +10 -6
  755. package/src/modules/messages/api/[id]/route.ts +55 -1
  756. package/src/modules/messages/api/openapi.ts +20 -0
  757. package/src/modules/messages/api/route.ts +31 -2
  758. package/src/modules/messages/components/MessagesInboxPageClient.tsx +9 -16
  759. package/src/modules/messages/components/inboxFilters.ts +36 -0
  760. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +14 -1
  761. package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +3 -1
  762. package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +2 -1
  763. package/src/modules/messages/components/message-detail/types.ts +3 -0
  764. package/src/modules/messages/components/messageListLabels.ts +52 -3
  765. package/src/modules/messages/data/validators.ts +43 -4
  766. package/src/modules/messages/lib/channel-sender-identity.ts +55 -0
  767. package/src/modules/messages/lib/composeSourceChannelType.ts +95 -0
  768. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +4 -6
  769. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +4 -1
  770. package/src/modules/payment_gateways/lib/webhook-processor.ts +11 -0
  771. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +4 -0
  772. package/src/modules/push_notifications/backend/push_notifications/page.tsx +4 -1
  773. package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +4 -4
  774. package/src/modules/query_index/lib/engine.ts +249 -61
  775. package/src/modules/query_index/lib/search-entity-policy.ts +46 -0
  776. package/src/modules/query_index/lib/search-tokens.ts +135 -3
  777. package/src/modules/resources/backend/resources/resource-types/page.tsx +4 -1
  778. package/src/modules/resources/backend/resources/resources/page.tsx +4 -1
  779. package/src/modules/sales/backend/sales/channels/offers/page.tsx +4 -0
  780. package/src/modules/sales/backend/sales/channels/page.tsx +4 -0
  781. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +14 -8
  782. package/src/modules/sales/commands/documents.ts +93 -0
  783. package/src/modules/sales/components/PriceWithCurrency.tsx +17 -5
  784. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +4 -0
  785. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +6 -5
  786. package/src/modules/sales/components/documents/ItemsSection.tsx +56 -18
  787. package/src/modules/sales/components/documents/LineItemDialog.tsx +137 -20
  788. package/src/modules/sales/components/documents/PaymentsSection.tsx +20 -9
  789. package/src/modules/sales/components/documents/ReturnsSection.tsx +6 -5
  790. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +106 -14
  791. package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +6 -5
  792. package/src/modules/sales/components/documents/ShipmentDialog.tsx +5 -4
  793. package/src/modules/sales/components/documents/ShipmentsSection.tsx +6 -5
  794. package/src/modules/sales/components/documents/lineItemShipmentLock.ts +74 -0
  795. package/src/modules/sales/components/documents/lineItemUtils.ts +7 -2
  796. package/src/modules/sales/data/entities.ts +6 -0
  797. package/src/modules/sales/extension-points.ts +1 -0
  798. package/src/modules/sales/i18n/de.json +8 -0
  799. package/src/modules/sales/i18n/en.json +8 -0
  800. package/src/modules/sales/i18n/es.json +8 -0
  801. package/src/modules/sales/i18n/ko.json +8 -0
  802. package/src/modules/sales/i18n/pl.json +8 -0
  803. package/src/modules/sales/lib/salesChannelsToggleSeed.ts +42 -0
  804. package/src/modules/sales/migrations/.snapshot-open-mercato.json +60 -0
  805. package/src/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.ts +87 -0
  806. package/src/modules/sales/setup.ts +2 -0
  807. package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +9 -1
  808. package/src/modules/sales/widgets/injection-table.ts +4 -7
  809. package/src/modules/staff/backend/staff/leave-requests/page.tsx +4 -0
  810. package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +4 -0
  811. package/src/modules/staff/backend/staff/team-members/page.tsx +6 -0
  812. package/src/modules/staff/backend/staff/team-roles/page.tsx +4 -0
  813. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +4 -0
  814. package/src/modules/staff/backend/staff/teams/page.tsx +4 -0
  815. package/src/modules/staff/backend/staff/timesheets/page.tsx +12 -1
  816. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +4 -0
  817. package/src/modules/sync_excel/lib/adapters/customers.ts +5 -0
  818. package/src/modules/warranty_claims/api/assignees/route.ts +3 -3
  819. package/src/modules/warranty_claims/api/portal/attachments/route.ts +2 -2
  820. package/src/modules/warranty_claims/api/portal/claims/route.ts +12 -9
  821. package/src/modules/warranty_claims/backend/page.tsx +4 -0
  822. package/src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx +4 -0
  823. package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx +4 -0
  824. package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx +4 -0
  825. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +4 -0
  826. package/src/modules/wms/api/warehouseSearch.ts +23 -0
  827. package/src/modules/wms/api/warehouses/route.ts +13 -9
  828. package/src/modules/wms/api/zones/route.ts +16 -0
  829. package/src/modules/wms/commands/configuration.ts +159 -10
  830. package/src/modules/wms/commands/inventory-actions.ts +3 -0
  831. package/src/modules/wms/commands/shared.ts +17 -0
  832. package/src/modules/wms/components/backend/WarehouseEditDialog.tsx +216 -0
  833. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +95 -141
  834. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +2 -0
  835. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +2 -0
  836. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +36 -20
  837. package/src/modules/wms/components/backend/warehouseFormOptions.ts +72 -0
  838. package/src/modules/wms/i18n/de.json +2 -0
  839. package/src/modules/wms/i18n/en.json +2 -0
  840. package/src/modules/wms/i18n/es.json +2 -0
  841. package/src/modules/wms/i18n/ko.json +2 -0
  842. package/src/modules/wms/i18n/pl.json +2 -0
  843. package/src/modules/workflows/backend/definitions/page.tsx +4 -1
  844. package/src/modules/workflows/backend/events/page.tsx +4 -1
  845. package/src/modules/workflows/backend/instances/page.tsx +4 -1
  846. package/src/modules/workflows/backend/tasks/page.tsx +4 -1
  847. package/src/modules/workflows/lib/activity-executor.ts +9 -0
@@ -52,6 +52,11 @@ import {
52
52
  refreshIntegrationDetailPanels,
53
53
  refreshIntegrationRunActivityPanels,
54
54
  } from '../detail-page-refresh'
55
+ import {
56
+ buildCredentialEditValues,
57
+ buildIntegrationCredentialSavePayload,
58
+ type SecretFieldsConfigured,
59
+ } from '../credential-secret-fields'
55
60
  import { isValidCredentialUrl } from '../../../lib/credentials-field-validation'
56
61
 
57
62
  type CredentialField = IntegrationCredentialField
@@ -290,19 +295,32 @@ function resolvePathnameId(pathname: string): string | undefined {
290
295
  return decodeURIComponent(integrationId)
291
296
  }
292
297
 
293
- function buildCredentialFields(credFields: CredentialField[]): CrudField[] {
298
+ function buildCredentialFields(
299
+ credFields: CredentialField[],
300
+ secretFieldsConfigured: SecretFieldsConfigured,
301
+ t: ReturnType<typeof useT>,
302
+ ): CrudField[] {
294
303
  return credFields.map((field) => {
304
+ const baseDescription = field.helpDetails ? (
305
+ <div className="space-y-1">
306
+ {field.helpText ? <div>{field.helpText}</div> : null}
307
+ <WebhookSetupGuide guide={field.helpDetails} />
308
+ </div>
309
+ ) : field.helpText
310
+ const description = field.type === 'secret' && secretFieldsConfigured[field.key] ? (
311
+ <div className="space-y-1">
312
+ {baseDescription ? <div>{baseDescription}</div> : null}
313
+ <p className="text-xs text-muted-foreground">
314
+ {t('integrations.detail.credentials.secretConfigured')}
315
+ </p>
316
+ </div>
317
+ ) : baseDescription
295
318
  const shared = {
296
319
  id: field.key,
297
320
  label: field.label,
298
- description: field.helpDetails ? (
299
- <div className="space-y-1">
300
- {field.helpText ? <div>{field.helpText}</div> : null}
301
- <WebhookSetupGuide guide={field.helpDetails} buttonLabel="Show details" />
302
- </div>
303
- ) : field.helpText,
321
+ description,
304
322
  placeholder: field.placeholder,
305
- required: field.required,
323
+ required: field.required && !(field.type === 'secret' && secretFieldsConfigured[field.key]),
306
324
  visibleWhen: field.visibleWhen,
307
325
  }
308
326
 
@@ -317,6 +335,7 @@ function buildCredentialFields(credFields: CredentialField[]): CrudField[] {
317
335
  value={typeof value === 'string' ? value : ''}
318
336
  onChange={(event) => setValue(event.target.value)}
319
337
  disabled={disabled}
338
+ autoComplete="new-password"
320
339
  />
321
340
  ),
322
341
  }
@@ -426,6 +445,7 @@ export default function IntegrationDetailPage({ params }: IntegrationDetailPageP
426
445
  const [isNotFound, setIsNotFound] = React.useState(false)
427
446
 
428
447
  const [credValues, setCredValues] = React.useState<Record<string, unknown>>({})
448
+ const [secretFieldsConfigured, setSecretFieldsConfigured] = React.useState<SecretFieldsConfigured>({})
429
449
  const [credentialsUpdatedAt, setCredentialsUpdatedAt] = React.useState<string | null>(null)
430
450
  const [credentialsFormKey, setCredentialsFormKey] = React.useState(0)
431
451
  const [isSavingCredentials, setIsSavingCredentials] = React.useState(false)
@@ -490,13 +510,18 @@ export default function IntegrationDetailPage({ params }: IntegrationDetailPageP
490
510
  const loadCredentials = React.useCallback(async () => {
491
511
  const currentIntegrationId = resolveCurrentIntegrationId()
492
512
  if (!currentIntegrationId) return
493
- const call = await apiCall<{ credentials: Record<string, unknown>; updatedAt?: string | null }>(
513
+ const call = await apiCall<{
514
+ credentials: Record<string, unknown>
515
+ secretFieldsConfigured?: SecretFieldsConfigured
516
+ updatedAt?: string | null
517
+ }>(
494
518
  `/api/integrations/${encodeURIComponent(currentIntegrationId)}/credentials`,
495
519
  undefined,
496
520
  { fallback: null },
497
521
  )
498
522
  if (call.ok && call.result) {
499
523
  setCredentialsUpdatedAt(call.result.updatedAt ?? null)
524
+ setSecretFieldsConfigured(call.result.secretFieldsConfigured ?? {})
500
525
  }
501
526
  if (call.ok && call.result?.credentials) {
502
527
  const next = { ...call.result.credentials }
@@ -713,35 +738,32 @@ export default function IntegrationDetailPage({ params }: IntegrationDetailPageP
713
738
  if (!currentIntegrationId) return
714
739
  setIsSavingCredentials(true)
715
740
  try {
716
- const sanitizedValues = { ...values }
717
- if (currentIntegrationId === 'storage_s3') {
718
- const authMode = sanitizedValues.authMode
719
- if (authMode !== 'access_keys' && authMode !== 'ambient') {
720
- const hasKeys = Boolean(sanitizedValues.accessKeyId || sanitizedValues.secretAccessKey)
721
- sanitizedValues.authMode = hasKeys ? 'access_keys' : 'ambient'
722
- }
723
- if (sanitizedValues.authMode === 'ambient') {
724
- delete sanitizedValues.accessKeyId
725
- delete sanitizedValues.secretAccessKey
726
- delete sanitizedValues.sessionToken
727
- }
728
- }
741
+ const credentialFields = (
742
+ detail?.integration.credentials?.fields
743
+ ?? detail?.bundle?.credentials?.fields
744
+ ?? []
745
+ )
746
+ const savePayload = buildIntegrationCredentialSavePayload(
747
+ currentIntegrationId,
748
+ values,
749
+ credentialFields,
750
+ secretFieldsConfigured,
751
+ )
729
752
  const call = await runMutationWithContext({
730
753
  actionId: 'save-credentials',
731
754
  tabId: 'credentials',
732
- mutationPayload: { integrationId: currentIntegrationId, credentials: sanitizedValues },
755
+ mutationPayload: { integrationId: currentIntegrationId, ...savePayload },
733
756
  operation: () => withScopedApiRequestHeaders(
734
757
  buildOptimisticLockHeader(credentialsUpdatedAt),
735
758
  () => apiCall(`/api/integrations/${encodeURIComponent(currentIntegrationId)}/credentials`, {
736
759
  method: 'PUT',
737
760
  headers: { 'Content-Type': 'application/json' },
738
- body: JSON.stringify({ credentials: sanitizedValues }),
761
+ body: JSON.stringify(savePayload),
739
762
  }, { fallback: null }),
740
763
  ),
741
764
  })
742
765
 
743
766
  if (call.ok) {
744
- setCredValues(sanitizedValues)
745
767
  setCredentialsFormKey((current) => current + 1)
746
768
  flash(t('integrations.detail.credentials.saved'), 'success')
747
769
  void loadCredentials()
@@ -759,7 +781,7 @@ export default function IntegrationDetailPage({ params }: IntegrationDetailPageP
759
781
  } finally {
760
782
  setIsSavingCredentials(false)
761
783
  }
762
- }, [credentialsUpdatedAt, loadCredentials, resolveCurrentIntegrationId, runMutationWithContext, t])
784
+ }, [credentialsUpdatedAt, detail, loadCredentials, resolveCurrentIntegrationId, runMutationWithContext, secretFieldsConfigured, t])
763
785
 
764
786
  const handleVersionChange = React.useCallback(async (version: string) => {
765
787
  const currentIntegrationId = resolveCurrentIntegrationId()
@@ -837,8 +859,12 @@ export default function IntegrationDetailPage({ params }: IntegrationDetailPageP
837
859
  [detail?.bundle?.credentials?.fields, detail?.integration.credentials?.fields],
838
860
  )
839
861
  const credentialFormFields = React.useMemo(
840
- () => buildCredentialFields(editableCredentialFields),
841
- [editableCredentialFields],
862
+ () => buildCredentialFields(editableCredentialFields, secretFieldsConfigured, t),
863
+ [editableCredentialFields, secretFieldsConfigured, t],
864
+ )
865
+ const credentialFormValues = React.useMemo(
866
+ () => buildCredentialEditValues(credValues, secretFieldsConfigured),
867
+ [credValues, secretFieldsConfigured],
842
868
  )
843
869
  const credentialSchema = React.useMemo(() => (
844
870
  z.object({}).passthrough().superRefine((rawValues, ctx) => {
@@ -880,7 +906,11 @@ export default function IntegrationDetailPage({ params }: IntegrationDetailPageP
880
906
 
881
907
  const normalizedValue = typeof value === 'string' ? value : ''
882
908
 
883
- if (field.required && normalizedValue.trim().length === 0) {
909
+ if (
910
+ field.required
911
+ && normalizedValue.trim().length === 0
912
+ && !(field.type === 'secret' && secretFieldsConfigured[field.key])
913
+ ) {
884
914
  ctx.addIssue({
885
915
  code: z.ZodIssueCode.custom,
886
916
  path: [field.key],
@@ -922,7 +952,7 @@ export default function IntegrationDetailPage({ params }: IntegrationDetailPageP
922
952
  }
923
953
  })
924
954
  })
925
- ) as z.ZodType<Record<string, unknown>>, [editableCredentialFields, t])
955
+ ) as z.ZodType<Record<string, unknown>>, [editableCredentialFields, secretFieldsConfigured, t])
926
956
  const latestHealthLog = React.useMemo(() => logs.find(isHealthLog) ?? null, [logs])
927
957
  const latestOperationalLog = React.useMemo(
928
958
  () => logs.find((log) => (
@@ -1257,7 +1287,7 @@ export default function IntegrationDetailPage({ params }: IntegrationDetailPageP
1257
1287
  entityId="integrations.integration"
1258
1288
  schema={credentialSchema}
1259
1289
  fields={credentialFormFields}
1260
- initialValues={credValues}
1290
+ initialValues={credentialFormValues}
1261
1291
  onSubmit={handleSaveCredentials}
1262
1292
  embedded
1263
1293
  hideFooterActions
@@ -8,6 +8,7 @@ import { Badge } from '@open-mercato/ui/primitives/badge'
8
8
  import { Button } from '@open-mercato/ui/primitives/button'
9
9
  import { Switch } from '@open-mercato/ui/primitives/switch'
10
10
  import { Input } from '@open-mercato/ui/primitives/input'
11
+ import { PasswordInput } from '@open-mercato/ui/primitives/password-input'
11
12
  import {
12
13
  Select,
13
14
  SelectContent,
@@ -23,6 +24,11 @@ import { flash } from '@open-mercato/ui/backend/FlashMessages'
23
24
  import { useT } from '@open-mercato/shared/lib/i18n/context'
24
25
  import type { CredentialFieldType, IntegrationCredentialField } from '@open-mercato/shared/modules/integrations/types'
25
26
  import { LoadingMessage, ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'
27
+ import {
28
+ buildCredentialEditValues,
29
+ buildCredentialSavePayload,
30
+ type SecretFieldsConfigured,
31
+ } from '../../credential-secret-fields'
26
32
 
27
33
  type CredentialField = IntegrationCredentialField
28
34
 
@@ -88,6 +94,7 @@ export default function BundleConfigPage({ params }: BundleConfigPageProps) {
88
94
  const [error, setError] = React.useState<string | null>(null)
89
95
  const [isNotFound, setIsNotFound] = React.useState(false)
90
96
  const [credValues, setCredValues] = React.useState<Record<string, unknown>>({})
97
+ const [secretFieldsConfigured, setSecretFieldsConfigured] = React.useState<SecretFieldsConfigured>({})
91
98
  const [credentialsUpdatedAt, setCredentialsUpdatedAt] = React.useState<string | null>(null)
92
99
  const [isSavingCreds, setIsSavingCreds] = React.useState(false)
93
100
  const [togglingIds, setTogglingIds] = React.useState<Set<string>>(new Set())
@@ -134,13 +141,18 @@ export default function BundleConfigPage({ params }: BundleConfigPageProps) {
134
141
  }
135
142
  setDetail(call.result)
136
143
 
137
- const credCall = await apiCall<{ credentials: Record<string, unknown>; updatedAt?: string | null }>(
144
+ const credCall = await apiCall<{
145
+ credentials: Record<string, unknown>
146
+ secretFieldsConfigured?: SecretFieldsConfigured
147
+ updatedAt?: string | null
148
+ }>(
138
149
  `/api/integrations/${encodeURIComponent(currentBundleId)}/credentials`,
139
150
  undefined,
140
151
  { fallback: null },
141
152
  )
142
153
  if (credCall.ok && credCall.result) {
143
154
  setCredentialsUpdatedAt(credCall.result.updatedAt ?? null)
155
+ setSecretFieldsConfigured(credCall.result.secretFieldsConfigured ?? {})
144
156
  }
145
157
  if (credCall.ok && credCall.result?.credentials) {
146
158
  const next = { ...credCall.result.credentials }
@@ -151,7 +163,10 @@ export default function BundleConfigPage({ params }: BundleConfigPageProps) {
151
163
  next.authMode = hasKeys ? 'access_keys' : 'ambient'
152
164
  }
153
165
  }
154
- setCredValues(next)
166
+ setCredValues(buildCredentialEditValues(
167
+ next,
168
+ credCall.result.secretFieldsConfigured ?? {},
169
+ ))
155
170
  }
156
171
  setIsLoading(false)
157
172
  }, [resolveCurrentBundleId, t])
@@ -163,8 +178,13 @@ export default function BundleConfigPage({ params }: BundleConfigPageProps) {
163
178
  if (!currentBundleId) return
164
179
  setIsSavingCreds(true)
165
180
  try {
181
+ const savePayload = buildCredentialSavePayload(
182
+ credValues,
183
+ detail?.bundle?.credentials?.fields ?? [],
184
+ secretFieldsConfigured,
185
+ )
166
186
  const call = await runMutation({
167
- mutationPayload: { bundleId: currentBundleId, credentials: credValues },
187
+ mutationPayload: { bundleId: currentBundleId, ...savePayload },
168
188
  context: {
169
189
  formId: mutationContextId,
170
190
  operation: 'update',
@@ -179,7 +199,7 @@ export default function BundleConfigPage({ params }: BundleConfigPageProps) {
179
199
  () => apiCall(`/api/integrations/${encodeURIComponent(currentBundleId)}/credentials`, {
180
200
  method: 'PUT',
181
201
  headers: { 'Content-Type': 'application/json' },
182
- body: JSON.stringify({ credentials: credValues }),
202
+ body: JSON.stringify(savePayload),
183
203
  }, { fallback: null }),
184
204
  ),
185
205
  })
@@ -194,7 +214,7 @@ export default function BundleConfigPage({ params }: BundleConfigPageProps) {
194
214
  } finally {
195
215
  setIsSavingCreds(false)
196
216
  }
197
- }, [resolveCurrentBundleId, runMutation, mutationContextId, retryLastMutation, credValues, credentialsUpdatedAt, load, t])
217
+ }, [resolveCurrentBundleId, runMutation, mutationContextId, retryLastMutation, credValues, credentialsUpdatedAt, detail?.bundle?.credentials?.fields, load, secretFieldsConfigured, t])
198
218
 
199
219
  const handleToggle = React.useCallback(async (integrationId: string, enabled: boolean, updatedAt?: string | null) => {
200
220
  setTogglingIds((prev) => new Set(prev).add(integrationId))
@@ -295,15 +315,15 @@ export default function BundleConfigPage({ params }: BundleConfigPageProps) {
295
315
  <CardContent className="space-y-4">
296
316
  {credFields.filter(isFieldVisible).map((field) => (
297
317
  <div key={field.key} className="space-y-1.5">
298
- <label className="text-sm font-medium">
299
- {field.label}{field.required && <span className="text-red-500 ml-0.5">*</span>}
318
+ <label htmlFor={`bundle-credential-${field.key}`} className="text-sm font-medium">
319
+ {field.label}{field.required && <span className="ml-0.5 text-destructive">*</span>}
300
320
  </label>
301
321
  {field.type === 'select' && field.options ? (
302
322
  <Select
303
323
  value={(credValues[field.key] as string) || undefined}
304
324
  onValueChange={(value) => setCredValues((prev) => ({ ...prev, [field.key]: value ?? '' }))}
305
325
  >
306
- <SelectTrigger>
326
+ <SelectTrigger id={`bundle-credential-${field.key}`}>
307
327
  <SelectValue placeholder="—" />
308
328
  </SelectTrigger>
309
329
  <SelectContent>
@@ -314,17 +334,32 @@ export default function BundleConfigPage({ params }: BundleConfigPageProps) {
314
334
  </Select>
315
335
  ) : field.type === 'boolean' ? (
316
336
  <Switch
337
+ id={`bundle-credential-${field.key}`}
317
338
  checked={Boolean(credValues[field.key])}
318
339
  onCheckedChange={(checked) => setCredValues((prev) => ({ ...prev, [field.key]: checked }))}
319
340
  />
341
+ ) : field.type === 'secret' ? (
342
+ <PasswordInput
343
+ id={`bundle-credential-${field.key}`}
344
+ placeholder={field.placeholder}
345
+ value={(credValues[field.key] as string) ?? ''}
346
+ onChange={(event) => setCredValues((prev) => ({ ...prev, [field.key]: event.target.value }))}
347
+ autoComplete="new-password"
348
+ />
320
349
  ) : (
321
350
  <Input
322
- type={field.type === 'secret' ? 'password' : 'text'}
351
+ id={`bundle-credential-${field.key}`}
352
+ type="text"
323
353
  placeholder={field.placeholder}
324
354
  value={(credValues[field.key] as string) ?? ''}
325
355
  onChange={(e) => setCredValues((prev) => ({ ...prev, [field.key]: e.target.value }))}
326
356
  />
327
357
  )}
358
+ {field.type === 'secret' && secretFieldsConfigured[field.key] ? (
359
+ <p className="text-xs text-muted-foreground">
360
+ {t('integrations.detail.credentials.secretConfigured')}
361
+ </p>
362
+ ) : null}
328
363
  </div>
329
364
  ))}
330
365
  <Button type="button" onClick={() => void handleSaveCredentials()} disabled={isSavingCreds}>
@@ -0,0 +1,84 @@
1
+ import type { IntegrationCredentialField } from '@open-mercato/shared/modules/integrations/types'
2
+ import { SECRET_CREDENTIAL_FIELD_TYPES } from '../../lib/credentials-masking'
3
+
4
+ export type SecretFieldsConfigured = Record<string, boolean>
5
+
6
+ export type CredentialSavePayload = {
7
+ credentials: Record<string, unknown>
8
+ unchangedSecretFields?: string[]
9
+ }
10
+
11
+ export function buildCredentialEditValues(
12
+ credentials: Record<string, unknown>,
13
+ secretFieldsConfigured: SecretFieldsConfigured,
14
+ ): Record<string, unknown> {
15
+ const editValues = { ...credentials }
16
+
17
+ for (const [fieldKey, configured] of Object.entries(secretFieldsConfigured)) {
18
+ if (configured) delete editValues[fieldKey]
19
+ }
20
+
21
+ return editValues
22
+ }
23
+
24
+ export function buildCredentialSavePayload(
25
+ values: Record<string, unknown>,
26
+ fields: readonly IntegrationCredentialField[],
27
+ secretFieldsConfigured: SecretFieldsConfigured,
28
+ deliberatelyClearedSecretFields: ReadonlySet<string> = new Set(),
29
+ ): CredentialSavePayload {
30
+ const credentials = { ...values }
31
+ const unchangedSecretFields = new Set<string>()
32
+
33
+ for (const field of fields) {
34
+ if (!SECRET_CREDENTIAL_FIELD_TYPES.has(field.type)) continue
35
+
36
+ if (deliberatelyClearedSecretFields.has(field.key)) {
37
+ delete credentials[field.key]
38
+ continue
39
+ }
40
+
41
+ if (!secretFieldsConfigured[field.key]) continue
42
+ const value = credentials[field.key]
43
+ if (value !== undefined && value !== '') continue
44
+
45
+ delete credentials[field.key]
46
+ unchangedSecretFields.add(field.key)
47
+ }
48
+
49
+ return unchangedSecretFields.size > 0
50
+ ? { credentials, unchangedSecretFields: [...unchangedSecretFields] }
51
+ : { credentials }
52
+ }
53
+
54
+ export function buildIntegrationCredentialSavePayload(
55
+ integrationId: string,
56
+ values: Record<string, unknown>,
57
+ fields: readonly IntegrationCredentialField[],
58
+ secretFieldsConfigured: SecretFieldsConfigured,
59
+ ): CredentialSavePayload {
60
+ const normalizedValues = { ...values }
61
+ const deliberatelyClearedSecretFields = new Set<string>()
62
+
63
+ if (integrationId === 'storage_s3') {
64
+ const authMode = normalizedValues.authMode
65
+ if (authMode !== 'access_keys' && authMode !== 'ambient') {
66
+ const hasKeys = Boolean(normalizedValues.accessKeyId || normalizedValues.secretAccessKey)
67
+ normalizedValues.authMode = hasKeys ? 'access_keys' : 'ambient'
68
+ }
69
+ if (normalizedValues.authMode === 'ambient') {
70
+ delete normalizedValues.accessKeyId
71
+ delete normalizedValues.secretAccessKey
72
+ delete normalizedValues.sessionToken
73
+ deliberatelyClearedSecretFields.add('secretAccessKey')
74
+ deliberatelyClearedSecretFields.add('sessionToken')
75
+ }
76
+ }
77
+
78
+ return buildCredentialSavePayload(
79
+ normalizedValues,
80
+ fields,
81
+ secretFieldsConfigured,
82
+ deliberatelyClearedSecretFields,
83
+ )
84
+ }
@@ -1,13 +1,23 @@
1
1
  import { z } from 'zod'
2
2
 
3
+ const credentialFieldKeySchema = z.string().min(1).max(128)
4
+
3
5
  export const saveCredentialsSchema = z.object({
4
6
  credentials: z.record(
5
- z.string().min(1).max(128),
7
+ credentialFieldKeySchema,
6
8
  z.union([z.string().max(20_000), z.number(), z.boolean(), z.null()]),
7
9
  ),
10
+ unchangedSecretFields: z.array(credentialFieldKeySchema).max(200).optional(),
8
11
  }).refine((value) => Object.keys(value.credentials).length <= 200, {
9
12
  message: 'At most 200 credential fields are allowed',
10
- })
13
+ }).refine(
14
+ (value) => !value.unchangedSecretFields
15
+ || new Set(value.unchangedSecretFields).size === value.unchangedSecretFields.length,
16
+ {
17
+ message: 'Unchanged secret field names must be unique',
18
+ path: ['unchangedSecretFields'],
19
+ },
20
+ )
11
21
 
12
22
  export type SaveCredentialsInput = z.infer<typeof saveCredentialsSchema>
13
23
 
@@ -15,6 +15,7 @@
15
15
  "integrations.detail.credentials.save": "Zugangsdaten speichern",
16
16
  "integrations.detail.credentials.saveError": "Zugangsdaten konnten nicht gespeichert werden",
17
17
  "integrations.detail.credentials.saved": "Zugangsdaten gespeichert",
18
+ "integrations.detail.credentials.secretConfigured": "Konfiguriert. Geben Sie einen neuen Wert ein, um ihn zu ersetzen.",
18
19
  "integrations.detail.credentials.validation.boolean": "Select a valid value.",
19
20
  "integrations.detail.credentials.validation.option": "Select one of the available options.",
20
21
  "integrations.detail.credentials.validation.required": "{field} is required.",
@@ -15,6 +15,7 @@
15
15
  "integrations.detail.credentials.save": "Save Credentials",
16
16
  "integrations.detail.credentials.saveError": "Failed to save credentials",
17
17
  "integrations.detail.credentials.saved": "Credentials saved",
18
+ "integrations.detail.credentials.secretConfigured": "Configured. Enter a new value to replace it.",
18
19
  "integrations.detail.credentials.validation.boolean": "Select a valid value.",
19
20
  "integrations.detail.credentials.validation.option": "Select one of the available options.",
20
21
  "integrations.detail.credentials.validation.required": "{field} is required.",
@@ -15,6 +15,7 @@
15
15
  "integrations.detail.credentials.save": "Guardar credenciales",
16
16
  "integrations.detail.credentials.saveError": "No se pudieron guardar las credenciales",
17
17
  "integrations.detail.credentials.saved": "Credenciales guardadas",
18
+ "integrations.detail.credentials.secretConfigured": "Configurado. Introduce un valor nuevo para reemplazarlo.",
18
19
  "integrations.detail.credentials.validation.boolean": "Select a valid value.",
19
20
  "integrations.detail.credentials.validation.option": "Select one of the available options.",
20
21
  "integrations.detail.credentials.validation.required": "{field} is required.",
@@ -15,6 +15,7 @@
15
15
  "integrations.detail.credentials.save": "자격 증명 저장",
16
16
  "integrations.detail.credentials.saveError": "자격 증명 저장에 실패했습니다",
17
17
  "integrations.detail.credentials.saved": "자격 증명이 저장되었습니다",
18
+ "integrations.detail.credentials.secretConfigured": "구성됨. 바꾸려면 새 값을 입력하세요.",
18
19
  "integrations.detail.credentials.validation.boolean": "유효한 값을 선택하세요.",
19
20
  "integrations.detail.credentials.validation.option": "사용 가능한 옵션 중 하나를 선택하세요.",
20
21
  "integrations.detail.credentials.validation.required": "{field}은(는) 필수입니다.",
@@ -15,6 +15,7 @@
15
15
  "integrations.detail.credentials.save": "Zapisz dane",
16
16
  "integrations.detail.credentials.saveError": "Nie udało się zapisać danych",
17
17
  "integrations.detail.credentials.saved": "Dane zapisane",
18
+ "integrations.detail.credentials.secretConfigured": "Skonfigurowano. Wpisz nową wartość, aby ją zastąpić.",
18
19
  "integrations.detail.credentials.validation.boolean": "Select a valid value.",
19
20
  "integrations.detail.credentials.validation.option": "Select one of the available options.",
20
21
  "integrations.detail.credentials.validation.required": "{field} is required.",
@@ -84,22 +84,26 @@ export function maskSecretCredentials(
84
84
  }
85
85
 
86
86
  /**
87
- * Reverse of {@link maskSecretCredentials} for the save path. When the client
88
- * submits the mask sentinel for a secret field it means "leave it unchanged":
89
- * restore the existing stored secret, or drop the field entirely when nothing
90
- * was previously stored (so the literal sentinel is never persisted). Any other
91
- * value (including an empty string, which clears the secret) is written as-is.
87
+ * Reverse of {@link maskSecretCredentials} for the save path. The exact mask
88
+ * sentinel and explicitly listed omitted secret fields mean "leave unchanged".
89
+ * Explicit values win over the list, including an empty string used to clear a
90
+ * secret, while plain omission retains the full-replacement contract.
92
91
  */
93
92
  export function mergeMaskedSecretCredentials(
94
93
  schema: IntegrationCredentialsSchema | undefined,
95
94
  incoming: Record<string, unknown>,
96
95
  existing: Record<string, unknown>,
96
+ unchangedSecretFields: readonly string[] = [],
97
97
  ): Record<string, unknown> {
98
98
  const merged: Record<string, unknown> = { ...incoming }
99
+ const unchangedSecretFieldSet = new Set(unchangedSecretFields)
99
100
 
100
101
  for (const field of schema?.fields ?? []) {
101
102
  if (!isSecretField(field.type)) continue
102
- if (merged[field.key] !== MASKED_SECRET_VALUE) continue
103
+ const hasIncomingValue = Object.prototype.hasOwnProperty.call(merged, field.key)
104
+ const submittedMask = merged[field.key] === MASKED_SECRET_VALUE
105
+ const explicitlyUnchanged = !hasIncomingValue && unchangedSecretFieldSet.has(field.key)
106
+ if (!submittedMask && !explicitlyUnchanged) continue
103
107
 
104
108
  if (hasPresentValue(existing[field.key])) {
105
109
  merged[field.key] = existing[field.key]
@@ -2,6 +2,7 @@ import type { EntityManager } from '@mikro-orm/postgresql'
2
2
  import type { CommandBus } from '@open-mercato/shared/lib/commands/command-bus'
3
3
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'
4
4
  import { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
5
+ import { applyResponseEnricherToRecord } from '@open-mercato/shared/lib/crud/enricher-runner'
5
6
  import { enforceCommandOptimisticLock } from '@open-mercato/shared/lib/crud/optimistic-lock-command'
6
7
  import { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
7
8
  import { User } from '../../../auth/data/entities'
@@ -38,6 +39,36 @@ type MessageObjectPreviewPayload = {
38
39
  metadata?: Record<string, string>
39
40
  } | null
40
41
 
42
+ type RbacServiceLike = {
43
+ getGrantedFeatures?: (
44
+ userId: string,
45
+ scope: { tenantId: string | null; organizationId: string | null },
46
+ ) => Promise<string[]>
47
+ }
48
+
49
+ /**
50
+ * Feature list for the enricher ACL gate, resolved from RBAC.
51
+ *
52
+ * Mirrors `customers/api/interactions/route.ts`. Returning `undefined` on
53
+ * failure is deliberate — the runner then treats every feature-gated enricher
54
+ * as denied, which is the safe direction.
55
+ */
56
+ async function resolveGrantedFeatures(
57
+ container: { resolve: (name: string) => unknown },
58
+ scope: { tenantId: string; organizationId: string | null; userId: string },
59
+ ): Promise<string[] | undefined> {
60
+ try {
61
+ const rbac = container.resolve('rbacService') as RbacServiceLike | undefined
62
+ if (!rbac?.getGrantedFeatures) return undefined
63
+ return await rbac.getGrantedFeatures(scope.userId, {
64
+ tenantId: scope.tenantId,
65
+ organizationId: scope.organizationId,
66
+ })
67
+ } catch {
68
+ return undefined
69
+ }
70
+ }
71
+
41
72
  export async function GET(req: Request, { params }: { params: { id: string } }) {
42
73
  const { ctx, scope } = await resolveMessageContext(req)
43
74
  const em = ctx.container.resolve('em') as EntityManager
@@ -190,7 +221,7 @@ export async function GET(req: Request, { params }: { params: { id: string } })
190
221
  })
191
222
  }
192
223
 
193
- return Response.json({
224
+ const detail: Record<string, unknown> = {
194
225
  id: message.id,
195
226
  updatedAt: message.updatedAt ?? null,
196
227
  type: message.type,
@@ -257,6 +288,9 @@ export async function GET(req: Request, { params }: { params: { id: string } })
257
288
  senderUserId: threadMessage.senderUserId,
258
289
  senderName: threadSenderName,
259
290
  senderEmail: sender?.email ?? null,
291
+ externalName: threadMessage.externalName ?? null,
292
+ externalEmail: threadMessage.externalEmail ?? null,
293
+ sourceEntityType: threadMessage.sourceEntityType ?? null,
260
294
  body: threadMessage.body,
261
295
  bodyFormat: threadMessage.bodyFormat,
262
296
  sentAt: threadMessage.sentAt,
@@ -265,7 +299,27 @@ export async function GET(req: Request, { params }: { params: { id: string } })
265
299
  isRead: recipient ? (autoMarkRead || recipient.status !== 'unread') : true,
266
300
  conversationArchived,
267
301
  conversationAllUnread,
302
+ }
303
+
304
+ // Mirrors `enrichSingleRecord` in `shared/lib/crud/factory.ts`, which every
305
+ // `makeCrudRoute` host gets for free: same `_meta` envelope, and no blanket
306
+ // catch so a `critical: true` enricher still surfaces as an HTTP error.
307
+ // Non-critical failures never escape the runner — it merges `fallback` and
308
+ // records the id in `_meta.enricherErrors`.
309
+ const enriched = await applyResponseEnricherToRecord(detail, 'messages.message', {
310
+ organizationId: scope.organizationId ?? '',
311
+ tenantId: scope.tenantId,
312
+ userId: scope.userId,
313
+ em,
314
+ container: ctx.container,
315
+ userFeatures: await resolveGrantedFeatures(ctx.container, scope),
268
316
  })
317
+
318
+ if (enriched._meta.enrichedBy.length > 0 || enriched._meta.enricherErrors?.length) {
319
+ return Response.json({ ...enriched.record, _meta: enriched._meta })
320
+ }
321
+
322
+ return Response.json(enriched.record)
269
323
  }
270
324
 
271
325
  export async function PATCH(req: Request, { params }: { params: { id: string } }) {