@open-mercato/core 0.6.8-develop.7099.1.7ba2771d06 → 0.7.0

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 (941) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/helpers/integration/api.js +1 -13
  3. package/dist/helpers/integration/api.js.map +2 -2
  4. package/dist/helpers/integration/communicationChannelsFixtures.js +0 -19
  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 +1 -3
  9. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  10. package/dist/modules/attachments/api/route.js +2 -2
  11. package/dist/modules/attachments/api/route.js.map +2 -2
  12. package/dist/modules/attachments/components/AttachmentLibrary.js +0 -2
  13. package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
  14. package/dist/modules/attachments/di.js +1 -11
  15. package/dist/modules/attachments/di.js.map +2 -2
  16. package/dist/modules/attachments/index.js.map +1 -1
  17. package/dist/modules/attachments/lib/scoped-upload-service.js +2 -15
  18. package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
  19. package/dist/modules/attachments/lib/upload-limits.js +2 -6
  20. package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
  21. package/dist/modules/audit_logs/backend/audit-logs/page.js +0 -6
  22. package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
  23. package/dist/modules/audit_logs/lib/display-helpers.js +11 -19
  24. package/dist/modules/audit_logs/lib/display-helpers.js.map +2 -2
  25. package/dist/modules/audit_logs/services/actionLogService.js +12 -57
  26. package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
  27. package/dist/modules/auth/acl.js +5 -30
  28. package/dist/modules/auth/acl.js.map +2 -2
  29. package/dist/modules/auth/api/feature-check.js +2 -8
  30. package/dist/modules/auth/api/feature-check.js.map +2 -2
  31. package/dist/modules/auth/api/login.js +20 -4
  32. package/dist/modules/auth/api/login.js.map +2 -2
  33. package/dist/modules/auth/api/roles/acl/route.js +33 -28
  34. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  35. package/dist/modules/auth/api/routeError.js +11 -0
  36. package/dist/modules/auth/api/routeError.js.map +7 -0
  37. package/dist/modules/auth/api/session/refresh.js +1 -25
  38. package/dist/modules/auth/api/session/refresh.js.map +2 -2
  39. package/dist/modules/auth/api/users/acl/route.js +73 -102
  40. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  41. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js +1 -5
  42. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js.map +2 -2
  43. package/dist/modules/auth/backend/roles/page.js +1 -3
  44. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  45. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js +1 -5
  46. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js.map +2 -2
  47. package/dist/modules/auth/backend/users/page.js +1 -2
  48. package/dist/modules/auth/backend/users/page.js.map +2 -2
  49. package/dist/modules/auth/components/AclEditor.js +30 -39
  50. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  51. package/dist/modules/auth/data/entities.js.map +2 -2
  52. package/dist/modules/auth/data/validators.js +1 -5
  53. package/dist/modules/auth/data/validators.js.map +2 -2
  54. package/dist/modules/auth/di.js +9 -35
  55. package/dist/modules/auth/di.js.map +2 -2
  56. package/dist/modules/auth/frontend/reset/[token]/page.js +0 -46
  57. package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
  58. package/dist/modules/auth/lib/grantChecks.js.map +2 -2
  59. package/dist/modules/auth/services/authService.js +2 -16
  60. package/dist/modules/auth/services/authService.js.map +2 -2
  61. package/dist/modules/auth/services/rbacService.js +24 -67
  62. package/dist/modules/auth/services/rbacService.js.map +3 -3
  63. package/dist/modules/business_rules/backend/logs/page.js +1 -3
  64. package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
  65. package/dist/modules/business_rules/backend/rules/[id]/page.meta.js +6 -1
  66. package/dist/modules/business_rules/backend/rules/[id]/page.meta.js.map +2 -2
  67. package/dist/modules/business_rules/backend/rules/create/page.meta.js +5 -1
  68. package/dist/modules/business_rules/backend/rules/create/page.meta.js.map +2 -2
  69. package/dist/modules/business_rules/backend/rules/page.js +1 -3
  70. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  71. package/dist/modules/business_rules/backend/sets/[id]/page.meta.js +6 -1
  72. package/dist/modules/business_rules/backend/sets/[id]/page.meta.js.map +2 -2
  73. package/dist/modules/business_rules/backend/sets/create/page.meta.js +5 -1
  74. package/dist/modules/business_rules/backend/sets/create/page.meta.js.map +2 -2
  75. package/dist/modules/business_rules/backend/sets/page.js +1 -3
  76. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  77. package/dist/modules/business_rules/lib/expression-evaluator.js +9 -9
  78. package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
  79. package/dist/modules/business_rules/lib/rule-evaluator.js +9 -10
  80. package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
  81. package/dist/modules/catalog/ai-agents.js +1 -1
  82. package/dist/modules/catalog/ai-agents.js.map +1 -1
  83. package/dist/modules/catalog/ai-tools/merchandising-pack.js +2 -2
  84. package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
  85. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +2 -5
  86. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
  87. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +0 -2
  88. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  89. package/dist/modules/catalog/components/products/ProductsDataTable.js +1 -7
  90. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  91. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js +0 -2
  92. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js.map +2 -2
  93. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +1 -9
  94. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +2 -2
  95. package/dist/modules/communication_channels/api/post/test-seed/route.js +10 -95
  96. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  97. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +0 -3
  98. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
  99. package/dist/modules/communication_channels/commands/ingest-inbound-message.js +1 -14
  100. package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
  101. package/dist/modules/communication_channels/di.js +1 -7
  102. package/dist/modules/communication_channels/di.js.map +2 -2
  103. package/dist/modules/communication_channels/lib/email-capabilities.js +1 -4
  104. package/dist/modules/communication_channels/lib/email-capabilities.js.map +2 -2
  105. package/dist/modules/communication_channels/lib/test-seed.js +2 -41
  106. package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
  107. package/dist/modules/configs/lib/system-status.js +0 -9
  108. package/dist/modules/configs/lib/system-status.js.map +2 -2
  109. package/dist/modules/currencies/backend/currencies/page.js +1 -3
  110. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  111. package/dist/modules/currencies/backend/exchange-rates/page.js +1 -3
  112. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  113. package/dist/modules/customer_accounts/api/admin/domain-mappings.js +0 -9
  114. package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +2 -2
  115. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +1 -3
  116. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  117. package/dist/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.js +84 -0
  118. package/dist/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.js.map +7 -0
  119. package/dist/modules/customer_accounts/backend/customer_accounts/settings/page.js +7 -81
  120. package/dist/modules/customer_accounts/backend/customer_accounts/settings/page.js.map +2 -2
  121. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +523 -0
  122. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +7 -0
  123. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.js +731 -0
  124. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.js.map +7 -0
  125. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +7 -727
  126. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  127. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +7 -521
  128. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  129. package/dist/modules/customer_accounts/extension-points.js +1 -1
  130. package/dist/modules/customer_accounts/extension-points.js.map +2 -2
  131. package/dist/modules/customer_accounts/lib/portalUrl.js +69 -0
  132. package/dist/modules/customer_accounts/lib/portalUrl.js.map +7 -0
  133. package/dist/modules/customer_accounts/services/domainMappingService.js +0 -10
  134. package/dist/modules/customer_accounts/services/domainMappingService.js.map +2 -2
  135. package/dist/modules/customers/ai-tools/companies-pack.js +1 -4
  136. package/dist/modules/customers/ai-tools/companies-pack.js.map +2 -2
  137. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +2 -13
  138. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +2 -2
  139. package/dist/modules/customers/ai-tools/deals-pack.js +6 -52
  140. package/dist/modules/customers/ai-tools/deals-pack.js.map +2 -2
  141. package/dist/modules/customers/ai-tools/people-pack.js +1 -4
  142. package/dist/modules/customers/ai-tools/people-pack.js.map +2 -2
  143. package/dist/modules/customers/api/activities/route.js +6 -48
  144. package/dist/modules/customers/api/activities/route.js.map +2 -2
  145. package/dist/modules/customers/api/companies/[id]/people/route.js +64 -20
  146. package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
  147. package/dist/modules/customers/api/companies/[id]/route.js +94 -17
  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 +5 -8
  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 +25 -8
  156. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  157. package/dist/modules/customers/api/deals/[id]/stats/route.js +22 -3
  158. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +2 -2
  159. package/dist/modules/customers/api/deals/aggregate/route.js +4 -11
  160. package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
  161. package/dist/modules/customers/api/deals/map/route.js +1 -2
  162. package/dist/modules/customers/api/deals/map/route.js.map +2 -2
  163. package/dist/modules/customers/api/deals/route.js +1 -38
  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 +1 -3
  168. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  169. package/dist/modules/customers/api/interactions/tasks/route.js +4 -27
  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 +3 -4
  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 +10 -11
  178. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  179. package/dist/modules/customers/api/people/check-phone/route.js +9 -51
  180. package/dist/modules/customers/api/people/check-phone/route.js.map +2 -2
  181. package/dist/modules/customers/api/todos/route.js +5 -30
  182. package/dist/modules/customers/api/todos/route.js.map +2 -2
  183. package/dist/modules/customers/backend/customers/companies/page.js +4 -6
  184. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  185. package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -6
  186. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  187. package/dist/modules/customers/backend/customers/deals/page.js +4 -7
  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 +13 -4
  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 +14 -85
  192. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js.map +2 -2
  193. package/dist/modules/customers/backend/customers/people/page.js +4 -6
  194. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  195. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js +3 -9
  196. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js.map +2 -2
  197. package/dist/modules/customers/commands/deals.js +34 -21
  198. package/dist/modules/customers/commands/deals.js.map +2 -2
  199. package/dist/modules/customers/commands/interactions.js.map +1 -1
  200. package/dist/modules/customers/commands/personCompanyLinks.js +2 -131
  201. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  202. package/dist/modules/customers/components/CustomerTodosTable.js +0 -1
  203. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  204. package/dist/modules/customers/components/DealsKpiStrip.js +6 -7
  205. package/dist/modules/customers/components/DealsKpiStrip.js.map +2 -2
  206. package/dist/modules/customers/components/calendar/AgendaList.js +2 -2
  207. package/dist/modules/customers/components/calendar/AgendaList.js.map +2 -2
  208. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -1
  209. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
  210. package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
  211. package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
  212. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +1 -1
  213. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
  214. package/dist/modules/customers/components/calendar/EventBlock.js +1 -1
  215. package/dist/modules/customers/components/calendar/EventBlock.js.map +2 -2
  216. package/dist/modules/customers/components/calendar/EventPeekPopover.js +2 -3
  217. package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +2 -2
  218. package/dist/modules/customers/components/calendar/editor/PeopleField.js +5 -40
  219. package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
  220. package/dist/modules/customers/components/calendar/editor/hooks.js +1 -2
  221. package/dist/modules/customers/components/calendar/editor/hooks.js.map +2 -2
  222. package/dist/modules/customers/components/calendar/types.js +1 -1
  223. package/dist/modules/customers/components/calendar/types.js.map +2 -2
  224. package/dist/modules/customers/components/detail/AssignRoleDialog.js +33 -28
  225. package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +2 -2
  226. package/dist/modules/customers/components/detail/CompanyKpiBar.js +4 -5
  227. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
  228. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +1 -3
  229. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  230. package/dist/modules/customers/components/detail/DealForm.js +7 -19
  231. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  232. package/dist/modules/customers/components/detail/DealsSection.js +5 -6
  233. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  234. package/dist/modules/customers/components/detail/EntityTagsDialog.js +11 -35
  235. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  236. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +1 -3
  237. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
  238. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +13 -19
  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 +3 -32
  248. package/dist/modules/customers/data/validators.js.map +2 -2
  249. package/dist/modules/customers/events.js +0 -5
  250. package/dist/modules/customers/events.js.map +2 -2
  251. package/dist/modules/customers/lib/calendar/conflicts.js +2 -8
  252. package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
  253. package/dist/modules/customers/lib/calendar/editorPayload.js +2 -3
  254. package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
  255. package/dist/modules/customers/lib/calendar/mapItem.js +3 -8
  256. package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
  257. package/dist/modules/customers/lib/dealStatus.js +0 -30
  258. package/dist/modules/customers/lib/dealStatus.js.map +2 -2
  259. package/dist/modules/customers/lib/findPeopleByAddresses.js +0 -1
  260. package/dist/modules/customers/lib/findPeopleByAddresses.js.map +2 -2
  261. package/dist/modules/customers/lib/personCompanies.js +2 -100
  262. package/dist/modules/customers/lib/personCompanies.js.map +2 -2
  263. package/dist/modules/customers/lib/todoCompatibility.js +0 -12
  264. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  265. package/dist/modules/dashboards/lib/widgetScope.js +1 -6
  266. package/dist/modules/dashboards/lib/widgetScope.js.map +2 -2
  267. package/dist/modules/data_sync/backend/data-sync/page.js +1 -3
  268. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  269. package/dist/modules/data_sync/lib/sync-engine.js +6 -72
  270. package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
  271. package/dist/modules/data_sync/workers/sync-export.js +1 -5
  272. package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
  273. package/dist/modules/data_sync/workers/sync-import.js +1 -5
  274. package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
  275. package/dist/modules/devices/api/admin/devices/[id]/route.js +32 -5
  276. package/dist/modules/devices/api/admin/devices/[id]/route.js.map +2 -2
  277. package/dist/modules/devices/api/admin/devices/route.js +1 -14
  278. package/dist/modules/devices/api/admin/devices/route.js.map +2 -2
  279. package/dist/modules/devices/api/deviceList.js +12 -99
  280. package/dist/modules/devices/api/deviceList.js.map +2 -2
  281. package/dist/modules/devices/api/openapi.js +1 -3
  282. package/dist/modules/devices/api/openapi.js.map +2 -2
  283. package/dist/modules/devices/api/route.js +1 -9
  284. package/dist/modules/devices/api/route.js.map +2 -2
  285. package/dist/modules/devices/backend/devices/[id]/page.js +8 -8
  286. package/dist/modules/devices/backend/devices/[id]/page.js.map +2 -2
  287. package/dist/modules/devices/backend/devices/page.js +13 -15
  288. package/dist/modules/devices/backend/devices/page.js.map +2 -2
  289. package/dist/modules/directory/backend/directory/organizations/page.js +1 -2
  290. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  291. package/dist/modules/directory/backend/directory/tenants/page.js +1 -2
  292. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  293. package/dist/modules/directory/di.js +0 -9
  294. package/dist/modules/directory/di.js.map +2 -2
  295. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  296. package/dist/modules/entities/api/records.js +2 -4
  297. package/dist/modules/entities/api/records.js.map +2 -2
  298. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +1 -3
  299. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  300. package/dist/modules/eudr/api/plots/route.js +1 -5
  301. package/dist/modules/eudr/api/plots/route.js.map +2 -2
  302. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js +3 -1
  303. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js.map +2 -2
  304. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js +1 -0
  305. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js.map +2 -2
  306. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +0 -3
  307. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
  308. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js +4 -1
  309. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js.map +2 -2
  310. package/dist/modules/eudr/backend/eudr/page.meta.js +2 -2
  311. package/dist/modules/eudr/backend/eudr/page.meta.js.map +2 -2
  312. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js +8 -2
  313. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js.map +2 -2
  314. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js +3 -1
  315. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js.map +2 -2
  316. package/dist/modules/eudr/backend/eudr/plots/create/page.js +8 -2
  317. package/dist/modules/eudr/backend/eudr/plots/create/page.js.map +2 -2
  318. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js +1 -0
  319. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js.map +2 -2
  320. package/dist/modules/eudr/backend/eudr/plots/page.js +0 -3
  321. package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
  322. package/dist/modules/eudr/backend/eudr/plots/page.meta.js +4 -1
  323. package/dist/modules/eudr/backend/eudr/plots/page.meta.js.map +2 -2
  324. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js +3 -1
  325. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js.map +2 -2
  326. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js +1 -0
  327. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js.map +2 -2
  328. package/dist/modules/eudr/backend/eudr/product-mappings/page.js +0 -3
  329. package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
  330. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js +4 -1
  331. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js.map +2 -2
  332. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js +3 -1
  333. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js.map +2 -2
  334. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js +1 -0
  335. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js.map +2 -2
  336. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +0 -3
  337. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
  338. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js +4 -1
  339. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js.map +2 -2
  340. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js +2 -0
  341. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js.map +2 -2
  342. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js +3 -1
  343. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js.map +2 -2
  344. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js +1 -0
  345. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js.map +2 -2
  346. package/dist/modules/eudr/backend/eudr/statements/page.js +30 -28
  347. package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
  348. package/dist/modules/eudr/backend/eudr/statements/page.meta.js +4 -1
  349. package/dist/modules/eudr/backend/eudr/statements/page.meta.js.map +2 -2
  350. package/dist/modules/eudr/commands/statements.js +8 -3
  351. package/dist/modules/eudr/commands/statements.js.map +2 -2
  352. package/dist/modules/eudr/components/crudErrorI18n.js +21 -1
  353. package/dist/modules/eudr/components/crudErrorI18n.js.map +2 -2
  354. package/dist/modules/eudr/components/formConfig.js +6 -2
  355. package/dist/modules/eudr/components/formConfig.js.map +2 -2
  356. package/dist/modules/eudr/data/validators.js +1 -4
  357. package/dist/modules/eudr/data/validators.js.map +2 -2
  358. package/dist/modules/eudr/lib/statement-lifecycle.js +9 -1
  359. package/dist/modules/eudr/lib/statement-lifecycle.js.map +2 -2
  360. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +0 -1
  361. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  362. package/dist/modules/feature_toggles/components/OverridesTable.js +0 -1
  363. package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
  364. package/dist/modules/feature_toggles/defaults.json +8 -0
  365. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +0 -3
  366. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
  367. package/dist/modules/inbox_ops/backend/inbox-ops/page.js +0 -3
  368. package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
  369. package/dist/modules/inbox_ops/lib/htmlToPlainText.js +12 -1
  370. package/dist/modules/inbox_ops/lib/htmlToPlainText.js.map +2 -2
  371. package/dist/modules/integrations/api/[id]/credentials/route.js +1 -6
  372. package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
  373. package/dist/modules/integrations/backend/integrations/[id]/page.js +29 -38
  374. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  375. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +9 -36
  376. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  377. package/dist/modules/integrations/data/validators.js +3 -11
  378. package/dist/modules/integrations/data/validators.js.map +2 -2
  379. package/dist/modules/integrations/lib/credentials-masking.js +2 -6
  380. package/dist/modules/integrations/lib/credentials-masking.js.map +2 -2
  381. package/dist/modules/messages/api/[id]/route.js +1 -29
  382. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  383. package/dist/modules/messages/api/openapi.js +2 -17
  384. package/dist/modules/messages/api/openapi.js.map +2 -2
  385. package/dist/modules/messages/api/route.js +2 -17
  386. package/dist/modules/messages/api/route.js.map +2 -2
  387. package/dist/modules/messages/components/MessagesInboxPageClient.js +14 -7
  388. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  389. package/dist/modules/messages/components/inboxFilters.js +0 -15
  390. package/dist/modules/messages/components/inboxFilters.js.map +2 -2
  391. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +1 -11
  392. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +2 -2
  393. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +1 -3
  394. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +2 -2
  395. package/dist/modules/messages/components/message-detail/panels/thread-panel.js +1 -2
  396. package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +2 -2
  397. package/dist/modules/messages/components/messageListLabels.js +2 -14
  398. package/dist/modules/messages/components/messageListLabels.js.map +2 -2
  399. package/dist/modules/messages/data/validators.js +4 -18
  400. package/dist/modules/messages/data/validators.js.map +2 -2
  401. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +6 -4
  402. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
  403. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +1 -3
  404. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  405. package/dist/modules/payment_gateways/lib/webhook-processor.js +0 -7
  406. package/dist/modules/payment_gateways/lib/webhook-processor.js.map +2 -2
  407. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +0 -3
  408. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  409. package/dist/modules/push_notifications/backend/push_notifications/page.js +1 -3
  410. package/dist/modules/push_notifications/backend/push_notifications/page.js.map +2 -2
  411. package/dist/modules/push_notifications/backend/push_notifications/send/page.js +1 -1
  412. package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +2 -2
  413. package/dist/modules/query_index/lib/engine.js +51 -150
  414. package/dist/modules/query_index/lib/engine.js.map +2 -2
  415. package/dist/modules/query_index/lib/search-tokens.js +3 -79
  416. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  417. package/dist/modules/resources/backend/resources/resource-types/page.js +1 -3
  418. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  419. package/dist/modules/resources/backend/resources/resources/page.js +1 -3
  420. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  421. package/dist/modules/sales/backend/sales/channels/offers/page.js +0 -3
  422. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  423. package/dist/modules/sales/backend/sales/channels/page.js +0 -3
  424. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  425. package/dist/modules/sales/backend/sales/documents/[id]/page.js +8 -10
  426. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  427. package/dist/modules/sales/commands/documents.js +1 -79
  428. package/dist/modules/sales/commands/documents.js.map +2 -2
  429. package/dist/modules/sales/components/PriceWithCurrency.js +5 -7
  430. package/dist/modules/sales/components/PriceWithCurrency.js.map +2 -2
  431. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +0 -3
  432. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  433. package/dist/modules/sales/components/documents/AdjustmentsSection.js +6 -8
  434. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  435. package/dist/modules/sales/components/documents/ItemsSection.js +22 -51
  436. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  437. package/dist/modules/sales/components/documents/LineItemDialog.js +19 -84
  438. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  439. package/dist/modules/sales/components/documents/PaymentsSection.js +9 -23
  440. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  441. package/dist/modules/sales/components/documents/ReturnsSection.js +6 -8
  442. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  443. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +14 -68
  444. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  445. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +5 -6
  446. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +2 -2
  447. package/dist/modules/sales/components/documents/ShipmentDialog.js +4 -5
  448. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  449. package/dist/modules/sales/components/documents/ShipmentsSection.js +6 -8
  450. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  451. package/dist/modules/sales/components/documents/lineItemUtils.js +2 -2
  452. package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
  453. package/dist/modules/sales/data/entities.js +2 -8
  454. package/dist/modules/sales/data/entities.js.map +2 -2
  455. package/dist/modules/sales/extension-points.js +0 -1
  456. package/dist/modules/sales/extension-points.js.map +2 -2
  457. package/dist/modules/sales/setup.js +0 -2
  458. package/dist/modules/sales/setup.js.map +2 -2
  459. package/dist/modules/sales/widgets/injection/document-history/widget.client.js +44 -2
  460. package/dist/modules/sales/widgets/injection/document-history/widget.client.js.map +2 -2
  461. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +2 -10
  462. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +2 -2
  463. package/dist/modules/sales/widgets/injection-table.js +7 -4
  464. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  465. package/dist/modules/staff/backend/staff/leave-requests/page.js +0 -3
  466. package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
  467. package/dist/modules/staff/backend/staff/my-leave-requests/page.js +0 -3
  468. package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
  469. package/dist/modules/staff/backend/staff/team-members/page.js +0 -3
  470. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  471. package/dist/modules/staff/backend/staff/team-roles/page.js +0 -3
  472. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  473. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +0 -3
  474. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  475. package/dist/modules/staff/backend/staff/teams/page.js +0 -3
  476. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  477. package/dist/modules/staff/backend/staff/timesheets/page.js +18 -29
  478. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  479. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +0 -3
  480. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  481. package/dist/modules/sync_excel/lib/adapters/customers.js +0 -1
  482. package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
  483. package/dist/modules/warranty_claims/api/assignees/route.js +3 -3
  484. package/dist/modules/warranty_claims/api/assignees/route.js.map +2 -2
  485. package/dist/modules/warranty_claims/api/portal/attachments/route.js +2 -2
  486. package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
  487. package/dist/modules/warranty_claims/api/portal/claims/route.js +9 -12
  488. package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
  489. package/dist/modules/warranty_claims/backend/page.js +0 -3
  490. package/dist/modules/warranty_claims/backend/page.js.map +2 -2
  491. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js +0 -3
  492. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js.map +2 -2
  493. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js +0 -3
  494. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map +2 -2
  495. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js +0 -3
  496. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js.map +2 -2
  497. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +0 -3
  498. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
  499. package/dist/modules/wms/api/warehouses/route.js +9 -13
  500. package/dist/modules/wms/api/warehouses/route.js.map +2 -2
  501. package/dist/modules/wms/api/zones/route.js +2 -15
  502. package/dist/modules/wms/api/zones/route.js.map +2 -2
  503. package/dist/modules/wms/commands/configuration.js +9 -121
  504. package/dist/modules/wms/commands/configuration.js.map +2 -2
  505. package/dist/modules/wms/commands/inventory-actions.js +0 -3
  506. package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
  507. package/dist/modules/wms/commands/shared.js +1 -9
  508. package/dist/modules/wms/commands/shared.js.map +2 -2
  509. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +111 -76
  510. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +3 -3
  511. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +0 -1
  512. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
  513. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +20 -16
  514. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  515. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +10 -6
  516. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  517. package/dist/modules/wms/components/backend/WmsLotsListPage.js +0 -1
  518. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
  519. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +11 -7
  520. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +2 -2
  521. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +10 -6
  522. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  523. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +20 -27
  524. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
  525. package/dist/modules/workflows/backend/definitions/page.js +1 -3
  526. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  527. package/dist/modules/workflows/backend/events/page.js +1 -3
  528. package/dist/modules/workflows/backend/events/page.js.map +2 -2
  529. package/dist/modules/workflows/backend/instances/page.js +1 -3
  530. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  531. package/dist/modules/workflows/backend/tasks/page.js +1 -3
  532. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  533. package/dist/modules/workflows/lib/activity-executor.js +0 -4
  534. package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
  535. package/package.json +10 -9
  536. package/src/helpers/integration/api.ts +1 -33
  537. package/src/helpers/integration/communicationChannelsFixtures.ts +1 -69
  538. package/src/modules/api_keys/api/keys/route.ts +1 -3
  539. package/src/modules/api_keys/backend/api-keys/page.tsx +1 -4
  540. package/src/modules/attachments/AGENTS.md +0 -15
  541. package/src/modules/attachments/api/route.ts +2 -2
  542. package/src/modules/attachments/components/AttachmentLibrary.tsx +0 -3
  543. package/src/modules/attachments/di.ts +0 -16
  544. package/src/modules/attachments/i18n/de.json +0 -5
  545. package/src/modules/attachments/i18n/en.json +0 -5
  546. package/src/modules/attachments/i18n/es.json +0 -5
  547. package/src/modules/attachments/i18n/ko.json +0 -5
  548. package/src/modules/attachments/i18n/pl.json +0 -5
  549. package/src/modules/attachments/index.ts +0 -10
  550. package/src/modules/attachments/lib/scoped-upload-service.ts +0 -46
  551. package/src/modules/attachments/lib/upload-limits.ts +2 -6
  552. package/src/modules/audit_logs/backend/audit-logs/page.tsx +0 -8
  553. package/src/modules/audit_logs/lib/display-helpers.tsx +32 -42
  554. package/src/modules/audit_logs/services/actionLogService.ts +11 -74
  555. package/src/modules/auth/acl.ts +6 -30
  556. package/src/modules/auth/api/feature-check.ts +3 -10
  557. package/src/modules/auth/api/login.ts +24 -9
  558. package/src/modules/auth/api/roles/acl/route.ts +39 -42
  559. package/src/modules/auth/api/routeError.ts +30 -0
  560. package/src/modules/auth/api/session/refresh.ts +1 -32
  561. package/src/modules/auth/api/users/acl/route.ts +101 -185
  562. package/src/modules/auth/backend/roles/[id]/edit/page.meta.ts +2 -5
  563. package/src/modules/auth/backend/roles/page.tsx +2 -4
  564. package/src/modules/auth/backend/users/[id]/edit/page.meta.ts +2 -5
  565. package/src/modules/auth/backend/users/page.tsx +2 -3
  566. package/src/modules/auth/components/AclEditor.tsx +33 -63
  567. package/src/modules/auth/data/entities.ts +1 -4
  568. package/src/modules/auth/data/validators.ts +0 -5
  569. package/src/modules/auth/di.ts +16 -46
  570. package/src/modules/auth/frontend/reset/[token]/page.tsx +0 -74
  571. package/src/modules/auth/i18n/de.json +0 -389
  572. package/src/modules/auth/i18n/en.json +0 -389
  573. package/src/modules/auth/i18n/es.json +0 -389
  574. package/src/modules/auth/i18n/ko.json +0 -389
  575. package/src/modules/auth/i18n/pl.json +2 -391
  576. package/src/modules/auth/lib/grantChecks.ts +0 -6
  577. package/src/modules/auth/services/authService.ts +2 -18
  578. package/src/modules/auth/services/rbacService.ts +24 -110
  579. package/src/modules/business_rules/backend/logs/page.tsx +1 -4
  580. package/src/modules/business_rules/backend/rules/[id]/page.meta.ts +5 -0
  581. package/src/modules/business_rules/backend/rules/create/page.meta.ts +5 -1
  582. package/src/modules/business_rules/backend/rules/page.tsx +1 -4
  583. package/src/modules/business_rules/backend/sets/[id]/page.meta.ts +5 -0
  584. package/src/modules/business_rules/backend/sets/create/page.meta.ts +5 -1
  585. package/src/modules/business_rules/backend/sets/page.tsx +1 -4
  586. package/src/modules/business_rules/lib/expression-evaluator.ts +9 -9
  587. package/src/modules/business_rules/lib/rule-evaluator.ts +9 -10
  588. package/src/modules/catalog/ai-agents.ts +1 -1
  589. package/src/modules/catalog/ai-tools/merchandising-pack.ts +2 -2
  590. package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +5 -12
  591. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +0 -3
  592. package/src/modules/catalog/components/products/ProductsDataTable.tsx +0 -7
  593. package/src/modules/catalog/i18n/de.json +0 -1
  594. package/src/modules/catalog/i18n/en.json +0 -1
  595. package/src/modules/catalog/i18n/es.json +0 -1
  596. package/src/modules/catalog/i18n/ko.json +0 -1
  597. package/src/modules/catalog/i18n/pl.json +0 -1
  598. package/src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx +0 -4
  599. package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +1 -17
  600. package/src/modules/communication_channels/api/post/test-seed/route.ts +16 -155
  601. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +0 -4
  602. package/src/modules/communication_channels/commands/ingest-inbound-message.ts +1 -38
  603. package/src/modules/communication_channels/di.ts +0 -7
  604. package/src/modules/communication_channels/lib/adapter.ts +0 -14
  605. package/src/modules/communication_channels/lib/email-capabilities.ts +0 -4
  606. package/src/modules/communication_channels/lib/test-seed.ts +4 -64
  607. package/src/modules/configs/i18n/de.json +0 -2
  608. package/src/modules/configs/i18n/en.json +0 -2
  609. package/src/modules/configs/i18n/es.json +0 -2
  610. package/src/modules/configs/i18n/ko.json +0 -2
  611. package/src/modules/configs/i18n/pl.json +0 -2
  612. package/src/modules/configs/lib/system-status.ts +0 -9
  613. package/src/modules/currencies/backend/currencies/page.tsx +1 -4
  614. package/src/modules/currencies/backend/exchange-rates/page.tsx +1 -4
  615. package/src/modules/customer_accounts/api/admin/domain-mappings.ts +0 -7
  616. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +1 -4
  617. package/src/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.tsx +138 -0
  618. package/src/modules/customer_accounts/backend/customer_accounts/settings/page.tsx +8 -132
  619. package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +598 -0
  620. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.tsx +838 -0
  621. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +6 -838
  622. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +6 -590
  623. package/src/modules/customer_accounts/extension-points.ts +1 -1
  624. package/src/modules/customer_accounts/lib/portalUrl.ts +112 -0
  625. package/src/modules/customer_accounts/services/domainMappingService.ts +0 -10
  626. package/src/modules/customers/ai-tools/companies-pack.ts +1 -4
  627. package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +2 -17
  628. package/src/modules/customers/ai-tools/deals-pack.ts +1 -66
  629. package/src/modules/customers/ai-tools/people-pack.ts +1 -4
  630. package/src/modules/customers/api/activities/route.ts +0 -45
  631. package/src/modules/customers/api/companies/[id]/people/route.ts +73 -24
  632. package/src/modules/customers/api/companies/[id]/route.ts +107 -24
  633. package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +8 -16
  634. package/src/modules/customers/api/deals/[id]/companies/route.ts +1 -4
  635. package/src/modules/customers/api/deals/[id]/people/route.ts +1 -4
  636. package/src/modules/customers/api/deals/[id]/route.ts +28 -17
  637. package/src/modules/customers/api/deals/[id]/stats/route.ts +25 -10
  638. package/src/modules/customers/api/deals/aggregate/route.ts +4 -14
  639. package/src/modules/customers/api/deals/map/route.ts +0 -1
  640. package/src/modules/customers/api/deals/route.ts +1 -50
  641. package/src/modules/customers/api/entity-roles-factory.ts +4 -8
  642. package/src/modules/customers/api/interactions/route.ts +2 -8
  643. package/src/modules/customers/api/interactions/tasks/route.ts +1 -24
  644. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +4 -12
  645. package/src/modules/customers/api/people/[id]/companies/context.ts +1 -4
  646. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +1 -4
  647. package/src/modules/customers/api/people/[id]/route.ts +11 -16
  648. package/src/modules/customers/api/people/check-phone/route.ts +10 -75
  649. package/src/modules/customers/api/todos/route.ts +2 -27
  650. package/src/modules/customers/backend/customers/companies/page.tsx +4 -7
  651. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +2 -7
  652. package/src/modules/customers/backend/customers/deals/page.tsx +4 -10
  653. package/src/modules/customers/backend/customers/deals/pipeline/components/Lane.tsx +14 -5
  654. package/src/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.tsx +27 -109
  655. package/src/modules/customers/backend/customers/people/page.tsx +4 -7
  656. package/src/modules/customers/backend/hooks/useEmailDuplicateCheck.ts +4 -12
  657. package/src/modules/customers/commands/deals.ts +59 -34
  658. package/src/modules/customers/commands/interactions.ts +1 -1
  659. package/src/modules/customers/commands/personCompanyLinks.ts +8 -224
  660. package/src/modules/customers/components/CustomerTodosTable.tsx +0 -2
  661. package/src/modules/customers/components/DealsKpiStrip.tsx +7 -7
  662. package/src/modules/customers/components/calendar/AgendaList.tsx +3 -3
  663. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -1
  664. package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
  665. package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +1 -1
  666. package/src/modules/customers/components/calendar/EventBlock.tsx +2 -2
  667. package/src/modules/customers/components/calendar/EventPeekPopover.tsx +2 -4
  668. package/src/modules/customers/components/calendar/editor/PeopleField.tsx +5 -61
  669. package/src/modules/customers/components/calendar/editor/hooks.ts +1 -7
  670. package/src/modules/customers/components/calendar/types.ts +2 -2
  671. package/src/modules/customers/components/detail/AssignRoleDialog.tsx +12 -7
  672. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +4 -5
  673. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +1 -8
  674. package/src/modules/customers/components/detail/DealForm.tsx +2 -22
  675. package/src/modules/customers/components/detail/DealsSection.tsx +5 -11
  676. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +12 -58
  677. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +1 -8
  678. package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +14 -23
  679. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +5 -5
  680. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +5 -5
  681. package/src/modules/customers/components/detail/types.ts +1 -1
  682. package/src/modules/customers/components/detail/utils.ts +5 -15
  683. package/src/modules/customers/data/entities.ts +1 -1
  684. package/src/modules/customers/data/validators.ts +9 -50
  685. package/src/modules/customers/events.ts +0 -5
  686. package/src/modules/customers/i18n/de.json +1 -9
  687. package/src/modules/customers/i18n/en.json +1 -9
  688. package/src/modules/customers/i18n/es.json +1 -9
  689. package/src/modules/customers/i18n/ko.json +1 -9
  690. package/src/modules/customers/i18n/pl.json +1 -9
  691. package/src/modules/customers/lib/calendar/conflicts.ts +2 -10
  692. package/src/modules/customers/lib/calendar/editorPayload.ts +3 -4
  693. package/src/modules/customers/lib/calendar/mapItem.ts +3 -8
  694. package/src/modules/customers/lib/dealStatus.ts +0 -42
  695. package/src/modules/customers/lib/findPeopleByAddresses.ts +6 -8
  696. package/src/modules/customers/lib/personCompanies.ts +1 -136
  697. package/src/modules/customers/lib/todoCompatibility.ts +1 -19
  698. package/src/modules/dashboards/i18n/es.json +4 -4
  699. package/src/modules/dashboards/i18n/pl.json +7 -7
  700. package/src/modules/dashboards/lib/widgetScope.ts +0 -6
  701. package/src/modules/data_sync/AGENTS.md +1 -1
  702. package/src/modules/data_sync/backend/data-sync/page.tsx +1 -4
  703. package/src/modules/data_sync/lib/adapter.ts +0 -36
  704. package/src/modules/data_sync/lib/sync-engine.ts +5 -113
  705. package/src/modules/data_sync/workers/sync-export.ts +0 -4
  706. package/src/modules/data_sync/workers/sync-import.ts +0 -4
  707. package/src/modules/devices/AGENTS.md +0 -8
  708. package/src/modules/devices/api/admin/devices/[id]/route.ts +34 -5
  709. package/src/modules/devices/api/admin/devices/route.ts +1 -14
  710. package/src/modules/devices/api/deviceList.ts +11 -135
  711. package/src/modules/devices/api/openapi.ts +1 -9
  712. package/src/modules/devices/api/route.ts +1 -9
  713. package/src/modules/devices/backend/devices/[id]/page.tsx +15 -15
  714. package/src/modules/devices/backend/devices/page.tsx +21 -24
  715. package/src/modules/directory/backend/directory/organizations/page.tsx +1 -3
  716. package/src/modules/directory/backend/directory/tenants/page.tsx +1 -3
  717. package/src/modules/directory/di.ts +2 -14
  718. package/src/modules/directory/utils/organizationScope.ts +15 -4
  719. package/src/modules/entities/api/records.ts +0 -2
  720. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +1 -4
  721. package/src/modules/eudr/api/plots/route.ts +0 -4
  722. package/src/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.ts +2 -0
  723. package/src/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.ts +1 -0
  724. package/src/modules/eudr/backend/eudr/evidence-submissions/page.meta.ts +4 -1
  725. package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +0 -4
  726. package/src/modules/eudr/backend/eudr/page.meta.ts +2 -2
  727. package/src/modules/eudr/backend/eudr/plots/[id]/page.meta.ts +2 -0
  728. package/src/modules/eudr/backend/eudr/plots/[id]/page.tsx +8 -2
  729. package/src/modules/eudr/backend/eudr/plots/create/page.meta.ts +1 -0
  730. package/src/modules/eudr/backend/eudr/plots/create/page.tsx +8 -2
  731. package/src/modules/eudr/backend/eudr/plots/page.meta.ts +4 -1
  732. package/src/modules/eudr/backend/eudr/plots/page.tsx +0 -4
  733. package/src/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.ts +2 -0
  734. package/src/modules/eudr/backend/eudr/product-mappings/create/page.meta.ts +1 -0
  735. package/src/modules/eudr/backend/eudr/product-mappings/page.meta.ts +4 -1
  736. package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +0 -4
  737. package/src/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.ts +2 -0
  738. package/src/modules/eudr/backend/eudr/risk-assessments/create/page.meta.ts +1 -0
  739. package/src/modules/eudr/backend/eudr/risk-assessments/page.meta.ts +4 -1
  740. package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +0 -4
  741. package/src/modules/eudr/backend/eudr/statements/[id]/page.meta.ts +2 -0
  742. package/src/modules/eudr/backend/eudr/statements/[id]/page.tsx +2 -0
  743. package/src/modules/eudr/backend/eudr/statements/create/page.meta.ts +1 -0
  744. package/src/modules/eudr/backend/eudr/statements/page.meta.ts +4 -1
  745. package/src/modules/eudr/backend/eudr/statements/page.tsx +32 -30
  746. package/src/modules/eudr/commands/statements.ts +7 -2
  747. package/src/modules/eudr/components/crudErrorI18n.ts +31 -0
  748. package/src/modules/eudr/components/formConfig.tsx +9 -1
  749. package/src/modules/eudr/data/validators.ts +1 -16
  750. package/src/modules/eudr/i18n/de.json +3 -2
  751. package/src/modules/eudr/i18n/en.json +3 -2
  752. package/src/modules/eudr/i18n/es.json +3 -2
  753. package/src/modules/eudr/i18n/ko.json +3 -2
  754. package/src/modules/eudr/i18n/pl.json +3 -2
  755. package/src/modules/eudr/lib/statement-lifecycle.ts +8 -0
  756. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +1 -2
  757. package/src/modules/feature_toggles/components/OverridesTable.tsx +1 -2
  758. package/src/modules/feature_toggles/defaults.json +8 -0
  759. package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +0 -4
  760. package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +0 -4
  761. package/src/modules/inbox_ops/lib/htmlToPlainText.ts +17 -1
  762. package/src/modules/integrations/api/[id]/credentials/route.ts +4 -6
  763. package/src/modules/integrations/backend/integrations/[id]/page.tsx +31 -61
  764. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +9 -44
  765. package/src/modules/integrations/data/validators.ts +2 -12
  766. package/src/modules/integrations/i18n/de.json +0 -1
  767. package/src/modules/integrations/i18n/en.json +0 -1
  768. package/src/modules/integrations/i18n/es.json +0 -1
  769. package/src/modules/integrations/i18n/ko.json +0 -1
  770. package/src/modules/integrations/i18n/pl.json +0 -1
  771. package/src/modules/integrations/lib/credentials-masking.ts +6 -10
  772. package/src/modules/messages/api/[id]/route.ts +1 -55
  773. package/src/modules/messages/api/openapi.ts +0 -20
  774. package/src/modules/messages/api/route.ts +2 -31
  775. package/src/modules/messages/components/MessagesInboxPageClient.tsx +16 -9
  776. package/src/modules/messages/components/inboxFilters.ts +0 -36
  777. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +1 -14
  778. package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +1 -3
  779. package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +1 -2
  780. package/src/modules/messages/components/message-detail/types.ts +0 -3
  781. package/src/modules/messages/components/messageListLabels.ts +3 -52
  782. package/src/modules/messages/data/validators.ts +4 -43
  783. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +6 -4
  784. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +1 -4
  785. package/src/modules/payment_gateways/lib/webhook-processor.ts +0 -11
  786. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +0 -4
  787. package/src/modules/push_notifications/backend/push_notifications/page.tsx +1 -4
  788. package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +4 -4
  789. package/src/modules/query_index/lib/engine.ts +61 -249
  790. package/src/modules/query_index/lib/search-tokens.ts +3 -135
  791. package/src/modules/resources/backend/resources/resource-types/page.tsx +1 -4
  792. package/src/modules/resources/backend/resources/resources/page.tsx +1 -4
  793. package/src/modules/sales/backend/sales/channels/offers/page.tsx +0 -4
  794. package/src/modules/sales/backend/sales/channels/page.tsx +0 -4
  795. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +8 -14
  796. package/src/modules/sales/commands/documents.ts +0 -93
  797. package/src/modules/sales/components/PriceWithCurrency.tsx +5 -17
  798. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +0 -4
  799. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +5 -6
  800. package/src/modules/sales/components/documents/ItemsSection.tsx +18 -56
  801. package/src/modules/sales/components/documents/LineItemDialog.tsx +21 -138
  802. package/src/modules/sales/components/documents/PaymentsSection.tsx +9 -20
  803. package/src/modules/sales/components/documents/ReturnsSection.tsx +5 -6
  804. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +14 -106
  805. package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +5 -6
  806. package/src/modules/sales/components/documents/ShipmentDialog.tsx +4 -5
  807. package/src/modules/sales/components/documents/ShipmentsSection.tsx +5 -6
  808. package/src/modules/sales/components/documents/lineItemUtils.ts +2 -7
  809. package/src/modules/sales/data/entities.ts +0 -6
  810. package/src/modules/sales/extension-points.ts +0 -1
  811. package/src/modules/sales/i18n/de.json +37 -8
  812. package/src/modules/sales/i18n/en.json +37 -8
  813. package/src/modules/sales/i18n/es.json +37 -8
  814. package/src/modules/sales/i18n/ko.json +37 -8
  815. package/src/modules/sales/i18n/pl.json +37 -8
  816. package/src/modules/sales/migrations/.snapshot-open-mercato.json +0 -60
  817. package/src/modules/sales/setup.ts +0 -2
  818. package/src/modules/sales/widgets/injection/document-history/widget.client.tsx +42 -2
  819. package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +1 -9
  820. package/src/modules/sales/widgets/injection-table.ts +7 -4
  821. package/src/modules/staff/backend/staff/leave-requests/page.tsx +0 -4
  822. package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +0 -4
  823. package/src/modules/staff/backend/staff/team-members/page.tsx +0 -6
  824. package/src/modules/staff/backend/staff/team-roles/page.tsx +0 -4
  825. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +0 -4
  826. package/src/modules/staff/backend/staff/teams/page.tsx +0 -4
  827. package/src/modules/staff/backend/staff/timesheets/page.tsx +1 -12
  828. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +0 -4
  829. package/src/modules/sync_excel/lib/adapters/customers.ts +0 -5
  830. package/src/modules/warranty_claims/api/assignees/route.ts +3 -3
  831. package/src/modules/warranty_claims/api/portal/attachments/route.ts +2 -2
  832. package/src/modules/warranty_claims/api/portal/claims/route.ts +9 -12
  833. package/src/modules/warranty_claims/backend/page.tsx +0 -4
  834. package/src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx +0 -4
  835. package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx +0 -4
  836. package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx +0 -4
  837. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +0 -4
  838. package/src/modules/wms/api/warehouses/route.ts +9 -13
  839. package/src/modules/wms/api/zones/route.ts +0 -16
  840. package/src/modules/wms/commands/configuration.ts +10 -159
  841. package/src/modules/wms/commands/inventory-actions.ts +0 -3
  842. package/src/modules/wms/commands/shared.ts +0 -17
  843. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +141 -95
  844. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +0 -2
  845. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +30 -26
  846. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +21 -17
  847. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +0 -2
  848. package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +17 -13
  849. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +16 -12
  850. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +20 -36
  851. package/src/modules/wms/i18n/de.json +0 -2
  852. package/src/modules/wms/i18n/en.json +0 -2
  853. package/src/modules/wms/i18n/es.json +0 -2
  854. package/src/modules/wms/i18n/ko.json +0 -2
  855. package/src/modules/wms/i18n/pl.json +0 -2
  856. package/src/modules/workflows/backend/definitions/page.tsx +1 -4
  857. package/src/modules/workflows/backend/events/page.tsx +1 -4
  858. package/src/modules/workflows/backend/instances/page.tsx +1 -4
  859. package/src/modules/workflows/backend/tasks/page.tsx +1 -4
  860. package/src/modules/workflows/lib/activity-executor.ts +0 -9
  861. package/dist/modules/api_keys/di.js +0 -9
  862. package/dist/modules/api_keys/di.js.map +0 -7
  863. package/dist/modules/api_keys/services/principalService.js +0 -31
  864. package/dist/modules/api_keys/services/principalService.js.map +0 -7
  865. package/dist/modules/attachments/lib/attachment-service.js +0 -313
  866. package/dist/modules/attachments/lib/attachment-service.js.map +0 -7
  867. package/dist/modules/auth/api/reset/validate.js +0 -55
  868. package/dist/modules/auth/api/reset/validate.js.map +0 -7
  869. package/dist/modules/auth/commands/acl.js +0 -254
  870. package/dist/modules/auth/commands/acl.js.map +0 -7
  871. package/dist/modules/auth/services/principalService.js +0 -200
  872. package/dist/modules/auth/services/principalService.js.map +0 -7
  873. package/dist/modules/auth/services/roleOrganizationScope.js +0 -41
  874. package/dist/modules/auth/services/roleOrganizationScope.js.map +0 -7
  875. package/dist/modules/communication_channels/lib/outbound-recipient.js +0 -33
  876. package/dist/modules/communication_channels/lib/outbound-recipient.js.map +0 -7
  877. package/dist/modules/communication_channels/lib/resolve-channel-type.js +0 -51
  878. package/dist/modules/communication_channels/lib/resolve-channel-type.js.map +0 -7
  879. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js +0 -18
  880. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js.map +0 -7
  881. package/dist/modules/customers/lib/calendar/participantIdentity.js +0 -9
  882. package/dist/modules/customers/lib/calendar/participantIdentity.js.map +0 -7
  883. package/dist/modules/customers/lib/closureStage.js +0 -45
  884. package/dist/modules/customers/lib/closureStage.js.map +0 -7
  885. package/dist/modules/customers/lib/detailReadAccess.js +0 -12
  886. package/dist/modules/customers/lib/detailReadAccess.js.map +0 -7
  887. package/dist/modules/data_sync/lib/abandoned-run.js +0 -19
  888. package/dist/modules/data_sync/lib/abandoned-run.js.map +0 -7
  889. package/dist/modules/devices/api/deviceSerialization.js +0 -46
  890. package/dist/modules/devices/api/deviceSerialization.js.map +0 -7
  891. package/dist/modules/directory/services/organizationHierarchyService.js +0 -29
  892. package/dist/modules/directory/services/organizationHierarchyService.js.map +0 -7
  893. package/dist/modules/directory/services/organizationScopeService.js +0 -56
  894. package/dist/modules/directory/services/organizationScopeService.js.map +0 -7
  895. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js +0 -55
  896. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js.map +0 -7
  897. package/dist/modules/messages/lib/channel-sender-identity.js +0 -26
  898. package/dist/modules/messages/lib/channel-sender-identity.js.map +0 -7
  899. package/dist/modules/messages/lib/composeSourceChannelType.js +0 -41
  900. package/dist/modules/messages/lib/composeSourceChannelType.js.map +0 -7
  901. package/dist/modules/query_index/lib/search-entity-policy.js +0 -14
  902. package/dist/modules/query_index/lib/search-entity-policy.js.map +0 -7
  903. package/dist/modules/sales/components/documents/lineItemShipmentLock.js +0 -54
  904. package/dist/modules/sales/components/documents/lineItemShipmentLock.js.map +0 -7
  905. package/dist/modules/sales/lib/salesChannelsToggleSeed.js +0 -33
  906. package/dist/modules/sales/lib/salesChannelsToggleSeed.js.map +0 -7
  907. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js +0 -32
  908. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js.map +0 -7
  909. package/dist/modules/wms/api/warehouseSearch.js +0 -21
  910. package/dist/modules/wms/api/warehouseSearch.js.map +0 -7
  911. package/dist/modules/wms/components/backend/WarehouseEditDialog.js +0 -158
  912. package/dist/modules/wms/components/backend/WarehouseEditDialog.js.map +0 -7
  913. package/dist/modules/wms/components/backend/warehouseFormOptions.js +0 -66
  914. package/dist/modules/wms/components/backend/warehouseFormOptions.js.map +0 -7
  915. package/src/modules/api_keys/di.ts +0 -7
  916. package/src/modules/api_keys/services/principalService.ts +0 -33
  917. package/src/modules/attachments/lib/attachment-service.ts +0 -468
  918. package/src/modules/auth/api/reset/validate.ts +0 -57
  919. package/src/modules/auth/commands/acl.ts +0 -495
  920. package/src/modules/auth/services/principalService.ts +0 -266
  921. package/src/modules/auth/services/roleOrganizationScope.ts +0 -70
  922. package/src/modules/communication_channels/lib/outbound-recipient.ts +0 -71
  923. package/src/modules/communication_channels/lib/resolve-channel-type.ts +0 -99
  924. package/src/modules/customers/backend/customers/deals/pipeline/components/toneClasses.ts +0 -21
  925. package/src/modules/customers/lib/calendar/participantIdentity.ts +0 -17
  926. package/src/modules/customers/lib/closureStage.ts +0 -76
  927. package/src/modules/customers/lib/detailReadAccess.ts +0 -35
  928. package/src/modules/data_sync/lib/abandoned-run.ts +0 -56
  929. package/src/modules/devices/api/deviceSerialization.ts +0 -50
  930. package/src/modules/directory/services/organizationHierarchyService.ts +0 -34
  931. package/src/modules/directory/services/organizationScopeService.ts +0 -85
  932. package/src/modules/integrations/backend/integrations/credential-secret-fields.ts +0 -84
  933. package/src/modules/messages/lib/channel-sender-identity.ts +0 -55
  934. package/src/modules/messages/lib/composeSourceChannelType.ts +0 -95
  935. package/src/modules/query_index/lib/search-entity-policy.ts +0 -46
  936. package/src/modules/sales/components/documents/lineItemShipmentLock.ts +0 -74
  937. package/src/modules/sales/lib/salesChannelsToggleSeed.ts +0 -42
  938. package/src/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.ts +0 -87
  939. package/src/modules/wms/api/warehouseSearch.ts +0 -23
  940. package/src/modules/wms/components/backend/WarehouseEditDialog.tsx +0 -216
  941. package/src/modules/wms/components/backend/warehouseFormOptions.ts +0 -72
@@ -1,4 +1,4 @@
1
- [build:core] found 4351 entry points
1
+ [build:core] found 4320 entry points
2
2
  [build:core] built successfully
3
3
  [build:core:generated] found 218 entry points
4
4
  [build:core:generated] built successfully
@@ -1,4 +1,3 @@
1
- import { request as playwrightRequest } from "@playwright/test";
2
1
  import { DEFAULT_CREDENTIALS } from "./auth.js";
3
2
  const BASE_URL = process.env.BASE_URL?.trim() || null;
4
3
  function resolveUrl(path) {
@@ -90,21 +89,10 @@ async function postForm(request, path, data, options) {
90
89
  data: form.toString()
91
90
  });
92
91
  }
93
- async function withCredentialIsolatedRequest(use) {
94
- const context = await playwrightRequest.newContext({
95
- baseURL: BASE_URL ?? "http://localhost:3000"
96
- });
97
- try {
98
- return await use(context);
99
- } finally {
100
- await context.dispose();
101
- }
102
- }
103
92
  export {
104
93
  apiRequest,
105
94
  clearAuthTokenCache,
106
95
  getAuthToken,
107
- postForm,
108
- withCredentialIsolatedRequest
96
+ postForm
109
97
  };
110
98
  //# sourceMappingURL=api.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/helpers/integration/api.ts"],
4
- "sourcesContent": ["import { request as playwrightRequest, type APIRequestContext } from '@playwright/test';\nimport { DEFAULT_CREDENTIALS, type Role } from './auth';\n\nconst BASE_URL = process.env.BASE_URL?.trim() || null;\n\nfunction resolveUrl(path: string): string {\n return BASE_URL ? `${BASE_URL}${path}` : path;\n}\n\n// Cached tokens per credential to dodge the login rate limit\n// (5 attempts/60s per email). Tokens are reused across tests in the same\n// Playwright worker; each worker still mints its own.\nconst tokenCache = new Map<string, { token: string; mintedAt: number }>();\nconst TOKEN_TTL_MS = 45 * 60 * 1000; // 45 min; well under the default 2h session TTL.\n\n/**\n * Drops cached tokens so the next getAuthToken() mints a fresh session.\n *\n * A cached token points at a `sessions` row. Anything that deletes those rows \u2014\n * deactivating the user, a password change, an explicit session purge \u2014 leaves the\n * cached token resolving to 401 for the rest of the TTL, and `apiRequest` neither\n * retries nor re-mints. A spec that revokes sessions for an account other specs also\n * use MUST call this afterwards.\n */\nexport function clearAuthTokenCache(): void {\n tokenCache.clear();\n}\n\nexport async function getAuthToken(\n request: APIRequestContext,\n roleOrEmail: Role | string = 'admin',\n password?: string,\n): Promise<string> {\n const role = roleOrEmail in DEFAULT_CREDENTIALS ? (roleOrEmail as Role) : null;\n const credentialAttempts: Array<{ email: string; password: string }> = [];\n\n if (role) {\n const configured = DEFAULT_CREDENTIALS[role];\n credentialAttempts.push({ email: configured.email, password: password ?? configured.password });\n if (!password) {\n credentialAttempts.push({ email: `${role}@acme.com`, password: 'secret' });\n }\n } else {\n credentialAttempts.push({ email: roleOrEmail, password: password ?? 'secret' });\n }\n\n const cacheKey = credentialAttempts\n .map((entry) => `${entry.email}:${entry.password}`)\n .join('|');\n const cached = tokenCache.get(cacheKey);\n if (cached && Date.now() - cached.mintedAt < TOKEN_TTL_MS) {\n return cached.token;\n }\n\n let lastStatus = 0;\n\n for (const attempt of credentialAttempts) {\n const form = new URLSearchParams();\n form.set('email', attempt.email);\n form.set('password', attempt.password);\n\n // Retry on 429 (auth rate limit kicks in after ~25-30 rapid attempts from\n // the same test run). Capped exponential backoff: 1s, 2s, 4s; 3 retries.\n for (let retry = 0; retry < 4; retry += 1) {\n const response = await request.post(resolveUrl('/api/auth/login'), {\n headers: {\n 'content-type': 'application/x-www-form-urlencoded',\n },\n data: form.toString(),\n });\n\n const raw = await response.text();\n let body: Record<string, unknown> | null = null;\n try {\n body = raw ? (JSON.parse(raw) as Record<string, unknown>) : null;\n } catch {\n body = null;\n }\n\n lastStatus = response.status();\n if (response.ok() && body && typeof body.token === 'string' && body.token) {\n tokenCache.set(cacheKey, { token: body.token, mintedAt: Date.now() });\n return body.token;\n }\n if (response.status() !== 429) break;\n const backoffMs = 1000 * 2 ** retry;\n await new Promise((resolve) => setTimeout(resolve, backoffMs));\n }\n }\n\n throw new Error(`Failed to obtain auth token (status ${lastStatus})`);\n}\n\nexport async function apiRequest(\n request: APIRequestContext,\n method: string,\n path: string,\n options: {\n token: string;\n data?: unknown;\n timeout?: number;\n retryTransport?: boolean;\n headers?: Record<string, string>;\n },\n) {\n const headers = {\n Authorization: `Bearer ${options.token}`,\n 'Content-Type': 'application/json',\n ...(options.headers ?? {}),\n };\n const timeout = options.timeout ?? 30_000;\n let lastError: unknown = null;\n const maxAttempts = options.retryTransport === false ? 1 : 2;\n for (let attempt = 0; attempt < maxAttempts; attempt += 1) {\n try {\n return await request.fetch(resolveUrl(path), { method, headers, data: options.data, timeout });\n } catch (error) {\n lastError = error;\n const message = error instanceof Error ? error.message : '';\n const retryable = /timeout|idle-session|socket|ECONNRESET|Target page, context or browser has been closed/i.test(message);\n if (!retryable || attempt === maxAttempts - 1) throw error;\n await new Promise((resolve) => setTimeout(resolve, 250));\n }\n }\n throw lastError;\n}\n\nexport async function postForm(\n request: APIRequestContext,\n path: string,\n data: Record<string, string>,\n options?: { headers?: Record<string, string> },\n) {\n const form = new URLSearchParams();\n for (const [key, value] of Object.entries(data)) form.set(key, value);\n return request.post(resolveUrl(path), {\n headers: {\n 'content-type': 'application/x-www-form-urlencoded',\n ...(options?.headers ?? {}),\n },\n data: form.toString(),\n });\n}\n\n/**\n * Runs `use` against a request context that shares no cookies with the caller's.\n *\n * The `request` fixture keeps a cookie jar, and `/api/auth/login` sets `auth_token`\n * on it. Every later call through that fixture therefore carries the LAST logged-in\n * user's session, even one that deliberately sends no Authorization header or an\n * `ApiKey` one.\n *\n * A spec asserting \"no credentials are rejected\" or \"this API key alone decides\n * access\" must therefore issue the request from a jar that never saw a login,\n * rather than assuming the fixture's jar is empty. TC-DOCUMENTS-009 and\n * TC-DOCUMENTS-018 both observably failed in the standalone lane \u2014 with the\n * replayed cookie visible in the trace \u2014 while passing in the ephemeral one, and\n * routing them through this helper fixed both.\n */\nexport async function withCredentialIsolatedRequest<T>(\n use: (request: APIRequestContext) => Promise<T>,\n): Promise<T> {\n // A hand-built context does not inherit the project's `use.baseURL` the way the\n // `request` fixture does, so it has to repeat the config's own resolution \u2014 otherwise\n // a relative path throws here on any run that leaves BASE_URL unset, while the same\n // path works through the fixture.\n const context = await playwrightRequest.newContext({\n baseURL: BASE_URL ?? 'http://localhost:3000',\n });\n try {\n return await use(context);\n } finally {\n await context.dispose();\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { type APIRequestContext } from '@playwright/test';\nimport { DEFAULT_CREDENTIALS, type Role } from './auth';\n\nconst BASE_URL = process.env.BASE_URL?.trim() || null;\n\nfunction resolveUrl(path: string): string {\n return BASE_URL ? `${BASE_URL}${path}` : path;\n}\n\n// Cached tokens per credential to dodge the login rate limit\n// (5 attempts/60s per email). Tokens are reused across tests in the same\n// Playwright worker; each worker still mints its own.\nconst tokenCache = new Map<string, { token: string; mintedAt: number }>();\nconst TOKEN_TTL_MS = 45 * 60 * 1000; // 45 min; well under the default 2h session TTL.\n\n/**\n * Drops cached tokens so the next getAuthToken() mints a fresh session.\n *\n * A cached token points at a `sessions` row. Anything that deletes those rows \u2014\n * deactivating the user, a password change, an explicit session purge \u2014 leaves the\n * cached token resolving to 401 for the rest of the TTL, and `apiRequest` neither\n * retries nor re-mints. A spec that revokes sessions for an account other specs also\n * use MUST call this afterwards.\n */\nexport function clearAuthTokenCache(): void {\n tokenCache.clear();\n}\n\nexport async function getAuthToken(\n request: APIRequestContext,\n roleOrEmail: Role | string = 'admin',\n password?: string,\n): Promise<string> {\n const role = roleOrEmail in DEFAULT_CREDENTIALS ? (roleOrEmail as Role) : null;\n const credentialAttempts: Array<{ email: string; password: string }> = [];\n\n if (role) {\n const configured = DEFAULT_CREDENTIALS[role];\n credentialAttempts.push({ email: configured.email, password: password ?? configured.password });\n if (!password) {\n credentialAttempts.push({ email: `${role}@acme.com`, password: 'secret' });\n }\n } else {\n credentialAttempts.push({ email: roleOrEmail, password: password ?? 'secret' });\n }\n\n const cacheKey = credentialAttempts\n .map((entry) => `${entry.email}:${entry.password}`)\n .join('|');\n const cached = tokenCache.get(cacheKey);\n if (cached && Date.now() - cached.mintedAt < TOKEN_TTL_MS) {\n return cached.token;\n }\n\n let lastStatus = 0;\n\n for (const attempt of credentialAttempts) {\n const form = new URLSearchParams();\n form.set('email', attempt.email);\n form.set('password', attempt.password);\n\n // Retry on 429 (auth rate limit kicks in after ~25-30 rapid attempts from\n // the same test run). Capped exponential backoff: 1s, 2s, 4s; 3 retries.\n for (let retry = 0; retry < 4; retry += 1) {\n const response = await request.post(resolveUrl('/api/auth/login'), {\n headers: {\n 'content-type': 'application/x-www-form-urlencoded',\n },\n data: form.toString(),\n });\n\n const raw = await response.text();\n let body: Record<string, unknown> | null = null;\n try {\n body = raw ? (JSON.parse(raw) as Record<string, unknown>) : null;\n } catch {\n body = null;\n }\n\n lastStatus = response.status();\n if (response.ok() && body && typeof body.token === 'string' && body.token) {\n tokenCache.set(cacheKey, { token: body.token, mintedAt: Date.now() });\n return body.token;\n }\n if (response.status() !== 429) break;\n const backoffMs = 1000 * 2 ** retry;\n await new Promise((resolve) => setTimeout(resolve, backoffMs));\n }\n }\n\n throw new Error(`Failed to obtain auth token (status ${lastStatus})`);\n}\n\nexport async function apiRequest(\n request: APIRequestContext,\n method: string,\n path: string,\n options: {\n token: string;\n data?: unknown;\n timeout?: number;\n retryTransport?: boolean;\n headers?: Record<string, string>;\n },\n) {\n const headers = {\n Authorization: `Bearer ${options.token}`,\n 'Content-Type': 'application/json',\n ...(options.headers ?? {}),\n };\n const timeout = options.timeout ?? 30_000;\n let lastError: unknown = null;\n const maxAttempts = options.retryTransport === false ? 1 : 2;\n for (let attempt = 0; attempt < maxAttempts; attempt += 1) {\n try {\n return await request.fetch(resolveUrl(path), { method, headers, data: options.data, timeout });\n } catch (error) {\n lastError = error;\n const message = error instanceof Error ? error.message : '';\n const retryable = /timeout|idle-session|socket|ECONNRESET|Target page, context or browser has been closed/i.test(message);\n if (!retryable || attempt === maxAttempts - 1) throw error;\n await new Promise((resolve) => setTimeout(resolve, 250));\n }\n }\n throw lastError;\n}\n\nexport async function postForm(\n request: APIRequestContext,\n path: string,\n data: Record<string, string>,\n options?: { headers?: Record<string, string> },\n) {\n const form = new URLSearchParams();\n for (const [key, value] of Object.entries(data)) form.set(key, value);\n return request.post(resolveUrl(path), {\n headers: {\n 'content-type': 'application/x-www-form-urlencoded',\n ...(options?.headers ?? {}),\n },\n data: form.toString(),\n });\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -40,24 +40,6 @@ async function seedInboundMessage(request, token, input) {
40
40
  )
41
41
  };
42
42
  }
43
- async function ingestInboundChatMessage(request, token, input) {
44
- const response = await apiRequest(request, "POST", TEST_SEED_PATH, {
45
- token,
46
- data: { action: "ingest-inbound", ...input }
47
- });
48
- expect(
49
- response.status(),
50
- "POST /api/communication_channels/test-seed (ingest-inbound) should return 201 \u2014 a non-201 here means the hub rejected a sender with no email address"
51
- ).toBe(201);
52
- const body = await readJsonSafe(response);
53
- return {
54
- status: body?.status ?? "unknown",
55
- messageId: body?.messageId ?? null,
56
- conversationId: body?.conversationId ?? null,
57
- channelLinkId: body?.channelLinkId ?? null,
58
- channelType: body?.channelType ?? null
59
- };
60
- }
61
43
  async function deleteChannelIfExists(request, token, channelId) {
62
44
  if (!token || !channelId) return;
63
45
  await apiRequest(
@@ -69,7 +51,6 @@ async function deleteChannelIfExists(request, token, channelId) {
69
51
  }
70
52
  export {
71
53
  deleteChannelIfExists,
72
- ingestInboundChatMessage,
73
54
  isChannelSeedingAvailable,
74
55
  seedConnectedChannel,
75
56
  seedInboundMessage
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/helpers/integration/communicationChannelsFixtures.ts"],
4
- "sourcesContent": ["import { expect, type APIRequestContext } from '@playwright/test';\nimport { apiRequest } from './api';\nimport { expectId, readJsonSafe } from './generalFixtures';\n\n/**\n * Communication-channels integration fixtures.\n *\n * These drive the TEST-ONLY seed endpoint `POST /api/communication_channels/test-seed`,\n * which is gated by `OM_ENABLE_TEST_CHANNEL_SEEDING` (inert/404 in production). Use\n * {@link isChannelSeedingAvailable} to skip tests when the gate is off rather than\n * failing them.\n */\n\nexport type SeedAddressField =\n | string\n | { address: string; name?: string }\n | Array<string | { address: string; name?: string }>;\n\nconst TEST_SEED_PATH = '/api/communication_channels/test-seed';\n\n/**\n * Probe whether the env-gated test-seed endpoint is enabled in the target app.\n * Returns false when the route answers 404 (flag off) so callers can `test.skip`.\n * The caller's token must hold `communication_channels.connect_user_channel`.\n */\nexport async function isChannelSeedingAvailable(\n request: APIRequestContext,\n token: string,\n): Promise<boolean> {\n // A malformed body returns 422 when the gate is ON and 404 when it is OFF.\n const response = await apiRequest(request, 'POST', TEST_SEED_PATH, {\n token,\n data: { action: '__probe__' },\n });\n return response.status() !== 404;\n}\n\n/**\n * Seed a connected, network-free `__test_seed__` channel owned by the caller.\n * Returns the new channel id. Tear down with {@link deleteChannelIfExists}.\n */\nexport async function seedConnectedChannel(\n request: APIRequestContext,\n token: string,\n input: {\n displayName?: string;\n externalIdentifier?: string;\n /**\n * `chat` connects the non-email stub instead: a channel whose senders carry\n * an opaque handle and no address, and whose `externalIdentifier` is NULL \u2014\n * the shape a real Discord/Slack channel has. Use it for anything asserting\n * the hub's sender-identity contract (#4975); the default `email` flavor\n * cannot prove it, because it can only ever supply email-shaped data.\n */\n providerFlavor?: 'email' | 'chat';\n } = {},\n): Promise<string> {\n const response = await apiRequest(request, 'POST', TEST_SEED_PATH, {\n token,\n data: { action: 'connect-channel', ...input },\n });\n expect(\n response.status(),\n 'POST /api/communication_channels/test-seed (connect-channel) should return 201',\n ).toBe(201);\n const body = await readJsonSafe<{ channelId?: string }>(response);\n return expectId(body?.channelId, 'connect-channel response should include channelId');\n}\n\n/**\n * Seed an inbound `MessageChannelLink` for `channelId` and emit\n * `communication_channels.message.received` through the real event bus. The\n * persistent customers link-channel-message-received subscriber is enqueued to\n * the `events` queue \u2014 drain it with `drainIntegrationQueue('events')`.\n *\n * Returns the created link + message ids (the message id is the platform\n * `messages.message` id, usable as `messageThreadId` to thread a follow-up).\n *\n * Pass `createThreadMapping: true` to also seed a `ChannelThreadMapping` for the\n * thread \u2014 required before exercising the reaction (`/messages/[id]/reactions`)\n * and thread-assign (`/threads/[id]/assign`) routes, which resolve the owning\n * channel through that mapping.\n */\nexport async function seedInboundMessage(\n request: APIRequestContext,\n token: string,\n input: {\n channelId: string;\n from?: SeedAddressField;\n to?: SeedAddressField;\n cc?: SeedAddressField;\n subject?: string;\n bodyText?: string;\n messageId?: string;\n inReplyTo?: string;\n references?: string[];\n messageThreadId?: string;\n providerKey?: string;\n createThreadMapping?: boolean;\n },\n): Promise<{ channelLinkId: string; messageId: string; conversationId: string }> {\n const response = await apiRequest(request, 'POST', TEST_SEED_PATH, {\n token,\n data: { action: 'emit-inbound', ...input },\n });\n expect(\n response.status(),\n 'POST /api/communication_channels/test-seed (emit-inbound) should return 201',\n ).toBe(201);\n const body = await readJsonSafe<{\n channelLinkId?: string;\n messageId?: string;\n conversationId?: string;\n }>(response);\n return {\n channelLinkId: expectId(body?.channelLinkId, 'emit-inbound response should include channelLinkId'),\n messageId: expectId(body?.messageId, 'emit-inbound response should include messageId'),\n conversationId: expectId(\n body?.conversationId,\n 'emit-inbound response should include conversationId',\n ),\n };\n}\n\n/**\n * Best-effort delete of a seeded channel via the owner-scoped DELETE route.\n * Safe to call with a null id in `finally`.\n */\n/**\n * Ingest an inbound chat message through the REAL `ingest_inbound_message`\n * command: the stub adapter normalizes the frame and the hub composes the\n * platform message via `messages.messages.compose`.\n *\n * Unlike {@link seedInboundMessage}, nothing here is short-circuited \u2014 no row is\n * inserted behind the compose path \u2014 so a hub contract the provider cannot\n * satisfy fails the test instead of hiding behind seeded data. That bypass is\n * exactly why CI was green while every real inbound Discord message was rejected\n * (#4975).\n *\n * The sender is identified only by `senderIdentifier` (a Discord snowflake, a\n * Slack member id, \u2026). There is deliberately no way to pass an address.\n */\nexport async function ingestInboundChatMessage(\n request: APIRequestContext,\n token: string,\n input: {\n channelId: string;\n senderIdentifier: string;\n senderDisplayName?: string;\n body?: string;\n externalMessageId: string;\n externalConversationId: string;\n },\n): Promise<{\n status: string;\n messageId: string | null;\n conversationId: string | null;\n channelLinkId: string | null;\n channelType: string | null;\n}> {\n const response = await apiRequest(request, 'POST', TEST_SEED_PATH, {\n token,\n data: { action: 'ingest-inbound', ...input },\n });\n expect(\n response.status(),\n 'POST /api/communication_channels/test-seed (ingest-inbound) should return 201 \u2014 ' +\n 'a non-201 here means the hub rejected a sender with no email address',\n ).toBe(201);\n const body = await readJsonSafe<{\n status?: string;\n messageId?: string | null;\n conversationId?: string | null;\n channelLinkId?: string | null;\n channelType?: string | null;\n }>(response);\n return {\n status: body?.status ?? 'unknown',\n messageId: body?.messageId ?? null,\n conversationId: body?.conversationId ?? null,\n channelLinkId: body?.channelLinkId ?? null,\n channelType: body?.channelType ?? null,\n };\n}\n\nexport async function deleteChannelIfExists(\n request: APIRequestContext,\n token: string | null,\n channelId: string | null,\n): Promise<void> {\n if (!token || !channelId) return;\n await apiRequest(\n request,\n 'DELETE',\n `/api/communication_channels/channels/${encodeURIComponent(channelId)}`,\n { token },\n ).catch(() => undefined);\n}\n"],
5
- "mappings": "AAAA,SAAS,cAAsC;AAC/C,SAAS,kBAAkB;AAC3B,SAAS,UAAU,oBAAoB;AAgBvC,MAAM,iBAAiB;AAOvB,eAAsB,0BACpB,SACA,OACkB;AAElB,QAAM,WAAW,MAAM,WAAW,SAAS,QAAQ,gBAAgB;AAAA,IACjE;AAAA,IACA,MAAM,EAAE,QAAQ,YAAY;AAAA,EAC9B,CAAC;AACD,SAAO,SAAS,OAAO,MAAM;AAC/B;AAMA,eAAsB,qBACpB,SACA,OACA,QAWI,CAAC,GACY;AACjB,QAAM,WAAW,MAAM,WAAW,SAAS,QAAQ,gBAAgB;AAAA,IACjE;AAAA,IACA,MAAM,EAAE,QAAQ,mBAAmB,GAAG,MAAM;AAAA,EAC9C,CAAC;AACD;AAAA,IACE,SAAS,OAAO;AAAA,IAChB;AAAA,EACF,EAAE,KAAK,GAAG;AACV,QAAM,OAAO,MAAM,aAAqC,QAAQ;AAChE,SAAO,SAAS,MAAM,WAAW,mDAAmD;AACtF;AAgBA,eAAsB,mBACpB,SACA,OACA,OAc+E;AAC/E,QAAM,WAAW,MAAM,WAAW,SAAS,QAAQ,gBAAgB;AAAA,IACjE;AAAA,IACA,MAAM,EAAE,QAAQ,gBAAgB,GAAG,MAAM;AAAA,EAC3C,CAAC;AACD;AAAA,IACE,SAAS,OAAO;AAAA,IAChB;AAAA,EACF,EAAE,KAAK,GAAG;AACV,QAAM,OAAO,MAAM,aAIhB,QAAQ;AACX,SAAO;AAAA,IACL,eAAe,SAAS,MAAM,eAAe,oDAAoD;AAAA,IACjG,WAAW,SAAS,MAAM,WAAW,gDAAgD;AAAA,IACrF,gBAAgB;AAAA,MACd,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACF;AAoBA,eAAsB,yBACpB,SACA,OACA,OAcC;AACD,QAAM,WAAW,MAAM,WAAW,SAAS,QAAQ,gBAAgB;AAAA,IACjE;AAAA,IACA,MAAM,EAAE,QAAQ,kBAAkB,GAAG,MAAM;AAAA,EAC7C,CAAC;AACD;AAAA,IACE,SAAS,OAAO;AAAA,IAChB;AAAA,EAEF,EAAE,KAAK,GAAG;AACV,QAAM,OAAO,MAAM,aAMhB,QAAQ;AACX,SAAO;AAAA,IACL,QAAQ,MAAM,UAAU;AAAA,IACxB,WAAW,MAAM,aAAa;AAAA,IAC9B,gBAAgB,MAAM,kBAAkB;AAAA,IACxC,eAAe,MAAM,iBAAiB;AAAA,IACtC,aAAa,MAAM,eAAe;AAAA,EACpC;AACF;AAEA,eAAsB,sBACpB,SACA,OACA,WACe;AACf,MAAI,CAAC,SAAS,CAAC,UAAW;AAC1B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,wCAAwC,mBAAmB,SAAS,CAAC;AAAA,IACrE,EAAE,MAAM;AAAA,EACV,EAAE,MAAM,MAAM,MAAS;AACzB;",
4
+ "sourcesContent": ["import { expect, type APIRequestContext } from '@playwright/test';\nimport { apiRequest } from './api';\nimport { expectId, readJsonSafe } from './generalFixtures';\n\n/**\n * Communication-channels integration fixtures.\n *\n * These drive the TEST-ONLY seed endpoint `POST /api/communication_channels/test-seed`,\n * which is gated by `OM_ENABLE_TEST_CHANNEL_SEEDING` (inert/404 in production). Use\n * {@link isChannelSeedingAvailable} to skip tests when the gate is off rather than\n * failing them.\n */\n\nexport type SeedAddressField =\n | string\n | { address: string; name?: string }\n | Array<string | { address: string; name?: string }>;\n\nconst TEST_SEED_PATH = '/api/communication_channels/test-seed';\n\n/**\n * Probe whether the env-gated test-seed endpoint is enabled in the target app.\n * Returns false when the route answers 404 (flag off) so callers can `test.skip`.\n * The caller's token must hold `communication_channels.connect_user_channel`.\n */\nexport async function isChannelSeedingAvailable(\n request: APIRequestContext,\n token: string,\n): Promise<boolean> {\n // A malformed body returns 422 when the gate is ON and 404 when it is OFF.\n const response = await apiRequest(request, 'POST', TEST_SEED_PATH, {\n token,\n data: { action: '__probe__' },\n });\n return response.status() !== 404;\n}\n\n/**\n * Seed a connected, network-free `__test_seed__` channel owned by the caller.\n * Returns the new channel id. Tear down with {@link deleteChannelIfExists}.\n */\nexport async function seedConnectedChannel(\n request: APIRequestContext,\n token: string,\n input: { displayName?: string; externalIdentifier?: string } = {},\n): Promise<string> {\n const response = await apiRequest(request, 'POST', TEST_SEED_PATH, {\n token,\n data: { action: 'connect-channel', ...input },\n });\n expect(\n response.status(),\n 'POST /api/communication_channels/test-seed (connect-channel) should return 201',\n ).toBe(201);\n const body = await readJsonSafe<{ channelId?: string }>(response);\n return expectId(body?.channelId, 'connect-channel response should include channelId');\n}\n\n/**\n * Seed an inbound `MessageChannelLink` for `channelId` and emit\n * `communication_channels.message.received` through the real event bus. The\n * persistent customers link-channel-message-received subscriber is enqueued to\n * the `events` queue \u2014 drain it with `drainIntegrationQueue('events')`.\n *\n * Returns the created link + message ids (the message id is the platform\n * `messages.message` id, usable as `messageThreadId` to thread a follow-up).\n *\n * Pass `createThreadMapping: true` to also seed a `ChannelThreadMapping` for the\n * thread \u2014 required before exercising the reaction (`/messages/[id]/reactions`)\n * and thread-assign (`/threads/[id]/assign`) routes, which resolve the owning\n * channel through that mapping.\n */\nexport async function seedInboundMessage(\n request: APIRequestContext,\n token: string,\n input: {\n channelId: string;\n from?: SeedAddressField;\n to?: SeedAddressField;\n cc?: SeedAddressField;\n subject?: string;\n bodyText?: string;\n messageId?: string;\n inReplyTo?: string;\n references?: string[];\n messageThreadId?: string;\n providerKey?: string;\n createThreadMapping?: boolean;\n },\n): Promise<{ channelLinkId: string; messageId: string; conversationId: string }> {\n const response = await apiRequest(request, 'POST', TEST_SEED_PATH, {\n token,\n data: { action: 'emit-inbound', ...input },\n });\n expect(\n response.status(),\n 'POST /api/communication_channels/test-seed (emit-inbound) should return 201',\n ).toBe(201);\n const body = await readJsonSafe<{\n channelLinkId?: string;\n messageId?: string;\n conversationId?: string;\n }>(response);\n return {\n channelLinkId: expectId(body?.channelLinkId, 'emit-inbound response should include channelLinkId'),\n messageId: expectId(body?.messageId, 'emit-inbound response should include messageId'),\n conversationId: expectId(\n body?.conversationId,\n 'emit-inbound response should include conversationId',\n ),\n };\n}\n\n/**\n * Best-effort delete of a seeded channel via the owner-scoped DELETE route.\n * Safe to call with a null id in `finally`.\n */\nexport async function deleteChannelIfExists(\n request: APIRequestContext,\n token: string | null,\n channelId: string | null,\n): Promise<void> {\n if (!token || !channelId) return;\n await apiRequest(\n request,\n 'DELETE',\n `/api/communication_channels/channels/${encodeURIComponent(channelId)}`,\n { token },\n ).catch(() => undefined);\n}\n"],
5
+ "mappings": "AAAA,SAAS,cAAsC;AAC/C,SAAS,kBAAkB;AAC3B,SAAS,UAAU,oBAAoB;AAgBvC,MAAM,iBAAiB;AAOvB,eAAsB,0BACpB,SACA,OACkB;AAElB,QAAM,WAAW,MAAM,WAAW,SAAS,QAAQ,gBAAgB;AAAA,IACjE;AAAA,IACA,MAAM,EAAE,QAAQ,YAAY;AAAA,EAC9B,CAAC;AACD,SAAO,SAAS,OAAO,MAAM;AAC/B;AAMA,eAAsB,qBACpB,SACA,OACA,QAA+D,CAAC,GAC/C;AACjB,QAAM,WAAW,MAAM,WAAW,SAAS,QAAQ,gBAAgB;AAAA,IACjE;AAAA,IACA,MAAM,EAAE,QAAQ,mBAAmB,GAAG,MAAM;AAAA,EAC9C,CAAC;AACD;AAAA,IACE,SAAS,OAAO;AAAA,IAChB;AAAA,EACF,EAAE,KAAK,GAAG;AACV,QAAM,OAAO,MAAM,aAAqC,QAAQ;AAChE,SAAO,SAAS,MAAM,WAAW,mDAAmD;AACtF;AAgBA,eAAsB,mBACpB,SACA,OACA,OAc+E;AAC/E,QAAM,WAAW,MAAM,WAAW,SAAS,QAAQ,gBAAgB;AAAA,IACjE;AAAA,IACA,MAAM,EAAE,QAAQ,gBAAgB,GAAG,MAAM;AAAA,EAC3C,CAAC;AACD;AAAA,IACE,SAAS,OAAO;AAAA,IAChB;AAAA,EACF,EAAE,KAAK,GAAG;AACV,QAAM,OAAO,MAAM,aAIhB,QAAQ;AACX,SAAO;AAAA,IACL,eAAe,SAAS,MAAM,eAAe,oDAAoD;AAAA,IACjG,WAAW,SAAS,MAAM,WAAW,gDAAgD;AAAA,IACrF,gBAAgB;AAAA,MACd,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACF;AAMA,eAAsB,sBACpB,SACA,OACA,WACe;AACf,MAAI,CAAC,SAAS,CAAC,UAAW;AAC1B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,wCAAwC,mBAAmB,SAAS,CAAC;AAAA,IACrE,EAAE,MAAM;AAAA,EACV,EAAE,MAAM,MAAM,MAAS;AACzB;",
6
6
  "names": []
7
7
  }
@@ -249,7 +249,7 @@ const crud = makeCrudRoute({
249
249
  scopedCtx.__apiKeyRoles = roleEntities;
250
250
  scopedCtx.__apiKeyRoleIds = roleIds;
251
251
  const allowedIds = ctx.organizationScope?.allowedIds ?? null;
252
- const organizationId = Object.prototype.hasOwnProperty.call(input, "organizationId") ? input.organizationId ?? null : ctx.selectedOrganizationId ?? auth.orgId ?? null;
252
+ const organizationId = input.organizationId ?? ctx.selectedOrganizationId ?? auth.orgId ?? null;
253
253
  const isSuperAdmin = await resolveIsSuperAdmin(scopedCtx);
254
254
  if (!isOrganizationAccessAllowed({
255
255
  isSuperAdmin,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/api_keys/api/keys/route.ts"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport type { CrudCtx } from '@open-mercato/shared/lib/crud/factory'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\nimport { Role } from '@open-mercato/core/modules/auth/data/entities'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport { ApiKey } from '../../data/entities'\nimport { createApiKeySchema } from '../../data/validators'\nimport { generateApiKeySecret, hashApiKey } from '../../services/apiKeyService'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { enforceTenantSelection, resolveIsSuperAdmin } from '@open-mercato/core/modules/auth/lib/tenantAccess'\nimport { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'\nimport { assertActorCanGrantRoles } from '@open-mercato/core/modules/auth/lib/grantChecks'\nimport { isOrganizationAccessAllowed } from '@open-mercato/shared/lib/auth/organizationAccess'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\ntype ApiKeyCrudCtx = CrudCtx & {\n __apiKeySecret?: { secret: string; prefix: string }\n __apiKeyHash?: string\n __apiKeyRoleIds?: string[]\n __apiKeyRoles?: Role[]\n __apiKeyOrganizationId?: string | null\n __apiKeyTenantId?: string | null\n}\n\ntype ApiKeyEntityWithMeta = ApiKey & {\n __apiKeySecret?: string\n __apiKeyRoles?: Role[]\n}\n\nconst listQuerySchema = z.object({\n page: z.string().optional(),\n pageSize: z.string().optional(),\n search: z.string().optional(),\n})\n\nconst apiKeyRoleSchema = z.object({\n id: z.string().describe('Role identifier or alias assigned to the key'),\n name: z.string().nullable().describe('Display name of the mapped role, if available'),\n})\n\nconst apiKeyListItemSchema = z.object({\n id: z.string().describe('API key identifier'),\n name: z.string().describe('Friendly label used to identify the key'),\n description: z.string().nullable().describe('Optional free-form description'),\n keyPrefix: z.string().describe('Public prefix exposed to clients'),\n organizationId: z.string().uuid().nullable().describe('Organization scope of the key'),\n organizationName: z.string().nullable().describe('Resolved organization display name'),\n createdAt: z.string().describe('Creation timestamp (ISO 8601)'),\n lastUsedAt: z.string().nullable().describe('Last time the key was observed in use (ISO 8601)'),\n expiresAt: z.string().nullable().describe('When the key expires (ISO 8601)'),\n roles: z.array(apiKeyRoleSchema).describe('Effective roles applied when this key authenticates'),\n})\n\nconst apiKeyCollectionResponseSchema = z.object({\n items: z.array(apiKeyListItemSchema),\n total: z.number().int().nonnegative(),\n page: z.number().int().positive(),\n pageSize: z.number().int().positive(),\n totalPages: z.number().int().nonnegative(),\n})\n\nconst apiKeyCreateResponseSchema = z.object({\n id: z.string().describe('Newly created API key identifier'),\n name: z.string(),\n keyPrefix: z.string(),\n secret: z.string().describe('Full API key value. Shown once for secure persistence.').optional(),\n tenantId: z.string().uuid().nullable(),\n organizationId: z.string().uuid().nullable(),\n roles: z.array(apiKeyRoleSchema),\n})\n\nconst deleteResponseSchema = z.object({\n success: z.literal(true),\n})\n\nconst errorSchema = z.object({\n error: z.string(),\n})\n\nfunction json(payload: unknown, init: ResponseInit = { status: 200 }) {\n return new Response(JSON.stringify(payload), {\n ...init,\n headers: { 'content-type': 'application/json', ...(init.headers || {}) },\n })\n}\n\nconst crud = makeCrudRoute<\n z.infer<typeof createApiKeySchema>,\n never,\n z.infer<typeof listQuerySchema>\n>({\n metadata: {\n GET: { requireAuth: true, requireFeatures: ['api_keys.view'] },\n POST: { requireAuth: true, requireFeatures: ['api_keys.create'] },\n DELETE: { requireAuth: true, requireFeatures: ['api_keys.delete'] },\n },\n orm: { entity: ApiKey, orgField: null },\n list: { schema: listQuerySchema },\n create: {\n schema: createApiKeySchema,\n mapToEntity: (input, ctx) => {\n const scopedCtx = ctx as ApiKeyCrudCtx\n const secretData = scopedCtx.__apiKeySecret\n const keyHash = scopedCtx.__apiKeyHash\n if (!secretData || !keyHash) throw new Error('API key secret not prepared')\n const roleIds = Array.isArray(scopedCtx.__apiKeyRoleIds) ? scopedCtx.__apiKeyRoleIds : []\n const organizationId = scopedCtx.__apiKeyOrganizationId ?? null\n const tenantId = scopedCtx.__apiKeyTenantId ?? null\n return {\n name: input.name,\n description: input.description ?? null,\n tenantId,\n organizationId,\n keyHash,\n keyPrefix: secretData.prefix,\n rolesJson: roleIds,\n createdBy: ctx.auth?.sub ?? null,\n expiresAt: input.expiresAt ?? null,\n }\n },\n response: (entity) => {\n const meta = entity as ApiKeyEntityWithMeta\n const secret = meta.__apiKeySecret\n const roles = meta.__apiKeyRoles\n return {\n id: String(entity.id),\n name: entity.name,\n keyPrefix: entity.keyPrefix,\n secret,\n tenantId: entity.tenantId ?? null,\n organizationId: entity.organizationId ?? null,\n roles: Array.isArray(roles)\n ? roles.map((role) => ({ id: String(role.id), name: role.name ?? null }))\n : (Array.isArray(entity.rolesJson) ? entity.rolesJson.map((id: string) => ({ id, name: null })) : []),\n }\n },\n },\n del: { idFrom: 'query' },\n hooks: {\n beforeList: async (query, ctx) => {\n const auth = ctx.auth\n const { translate } = await resolveTranslations()\n if (!auth?.tenantId) throw json({ error: translate('api_keys.errors.tenantRequired', 'Tenant context required') }, { status: 400 })\n const page = Math.max(parseInt(query.page ?? '1', 10) || 1, 1)\n const pageSize = Math.min(Math.max(parseInt(query.pageSize ?? '20', 10) || 20, 1), 200)\n const search = (query.search ?? '').trim().toLowerCase()\n\n const organizationIds = Array.isArray(ctx.organizationIds) ? ctx.organizationIds : null\n if (organizationIds && organizationIds.length === 0) {\n throw json({ items: [], total: 0, page, pageSize, totalPages: 0 })\n }\n\n const em = (ctx.container.resolve('em') as EntityManager)\n const qb = em.createQueryBuilder(ApiKey, 'k')\n qb.where({ deletedAt: null })\n qb.andWhere({ tenantId: auth.tenantId })\n if (organizationIds && organizationIds.length > 0) {\n qb.andWhere({ organizationId: { $in: organizationIds } })\n } else if (auth.orgId) {\n qb.andWhere({ organizationId: auth.orgId })\n }\n if (search) {\n const pattern = `%${escapeLikePattern(search)}%`\n qb.andWhere({\n $or: [\n { name: { $ilike: pattern } },\n { keyPrefix: { $ilike: pattern } },\n ],\n })\n }\n qb.orderBy({ createdAt: 'desc' })\n qb.limit(pageSize).offset((page - 1) * pageSize)\n const [items, total] = await qb.getResultAndCount()\n\n if (!items.length) {\n throw json({ items: [], total, page, pageSize, totalPages: Math.ceil(total / pageSize) })\n }\n\n const roleIdSet = new Set<string>()\n const orgIdSet = new Set<string>()\n for (const item of items) {\n if (Array.isArray(item.rolesJson)) {\n for (const roleId of item.rolesJson) roleIdSet.add(String(roleId))\n }\n if (item.organizationId) orgIdSet.add(String(item.organizationId))\n }\n\n const roleIdArray = Array.from(roleIdSet)\n const organizationIdArray = Array.from(orgIdSet)\n const roleFilter: FilterQuery<Role> = { id: { $in: roleIdArray } }\n const organizationFilter: FilterQuery<Organization> = { id: { $in: organizationIdArray } }\n const [roles, organizations] = await Promise.all([\n roleIdArray.length ? em.find(Role, roleFilter) : [],\n organizationIdArray.length ? em.find(Organization, organizationFilter) : [],\n ])\n const roleMap = new Map(roles.map((role) => [String(role.id), role.name ?? null]))\n const orgMap = new Map(organizations.map((org) => [String(org.id), org.name ?? null]))\n\n const payload = {\n items: items.map((item) => ({\n id: item.id,\n name: item.name,\n description: item.description ?? null,\n keyPrefix: item.keyPrefix,\n organizationId: item.organizationId ?? null,\n organizationName: item.organizationId ? orgMap.get(String(item.organizationId)) ?? null : null,\n createdAt: item.createdAt,\n lastUsedAt: item.lastUsedAt ?? null,\n expiresAt: item.expiresAt ?? null,\n roles: Array.isArray(item.rolesJson)\n ? item.rolesJson.map((id) => ({ id, name: roleMap.get(String(id)) ?? null }))\n : [],\n })),\n total,\n page,\n pageSize,\n totalPages: Math.ceil(total / pageSize),\n }\n\n throw json(payload)\n },\n beforeCreate: async (input, ctx) => {\n const auth = ctx.auth\n const { translate } = await resolveTranslations()\n if (!auth?.tenantId) throw json({ error: translate('api_keys.errors.tenantRequired', 'Tenant context required') }, { status: 400 })\n\n const requestedTenant = Object.prototype.hasOwnProperty.call(input, 'tenantId') ? input.tenantId : auth.tenantId\n const scopedCtx = ctx as ApiKeyCrudCtx\n const targetTenantId = await enforceTenantSelection(scopedCtx, requestedTenant)\n scopedCtx.__apiKeyTenantId = targetTenantId\n\n const secretData = generateApiKeySecret()\n scopedCtx.__apiKeySecret = secretData\n scopedCtx.__apiKeyHash = await hashApiKey(secretData.secret)\n\n const em = (ctx.container.resolve('em') as EntityManager)\n const roleTokens = Array.isArray(input.roles) ? input.roles.filter((value) => typeof value === 'string' && value.trim().length > 0) : []\n const roleEntities: Role[] = []\n const roleIds: string[] = []\n for (const token of roleTokens) {\n const value = token.trim()\n const rawTenantId = targetTenantId ?? auth.tenantId ?? null\n const effectiveTenantId = typeof rawTenantId === 'string' && rawTenantId.trim().length > 0 ? rawTenantId.trim() : null\n const normalizedEffectiveTenantId = effectiveTenantId ? effectiveTenantId.toLowerCase() : null\n let role: Role | null = null\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)) {\n role = await em.findOne(Role, { id: value, deletedAt: null })\n }\n if (!role) {\n const nameFilter: FilterQuery<Role> = { name: value, deletedAt: null }\n if (normalizedEffectiveTenantId) {\n nameFilter.$or = [\n { tenantId: effectiveTenantId },\n { tenantId: null },\n ]\n } else {\n nameFilter.tenantId = null\n }\n const candidates = await em.find(Role, nameFilter, { limit: 5 })\n if (normalizedEffectiveTenantId) {\n role =\n candidates.find((candidate) => {\n if (!candidate.tenantId) return false\n return String(candidate.tenantId).toLowerCase() === normalizedEffectiveTenantId\n }) ??\n candidates.find((candidate) => candidate.tenantId === null) ??\n null\n } else {\n role = candidates.find((candidate) => candidate.tenantId === null) ?? null\n }\n if (!role) {\n role = candidates[0] ?? null\n }\n }\n if (!role) {\n throw json({ error: translate('api_keys.errors.roleNotFound', `Role ${value} not found`, { identifier: value }) }, { status: 400 })\n }\n const roleTenantId = role.tenantId ? String(role.tenantId) : null\n const normalizedRoleTenantId = roleTenantId ? roleTenantId.toLowerCase() : null\n if (normalizedRoleTenantId && normalizedEffectiveTenantId && normalizedRoleTenantId !== normalizedEffectiveTenantId) {\n throw json({ error: translate('api_keys.errors.roleWrongTenant', `Role ${role.name} belongs to another tenant`, { role: role.name ?? value }) }, { status: 400 })\n }\n roleEntities.push(role)\n roleIds.push(String(role.id))\n }\n await assertActorCanGrantRoles({\n em,\n rbacService: ctx.container.resolve('rbacService') as RbacService,\n actorUserId: auth.sub,\n tenantId: targetTenantId,\n organizationId: auth.orgId ?? null,\n roles: roleEntities,\n })\n scopedCtx.__apiKeyRoles = roleEntities\n scopedCtx.__apiKeyRoleIds = roleIds\n\n const allowedIds = ctx.organizationScope?.allowedIds ?? null\n const organizationId = Object.prototype.hasOwnProperty.call(input, 'organizationId')\n ? input.organizationId ?? null\n : ctx.selectedOrganizationId ?? auth.orgId ?? null\n const isSuperAdmin = await resolveIsSuperAdmin(scopedCtx)\n if (\n !isOrganizationAccessAllowed({\n isSuperAdmin,\n allowedOrganizationIds: allowedIds,\n targetOrganizationId: organizationId,\n })\n ) {\n throw json({ error: translate('api_keys.errors.organizationOutOfScope', 'Organization out of scope') }, { status: 403 })\n }\n scopedCtx.__apiKeyOrganizationId = organizationId ?? null\n\n return { ...input, organizationId }\n },\n afterCreate: async (entity, ctx) => {\n const scopedCtx = ctx as ApiKeyCrudCtx\n const secretData = scopedCtx.__apiKeySecret\n const roles = scopedCtx.__apiKeyRoles\n if (secretData) (entity as ApiKeyEntityWithMeta).__apiKeySecret = secretData.secret\n if (roles) (entity as ApiKeyEntityWithMeta).__apiKeyRoles = roles\n try {\n const rbac = (ctx.container.resolve('rbacService') as RbacService)\n await rbac.invalidateUserCache(`api_key:${entity.id}`)\n } catch {}\n },\n beforeDelete: async (id, ctx) => {\n const auth = ctx.auth\n const { translate } = await resolveTranslations()\n if (!auth?.tenantId) throw json({ error: translate('api_keys.errors.tenantRequired', 'Tenant context required') }, { status: 400 })\n const em = (ctx.container.resolve('em') as EntityManager)\n const scopedCtx = ctx as ApiKeyCrudCtx\n const isSuperAdmin = await resolveIsSuperAdmin(scopedCtx)\n const allowedIds = ctx.organizationScope?.allowedIds ?? null\n const recordFilter: FilterQuery<ApiKey> = {\n id,\n tenantId: auth.tenantId,\n deletedAt: null,\n }\n if (!isSuperAdmin && Array.isArray(allowedIds)) {\n recordFilter.organizationId = { $in: allowedIds }\n }\n const record = await findOneWithDecryption(\n em,\n ApiKey,\n recordFilter,\n undefined,\n { tenantId: auth.tenantId, organizationId: null },\n )\n if (\n !record ||\n record.tenantId !== auth.tenantId ||\n !isOrganizationAccessAllowed({\n isSuperAdmin,\n allowedOrganizationIds: allowedIds,\n targetOrganizationId: record.organizationId ?? null,\n })\n ) {\n throw json({ error: translate('api_keys.errors.notFound', 'Not found') }, { status: 404 })\n }\n scopedCtx.__apiKeyOrganizationId = record.organizationId ?? null\n },\n afterDelete: async (id, ctx) => {\n try {\n const rbac = (ctx.container.resolve('rbacService') as RbacService)\n await rbac.invalidateUserCache(`api_key:${id}`)\n } catch {}\n },\n },\n})\n\nexport const metadata = crud.metadata\nexport const GET = crud.GET\nexport const POST = crud.POST\nexport const DELETE = crud.DELETE\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Manage API keys',\n description:\n 'Provides list, creation, and deletion capabilities for API keys scoped to the authenticated tenant and organization.',\n methods: {\n GET: {\n summary: 'List API keys',\n description:\n 'Returns paginated API keys visible to the current user, including per-key role assignments and organization context.',\n query: listQuerySchema,\n responses: [\n {\n status: 200,\n description: 'Collection of API keys',\n schema: apiKeyCollectionResponseSchema,\n },\n ],\n errors: [\n { status: 400, description: 'Tenant context missing', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 403, description: 'Forbidden by organization scope', schema: errorSchema },\n ],\n },\n POST: {\n summary: 'Create API key',\n description:\n 'Creates a new API key, returning the one-time secret value together with the generated key prefix and scope details.',\n requestBody: {\n contentType: 'application/json',\n schema: createApiKeySchema,\n description: 'API key definition including optional scope and role assignments.',\n },\n responses: [\n {\n status: 201,\n description: 'API key created successfully',\n schema: apiKeyCreateResponseSchema,\n },\n ],\n errors: [\n { status: 400, description: 'Invalid payload or missing tenant context', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 403, description: 'Organization outside allowed scope', schema: errorSchema },\n ],\n },\n DELETE: {\n summary: 'Delete API key',\n description:\n 'Removes an API key by identifier. The key must belong to the current tenant and fall within the requester organization scope.',\n query: z.object({\n id: z.string().uuid().describe('API key identifier to delete'),\n }),\n responses: [\n { status: 200, description: 'Key deleted successfully', schema: deleteResponseSchema },\n ],\n errors: [\n { status: 400, description: 'Missing or invalid identifier', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 403, description: 'Organization outside allowed scope', schema: errorSchema },\n { status: 404, description: 'Key not found within scope', schema: errorSchema },\n ],\n },\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { z } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport type { CrudCtx } from '@open-mercato/shared/lib/crud/factory'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\nimport { Role } from '@open-mercato/core/modules/auth/data/entities'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport { ApiKey } from '../../data/entities'\nimport { createApiKeySchema } from '../../data/validators'\nimport { generateApiKeySecret, hashApiKey } from '../../services/apiKeyService'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { enforceTenantSelection, resolveIsSuperAdmin } from '@open-mercato/core/modules/auth/lib/tenantAccess'\nimport { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'\nimport { assertActorCanGrantRoles } from '@open-mercato/core/modules/auth/lib/grantChecks'\nimport { isOrganizationAccessAllowed } from '@open-mercato/shared/lib/auth/organizationAccess'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\ntype ApiKeyCrudCtx = CrudCtx & {\n __apiKeySecret?: { secret: string; prefix: string }\n __apiKeyHash?: string\n __apiKeyRoleIds?: string[]\n __apiKeyRoles?: Role[]\n __apiKeyOrganizationId?: string | null\n __apiKeyTenantId?: string | null\n}\n\ntype ApiKeyEntityWithMeta = ApiKey & {\n __apiKeySecret?: string\n __apiKeyRoles?: Role[]\n}\n\nconst listQuerySchema = z.object({\n page: z.string().optional(),\n pageSize: z.string().optional(),\n search: z.string().optional(),\n})\n\nconst apiKeyRoleSchema = z.object({\n id: z.string().describe('Role identifier or alias assigned to the key'),\n name: z.string().nullable().describe('Display name of the mapped role, if available'),\n})\n\nconst apiKeyListItemSchema = z.object({\n id: z.string().describe('API key identifier'),\n name: z.string().describe('Friendly label used to identify the key'),\n description: z.string().nullable().describe('Optional free-form description'),\n keyPrefix: z.string().describe('Public prefix exposed to clients'),\n organizationId: z.string().uuid().nullable().describe('Organization scope of the key'),\n organizationName: z.string().nullable().describe('Resolved organization display name'),\n createdAt: z.string().describe('Creation timestamp (ISO 8601)'),\n lastUsedAt: z.string().nullable().describe('Last time the key was observed in use (ISO 8601)'),\n expiresAt: z.string().nullable().describe('When the key expires (ISO 8601)'),\n roles: z.array(apiKeyRoleSchema).describe('Effective roles applied when this key authenticates'),\n})\n\nconst apiKeyCollectionResponseSchema = z.object({\n items: z.array(apiKeyListItemSchema),\n total: z.number().int().nonnegative(),\n page: z.number().int().positive(),\n pageSize: z.number().int().positive(),\n totalPages: z.number().int().nonnegative(),\n})\n\nconst apiKeyCreateResponseSchema = z.object({\n id: z.string().describe('Newly created API key identifier'),\n name: z.string(),\n keyPrefix: z.string(),\n secret: z.string().describe('Full API key value. Shown once for secure persistence.').optional(),\n tenantId: z.string().uuid().nullable(),\n organizationId: z.string().uuid().nullable(),\n roles: z.array(apiKeyRoleSchema),\n})\n\nconst deleteResponseSchema = z.object({\n success: z.literal(true),\n})\n\nconst errorSchema = z.object({\n error: z.string(),\n})\n\nfunction json(payload: unknown, init: ResponseInit = { status: 200 }) {\n return new Response(JSON.stringify(payload), {\n ...init,\n headers: { 'content-type': 'application/json', ...(init.headers || {}) },\n })\n}\n\nconst crud = makeCrudRoute<\n z.infer<typeof createApiKeySchema>,\n never,\n z.infer<typeof listQuerySchema>\n>({\n metadata: {\n GET: { requireAuth: true, requireFeatures: ['api_keys.view'] },\n POST: { requireAuth: true, requireFeatures: ['api_keys.create'] },\n DELETE: { requireAuth: true, requireFeatures: ['api_keys.delete'] },\n },\n orm: { entity: ApiKey, orgField: null },\n list: { schema: listQuerySchema },\n create: {\n schema: createApiKeySchema,\n mapToEntity: (input, ctx) => {\n const scopedCtx = ctx as ApiKeyCrudCtx\n const secretData = scopedCtx.__apiKeySecret\n const keyHash = scopedCtx.__apiKeyHash\n if (!secretData || !keyHash) throw new Error('API key secret not prepared')\n const roleIds = Array.isArray(scopedCtx.__apiKeyRoleIds) ? scopedCtx.__apiKeyRoleIds : []\n const organizationId = scopedCtx.__apiKeyOrganizationId ?? null\n const tenantId = scopedCtx.__apiKeyTenantId ?? null\n return {\n name: input.name,\n description: input.description ?? null,\n tenantId,\n organizationId,\n keyHash,\n keyPrefix: secretData.prefix,\n rolesJson: roleIds,\n createdBy: ctx.auth?.sub ?? null,\n expiresAt: input.expiresAt ?? null,\n }\n },\n response: (entity) => {\n const meta = entity as ApiKeyEntityWithMeta\n const secret = meta.__apiKeySecret\n const roles = meta.__apiKeyRoles\n return {\n id: String(entity.id),\n name: entity.name,\n keyPrefix: entity.keyPrefix,\n secret,\n tenantId: entity.tenantId ?? null,\n organizationId: entity.organizationId ?? null,\n roles: Array.isArray(roles)\n ? roles.map((role) => ({ id: String(role.id), name: role.name ?? null }))\n : (Array.isArray(entity.rolesJson) ? entity.rolesJson.map((id: string) => ({ id, name: null })) : []),\n }\n },\n },\n del: { idFrom: 'query' },\n hooks: {\n beforeList: async (query, ctx) => {\n const auth = ctx.auth\n const { translate } = await resolveTranslations()\n if (!auth?.tenantId) throw json({ error: translate('api_keys.errors.tenantRequired', 'Tenant context required') }, { status: 400 })\n const page = Math.max(parseInt(query.page ?? '1', 10) || 1, 1)\n const pageSize = Math.min(Math.max(parseInt(query.pageSize ?? '20', 10) || 20, 1), 200)\n const search = (query.search ?? '').trim().toLowerCase()\n\n const organizationIds = Array.isArray(ctx.organizationIds) ? ctx.organizationIds : null\n if (organizationIds && organizationIds.length === 0) {\n throw json({ items: [], total: 0, page, pageSize, totalPages: 0 })\n }\n\n const em = (ctx.container.resolve('em') as EntityManager)\n const qb = em.createQueryBuilder(ApiKey, 'k')\n qb.where({ deletedAt: null })\n qb.andWhere({ tenantId: auth.tenantId })\n if (organizationIds && organizationIds.length > 0) {\n qb.andWhere({ organizationId: { $in: organizationIds } })\n } else if (auth.orgId) {\n qb.andWhere({ organizationId: auth.orgId })\n }\n if (search) {\n const pattern = `%${escapeLikePattern(search)}%`\n qb.andWhere({\n $or: [\n { name: { $ilike: pattern } },\n { keyPrefix: { $ilike: pattern } },\n ],\n })\n }\n qb.orderBy({ createdAt: 'desc' })\n qb.limit(pageSize).offset((page - 1) * pageSize)\n const [items, total] = await qb.getResultAndCount()\n\n if (!items.length) {\n throw json({ items: [], total, page, pageSize, totalPages: Math.ceil(total / pageSize) })\n }\n\n const roleIdSet = new Set<string>()\n const orgIdSet = new Set<string>()\n for (const item of items) {\n if (Array.isArray(item.rolesJson)) {\n for (const roleId of item.rolesJson) roleIdSet.add(String(roleId))\n }\n if (item.organizationId) orgIdSet.add(String(item.organizationId))\n }\n\n const roleIdArray = Array.from(roleIdSet)\n const organizationIdArray = Array.from(orgIdSet)\n const roleFilter: FilterQuery<Role> = { id: { $in: roleIdArray } }\n const organizationFilter: FilterQuery<Organization> = { id: { $in: organizationIdArray } }\n const [roles, organizations] = await Promise.all([\n roleIdArray.length ? em.find(Role, roleFilter) : [],\n organizationIdArray.length ? em.find(Organization, organizationFilter) : [],\n ])\n const roleMap = new Map(roles.map((role) => [String(role.id), role.name ?? null]))\n const orgMap = new Map(organizations.map((org) => [String(org.id), org.name ?? null]))\n\n const payload = {\n items: items.map((item) => ({\n id: item.id,\n name: item.name,\n description: item.description ?? null,\n keyPrefix: item.keyPrefix,\n organizationId: item.organizationId ?? null,\n organizationName: item.organizationId ? orgMap.get(String(item.organizationId)) ?? null : null,\n createdAt: item.createdAt,\n lastUsedAt: item.lastUsedAt ?? null,\n expiresAt: item.expiresAt ?? null,\n roles: Array.isArray(item.rolesJson)\n ? item.rolesJson.map((id) => ({ id, name: roleMap.get(String(id)) ?? null }))\n : [],\n })),\n total,\n page,\n pageSize,\n totalPages: Math.ceil(total / pageSize),\n }\n\n throw json(payload)\n },\n beforeCreate: async (input, ctx) => {\n const auth = ctx.auth\n const { translate } = await resolveTranslations()\n if (!auth?.tenantId) throw json({ error: translate('api_keys.errors.tenantRequired', 'Tenant context required') }, { status: 400 })\n\n const requestedTenant = Object.prototype.hasOwnProperty.call(input, 'tenantId') ? input.tenantId : auth.tenantId\n const scopedCtx = ctx as ApiKeyCrudCtx\n const targetTenantId = await enforceTenantSelection(scopedCtx, requestedTenant)\n scopedCtx.__apiKeyTenantId = targetTenantId\n\n const secretData = generateApiKeySecret()\n scopedCtx.__apiKeySecret = secretData\n scopedCtx.__apiKeyHash = await hashApiKey(secretData.secret)\n\n const em = (ctx.container.resolve('em') as EntityManager)\n const roleTokens = Array.isArray(input.roles) ? input.roles.filter((value) => typeof value === 'string' && value.trim().length > 0) : []\n const roleEntities: Role[] = []\n const roleIds: string[] = []\n for (const token of roleTokens) {\n const value = token.trim()\n const rawTenantId = targetTenantId ?? auth.tenantId ?? null\n const effectiveTenantId = typeof rawTenantId === 'string' && rawTenantId.trim().length > 0 ? rawTenantId.trim() : null\n const normalizedEffectiveTenantId = effectiveTenantId ? effectiveTenantId.toLowerCase() : null\n let role: Role | null = null\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)) {\n role = await em.findOne(Role, { id: value, deletedAt: null })\n }\n if (!role) {\n const nameFilter: FilterQuery<Role> = { name: value, deletedAt: null }\n if (normalizedEffectiveTenantId) {\n nameFilter.$or = [\n { tenantId: effectiveTenantId },\n { tenantId: null },\n ]\n } else {\n nameFilter.tenantId = null\n }\n const candidates = await em.find(Role, nameFilter, { limit: 5 })\n if (normalizedEffectiveTenantId) {\n role =\n candidates.find((candidate) => {\n if (!candidate.tenantId) return false\n return String(candidate.tenantId).toLowerCase() === normalizedEffectiveTenantId\n }) ??\n candidates.find((candidate) => candidate.tenantId === null) ??\n null\n } else {\n role = candidates.find((candidate) => candidate.tenantId === null) ?? null\n }\n if (!role) {\n role = candidates[0] ?? null\n }\n }\n if (!role) {\n throw json({ error: translate('api_keys.errors.roleNotFound', `Role ${value} not found`, { identifier: value }) }, { status: 400 })\n }\n const roleTenantId = role.tenantId ? String(role.tenantId) : null\n const normalizedRoleTenantId = roleTenantId ? roleTenantId.toLowerCase() : null\n if (normalizedRoleTenantId && normalizedEffectiveTenantId && normalizedRoleTenantId !== normalizedEffectiveTenantId) {\n throw json({ error: translate('api_keys.errors.roleWrongTenant', `Role ${role.name} belongs to another tenant`, { role: role.name ?? value }) }, { status: 400 })\n }\n roleEntities.push(role)\n roleIds.push(String(role.id))\n }\n await assertActorCanGrantRoles({\n em,\n rbacService: ctx.container.resolve('rbacService') as RbacService,\n actorUserId: auth.sub,\n tenantId: targetTenantId,\n organizationId: auth.orgId ?? null,\n roles: roleEntities,\n })\n scopedCtx.__apiKeyRoles = roleEntities\n scopedCtx.__apiKeyRoleIds = roleIds\n\n const allowedIds = ctx.organizationScope?.allowedIds ?? null\n const organizationId = input.organizationId ?? ctx.selectedOrganizationId ?? auth.orgId ?? null\n const isSuperAdmin = await resolveIsSuperAdmin(scopedCtx)\n if (\n !isOrganizationAccessAllowed({\n isSuperAdmin,\n allowedOrganizationIds: allowedIds,\n targetOrganizationId: organizationId,\n })\n ) {\n throw json({ error: translate('api_keys.errors.organizationOutOfScope', 'Organization out of scope') }, { status: 403 })\n }\n scopedCtx.__apiKeyOrganizationId = organizationId ?? null\n\n return { ...input, organizationId }\n },\n afterCreate: async (entity, ctx) => {\n const scopedCtx = ctx as ApiKeyCrudCtx\n const secretData = scopedCtx.__apiKeySecret\n const roles = scopedCtx.__apiKeyRoles\n if (secretData) (entity as ApiKeyEntityWithMeta).__apiKeySecret = secretData.secret\n if (roles) (entity as ApiKeyEntityWithMeta).__apiKeyRoles = roles\n try {\n const rbac = (ctx.container.resolve('rbacService') as RbacService)\n await rbac.invalidateUserCache(`api_key:${entity.id}`)\n } catch {}\n },\n beforeDelete: async (id, ctx) => {\n const auth = ctx.auth\n const { translate } = await resolveTranslations()\n if (!auth?.tenantId) throw json({ error: translate('api_keys.errors.tenantRequired', 'Tenant context required') }, { status: 400 })\n const em = (ctx.container.resolve('em') as EntityManager)\n const scopedCtx = ctx as ApiKeyCrudCtx\n const isSuperAdmin = await resolveIsSuperAdmin(scopedCtx)\n const allowedIds = ctx.organizationScope?.allowedIds ?? null\n const recordFilter: FilterQuery<ApiKey> = {\n id,\n tenantId: auth.tenantId,\n deletedAt: null,\n }\n if (!isSuperAdmin && Array.isArray(allowedIds)) {\n recordFilter.organizationId = { $in: allowedIds }\n }\n const record = await findOneWithDecryption(\n em,\n ApiKey,\n recordFilter,\n undefined,\n { tenantId: auth.tenantId, organizationId: null },\n )\n if (\n !record ||\n record.tenantId !== auth.tenantId ||\n !isOrganizationAccessAllowed({\n isSuperAdmin,\n allowedOrganizationIds: allowedIds,\n targetOrganizationId: record.organizationId ?? null,\n })\n ) {\n throw json({ error: translate('api_keys.errors.notFound', 'Not found') }, { status: 404 })\n }\n scopedCtx.__apiKeyOrganizationId = record.organizationId ?? null\n },\n afterDelete: async (id, ctx) => {\n try {\n const rbac = (ctx.container.resolve('rbacService') as RbacService)\n await rbac.invalidateUserCache(`api_key:${id}`)\n } catch {}\n },\n },\n})\n\nexport const metadata = crud.metadata\nexport const GET = crud.GET\nexport const POST = crud.POST\nexport const DELETE = crud.DELETE\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Manage API keys',\n description:\n 'Provides list, creation, and deletion capabilities for API keys scoped to the authenticated tenant and organization.',\n methods: {\n GET: {\n summary: 'List API keys',\n description:\n 'Returns paginated API keys visible to the current user, including per-key role assignments and organization context.',\n query: listQuerySchema,\n responses: [\n {\n status: 200,\n description: 'Collection of API keys',\n schema: apiKeyCollectionResponseSchema,\n },\n ],\n errors: [\n { status: 400, description: 'Tenant context missing', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 403, description: 'Forbidden by organization scope', schema: errorSchema },\n ],\n },\n POST: {\n summary: 'Create API key',\n description:\n 'Creates a new API key, returning the one-time secret value together with the generated key prefix and scope details.',\n requestBody: {\n contentType: 'application/json',\n schema: createApiKeySchema,\n description: 'API key definition including optional scope and role assignments.',\n },\n responses: [\n {\n status: 201,\n description: 'API key created successfully',\n schema: apiKeyCreateResponseSchema,\n },\n ],\n errors: [\n { status: 400, description: 'Invalid payload or missing tenant context', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 403, description: 'Organization outside allowed scope', schema: errorSchema },\n ],\n },\n DELETE: {\n summary: 'Delete API key',\n description:\n 'Removes an API key by identifier. The key must belong to the current tenant and fall within the requester organization scope.',\n query: z.object({\n id: z.string().uuid().describe('API key identifier to delete'),\n }),\n responses: [\n { status: 200, description: 'Key deleted successfully', schema: deleteResponseSchema },\n ],\n errors: [\n { status: 400, description: 'Missing or invalid identifier', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 403, description: 'Organization outside allowed scope', schema: errorSchema },\n { status: 404, description: 'Key not found within scope', schema: errorSchema },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -29,7 +29,6 @@ function ApiKeysListPage() {
29
29
  const [page, setPage] = React.useState(1);
30
30
  const [total, setTotal] = React.useState(0);
31
31
  const [totalPages, setTotalPages] = React.useState(1);
32
- const [totalIsCapped, setTotalIsCapped] = React.useState(false);
33
32
  const [search, setSearch] = React.useState("");
34
33
  const [isLoading, setIsLoading] = React.useState(true);
35
34
  const [reloadToken, setReloadToken] = React.useState(0);
@@ -62,7 +61,6 @@ function ApiKeysListPage() {
62
61
  setRows(Array.isArray(payload.items) ? payload.items : []);
63
62
  setTotal(payload.total || 0);
64
63
  setTotalPages(payload.totalPages || 1);
65
- setTotalIsCapped(payload?.totalIsCapped === true);
66
64
  }
67
65
  } catch (error) {
68
66
  if (!cancelled) {
@@ -174,7 +172,7 @@ function ApiKeysListPage() {
174
172
  createLabel: t("api_keys.list.actions.create")
175
173
  }
176
174
  ),
177
- pagination: { page, pageSize: 20, total, totalPages, totalIsCapped, onPageChange: setPage },
175
+ pagination: { page, pageSize: 20, total, totalPages, onPageChange: setPage },
178
176
  isLoading
179
177
  }
180
178
  ) }),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/api_keys/backend/api-keys/page.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/api_keys/extension-points'\nimport Link from 'next/link'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\ntype RoleSummary = { id: string; name: string | null }\n\ntype Row = {\n id: string\n name: string\n description: string | null\n keyPrefix: string\n organizationId: string | null\n organizationName: string | null\n createdAt: string\n lastUsedAt: string | null\n expiresAt: string | null\n roles: RoleSummary[]\n updatedAt?: string | null\n}\n\ntype ResponsePayload = {\n items: Row[]\n total: number\n page: number\n totalPages: number\n totalIsCapped?: boolean\n}\n\nfunction formatDate(value: string | null, t: (key: string, params?: Record<string, string | number>) => string) {\n if (!value) return t('api_keys.list.noDate')\n try {\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return t('api_keys.list.noDate')\n return date.toLocaleString()\n } catch {\n return t('api_keys.list.noDate')\n }\n}\n\nexport default function ApiKeysListPage() {\n const [rows, setRows] = React.useState<Row[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [totalIsCapped, setTotalIsCapped] = React.useState(false)\n const [search, setSearch] = React.useState('')\n const [isLoading, setIsLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const scopeVersion = useOrganizationScopeVersion()\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n try {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', '20')\n if (search) params.set('search', search)\n const fallback: ResponsePayload = { items: [], total: 0, page, totalPages: 1 }\n const call = await apiCall<ResponsePayload>(\n `/api/api_keys/keys?${params.toString()}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('api_keys.list.error.loadFailed')\n flash(message, 'error')\n return\n }\n const payload = call.result ?? fallback\n if (!cancelled) {\n setRows(Array.isArray(payload.items) ? payload.items : [])\n setTotal(payload.total || 0)\n setTotalPages(payload.totalPages || 1)\n setTotalIsCapped(payload?.totalIsCapped === true)\n }\n } catch (error) {\n if (!cancelled) {\n const message = error instanceof Error ? error.message : t('api_keys.list.error.loadFailed')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [page, search, reloadToken, scopeVersion, t])\n\n const handleDelete = React.useCallback(async (row: Row) => {\n const confirmed = await confirm({\n title: t('api_keys.list.confirmDelete', { name: row.name }),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n const call = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(row.updatedAt),\n () => apiCall<{ error?: string }>(\n `/api/api_keys/keys?id=${encodeURIComponent(row.id)}`,\n { method: 'DELETE' },\n { fallback: null },\n ),\n )\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('api_keys.list.error.deleteFailed')\n flash(message, 'error')\n return\n }\n flash(t('api_keys.list.success.deleted'), 'success')\n setReloadToken((token) => token + 1)\n } catch (error) {\n const message = error instanceof Error ? error.message : t('api_keys.list.error.deleteFailed')\n flash(message, 'error')\n }\n }, [confirm, t])\n\n const columns = React.useMemo<ColumnDef<Row>[]>(() => [\n { accessorKey: 'name', header: t('api_keys.list.columns.name') },\n {\n accessorKey: 'keyPrefix',\n header: t('api_keys.list.columns.key'),\n cell: ({ row }) => <code className=\"text-xs\">{row.original.keyPrefix}\u2026</code>,\n },\n {\n accessorKey: 'organizationName',\n header: t('api_keys.list.columns.organization'),\n cell: ({ row }) => row.original.organizationName || t('api_keys.list.noDate'),\n },\n {\n accessorKey: 'roles',\n header: t('api_keys.list.columns.roles'),\n cell: ({ row }) => (\n <div className=\"flex flex-wrap gap-1\">\n {row.original.roles.length === 0 && <span className=\"text-muted-foreground text-xs\">{t('api_keys.list.noRoles')}</span>}\n {row.original.roles.map((role) => (\n <span\n key={role.id}\n className=\"inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium\"\n >\n {role.name || role.id}\n </span>\n ))}\n </div>\n ),\n },\n {\n accessorKey: 'lastUsedAt',\n header: t('api_keys.list.columns.lastUsed'),\n cell: ({ row }) => formatDate(row.original.lastUsedAt, t),\n },\n {\n accessorKey: 'expiresAt',\n header: t('api_keys.list.columns.expires'),\n cell: ({ row }) => formatDate(row.original.expiresAt, t),\n },\n ], [t])\n\n return (\n <Page>\n <PageBody>\n <DataTable\n title={t('api_keys.list.title')}\n actions={(\n <Button asChild>\n <Link href=\"/backend/api-keys/create\">{t('api_keys.list.actions.create')}</Link>\n </Button>\n )}\n columns={columns}\n data={rows}\n searchValue={search}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n perspective={{ tableId: extensionPoints.hosts.apiKeysTable.tableId }}\n rowActions={(row) => (\n <RowActions items={[\n { id: 'delete', label: t('common.delete'), destructive: true, onSelect: () => { void handleDelete(row) } },\n ]} />\n )}\n emptyState={(\n <ListEmptyState\n entityName={t('api_keys.list.title')}\n createHref=\"/backend/api-keys/create\"\n createLabel={t('api_keys.list.actions.create')}\n />\n )}\n pagination={{ page, pageSize: 20, total, totalPages, totalIsCapped, onPageChange: setPage }}\n isLoading={isLoading}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/api_keys/extension-points'\nimport Link from 'next/link'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\n\ntype RoleSummary = { id: string; name: string | null }\n\ntype Row = {\n id: string\n name: string\n description: string | null\n keyPrefix: string\n organizationId: string | null\n organizationName: string | null\n createdAt: string\n lastUsedAt: string | null\n expiresAt: string | null\n roles: RoleSummary[]\n updatedAt?: string | null\n}\n\ntype ResponsePayload = {\n items: Row[]\n total: number\n page: number\n totalPages: number\n}\n\nfunction formatDate(value: string | null, t: (key: string, params?: Record<string, string | number>) => string) {\n if (!value) return t('api_keys.list.noDate')\n try {\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return t('api_keys.list.noDate')\n return date.toLocaleString()\n } catch {\n return t('api_keys.list.noDate')\n }\n}\n\nexport default function ApiKeysListPage() {\n const [rows, setRows] = React.useState<Row[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState('')\n const [isLoading, setIsLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const scopeVersion = useOrganizationScopeVersion()\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n try {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', '20')\n if (search) params.set('search', search)\n const fallback: ResponsePayload = { items: [], total: 0, page, totalPages: 1 }\n const call = await apiCall<ResponsePayload>(\n `/api/api_keys/keys?${params.toString()}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('api_keys.list.error.loadFailed')\n flash(message, 'error')\n return\n }\n const payload = call.result ?? fallback\n if (!cancelled) {\n setRows(Array.isArray(payload.items) ? payload.items : [])\n setTotal(payload.total || 0)\n setTotalPages(payload.totalPages || 1)\n }\n } catch (error) {\n if (!cancelled) {\n const message = error instanceof Error ? error.message : t('api_keys.list.error.loadFailed')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [page, search, reloadToken, scopeVersion, t])\n\n const handleDelete = React.useCallback(async (row: Row) => {\n const confirmed = await confirm({\n title: t('api_keys.list.confirmDelete', { name: row.name }),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n const call = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(row.updatedAt),\n () => apiCall<{ error?: string }>(\n `/api/api_keys/keys?id=${encodeURIComponent(row.id)}`,\n { method: 'DELETE' },\n { fallback: null },\n ),\n )\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('api_keys.list.error.deleteFailed')\n flash(message, 'error')\n return\n }\n flash(t('api_keys.list.success.deleted'), 'success')\n setReloadToken((token) => token + 1)\n } catch (error) {\n const message = error instanceof Error ? error.message : t('api_keys.list.error.deleteFailed')\n flash(message, 'error')\n }\n }, [confirm, t])\n\n const columns = React.useMemo<ColumnDef<Row>[]>(() => [\n { accessorKey: 'name', header: t('api_keys.list.columns.name') },\n {\n accessorKey: 'keyPrefix',\n header: t('api_keys.list.columns.key'),\n cell: ({ row }) => <code className=\"text-xs\">{row.original.keyPrefix}\u2026</code>,\n },\n {\n accessorKey: 'organizationName',\n header: t('api_keys.list.columns.organization'),\n cell: ({ row }) => row.original.organizationName || t('api_keys.list.noDate'),\n },\n {\n accessorKey: 'roles',\n header: t('api_keys.list.columns.roles'),\n cell: ({ row }) => (\n <div className=\"flex flex-wrap gap-1\">\n {row.original.roles.length === 0 && <span className=\"text-muted-foreground text-xs\">{t('api_keys.list.noRoles')}</span>}\n {row.original.roles.map((role) => (\n <span\n key={role.id}\n className=\"inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium\"\n >\n {role.name || role.id}\n </span>\n ))}\n </div>\n ),\n },\n {\n accessorKey: 'lastUsedAt',\n header: t('api_keys.list.columns.lastUsed'),\n cell: ({ row }) => formatDate(row.original.lastUsedAt, t),\n },\n {\n accessorKey: 'expiresAt',\n header: t('api_keys.list.columns.expires'),\n cell: ({ row }) => formatDate(row.original.expiresAt, t),\n },\n ], [t])\n\n return (\n <Page>\n <PageBody>\n <DataTable\n title={t('api_keys.list.title')}\n actions={(\n <Button asChild>\n <Link href=\"/backend/api-keys/create\">{t('api_keys.list.actions.create')}</Link>\n </Button>\n )}\n columns={columns}\n data={rows}\n searchValue={search}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n perspective={{ tableId: extensionPoints.hosts.apiKeysTable.tableId }}\n rowActions={(row) => (\n <RowActions items={[\n { id: 'delete', label: t('common.delete'), destructive: true, onSelect: () => { void handleDelete(row) } },\n ]} />\n )}\n emptyState={(\n <ListEmptyState\n entityName={t('api_keys.list.title')}\n createHref=\"/backend/api-keys/create\"\n createLabel={t('api_keys.list.actions.create')}\n />\n )}\n pagination={{ page, pageSize: 20, total, totalPages, onPageChange: setPage }}\n isLoading={isLoading}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -189,7 +189,7 @@ async function GET(req) {
189
189
  const currentPage = usePaging ? Math.max(1, page) : null;
190
190
  const currentPageSize = usePaging ? pageSize : null;
191
191
  const totalPages = usePaging && total !== null ? Math.max(1, Math.ceil(total / currentPageSize)) : null;
192
- const pageOffset = usePaging ? (currentPage - 1) * currentPageSize : void 0;
192
+ const pageOffset = usePaging ? (Math.min(currentPage, totalPages) - 1) * currentPageSize : void 0;
193
193
  const items = await findWithDecryption(
194
194
  em,
195
195
  Attachment,
@@ -229,7 +229,7 @@ async function GET(req) {
229
229
  }),
230
230
  ...usePaging ? {
231
231
  total,
232
- page: currentPage,
232
+ page: Math.min(currentPage, totalPages),
233
233
  pageSize: currentPageSize,
234
234
  totalPages
235
235
  } : {}