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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (847) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/helpers/integration/api.js +13 -1
  3. package/dist/helpers/integration/api.js.map +2 -2
  4. package/dist/helpers/integration/communicationChannelsFixtures.js +19 -0
  5. package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
  6. package/dist/modules/api_keys/api/keys/route.js +1 -1
  7. package/dist/modules/api_keys/api/keys/route.js.map +2 -2
  8. package/dist/modules/api_keys/backend/api-keys/page.js +3 -1
  9. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  10. package/dist/modules/api_keys/di.js +9 -0
  11. package/dist/modules/api_keys/di.js.map +7 -0
  12. package/dist/modules/api_keys/services/principalService.js +31 -0
  13. package/dist/modules/api_keys/services/principalService.js.map +7 -0
  14. package/dist/modules/attachments/api/route.js +2 -2
  15. package/dist/modules/attachments/api/route.js.map +2 -2
  16. package/dist/modules/attachments/components/AttachmentLibrary.js +2 -0
  17. package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
  18. package/dist/modules/attachments/di.js +11 -1
  19. package/dist/modules/attachments/di.js.map +2 -2
  20. package/dist/modules/attachments/index.js.map +1 -1
  21. package/dist/modules/attachments/lib/attachment-service.js +313 -0
  22. package/dist/modules/attachments/lib/attachment-service.js.map +7 -0
  23. package/dist/modules/attachments/lib/scoped-upload-service.js +15 -2
  24. package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
  25. package/dist/modules/attachments/lib/upload-limits.js +6 -2
  26. package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
  27. package/dist/modules/audit_logs/backend/audit-logs/page.js +6 -0
  28. package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
  29. package/dist/modules/audit_logs/lib/display-helpers.js +19 -11
  30. package/dist/modules/audit_logs/lib/display-helpers.js.map +2 -2
  31. package/dist/modules/audit_logs/services/actionLogService.js +57 -12
  32. package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
  33. package/dist/modules/auth/acl.js +30 -5
  34. package/dist/modules/auth/acl.js.map +2 -2
  35. package/dist/modules/auth/api/feature-check.js +8 -2
  36. package/dist/modules/auth/api/feature-check.js.map +2 -2
  37. package/dist/modules/auth/api/login.js +4 -1
  38. package/dist/modules/auth/api/login.js.map +2 -2
  39. package/dist/modules/auth/api/reset/validate.js +55 -0
  40. package/dist/modules/auth/api/reset/validate.js.map +7 -0
  41. package/dist/modules/auth/api/roles/acl/route.js +28 -33
  42. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  43. package/dist/modules/auth/api/session/refresh.js +25 -1
  44. package/dist/modules/auth/api/session/refresh.js.map +2 -2
  45. package/dist/modules/auth/api/users/acl/route.js +96 -51
  46. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  47. package/dist/modules/auth/api/users/route.js +13 -5
  48. package/dist/modules/auth/api/users/route.js.map +2 -2
  49. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js +5 -1
  50. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js.map +2 -2
  51. package/dist/modules/auth/backend/roles/page.js +3 -1
  52. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  53. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js +5 -1
  54. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js.map +2 -2
  55. package/dist/modules/auth/backend/users/page.js +2 -1
  56. package/dist/modules/auth/backend/users/page.js.map +2 -2
  57. package/dist/modules/auth/commands/acl.js +254 -0
  58. package/dist/modules/auth/commands/acl.js.map +7 -0
  59. package/dist/modules/auth/components/AclEditor.js +39 -30
  60. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  61. package/dist/modules/auth/data/entities.js.map +2 -2
  62. package/dist/modules/auth/data/validators.js +5 -1
  63. package/dist/modules/auth/data/validators.js.map +2 -2
  64. package/dist/modules/auth/di.js +35 -9
  65. package/dist/modules/auth/di.js.map +2 -2
  66. package/dist/modules/auth/frontend/reset/[token]/page.js +46 -0
  67. package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
  68. package/dist/modules/auth/lib/grantChecks.js.map +2 -2
  69. package/dist/modules/auth/lib/userIdFilter.js +16 -0
  70. package/dist/modules/auth/lib/userIdFilter.js.map +7 -0
  71. package/dist/modules/auth/services/authService.js +16 -2
  72. package/dist/modules/auth/services/authService.js.map +2 -2
  73. package/dist/modules/auth/services/principalService.js +200 -0
  74. package/dist/modules/auth/services/principalService.js.map +7 -0
  75. package/dist/modules/auth/services/rbacService.js +67 -24
  76. package/dist/modules/auth/services/rbacService.js.map +3 -3
  77. package/dist/modules/auth/services/roleOrganizationScope.js +41 -0
  78. package/dist/modules/auth/services/roleOrganizationScope.js.map +7 -0
  79. package/dist/modules/business_rules/backend/logs/page.js +3 -1
  80. package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
  81. package/dist/modules/business_rules/backend/rules/page.js +3 -1
  82. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  83. package/dist/modules/business_rules/backend/sets/page.js +3 -1
  84. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  85. package/dist/modules/business_rules/lib/expression-evaluator.js +9 -9
  86. package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
  87. package/dist/modules/business_rules/lib/rule-evaluator.js +10 -9
  88. package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
  89. package/dist/modules/catalog/ai-agents.js +1 -1
  90. package/dist/modules/catalog/ai-agents.js.map +1 -1
  91. package/dist/modules/catalog/ai-tools/merchandising-pack.js +2 -2
  92. package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
  93. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +5 -2
  94. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
  95. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -0
  96. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  97. package/dist/modules/catalog/components/products/ProductsDataTable.js +7 -1
  98. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  99. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js +2 -0
  100. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js.map +2 -2
  101. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +9 -1
  102. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +2 -2
  103. package/dist/modules/communication_channels/api/post/test-seed/route.js +95 -10
  104. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  105. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +3 -0
  106. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
  107. package/dist/modules/communication_channels/commands/ingest-inbound-message.js +14 -1
  108. package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
  109. package/dist/modules/communication_channels/di.js +7 -1
  110. package/dist/modules/communication_channels/di.js.map +2 -2
  111. package/dist/modules/communication_channels/lib/email-capabilities.js +4 -1
  112. package/dist/modules/communication_channels/lib/email-capabilities.js.map +2 -2
  113. package/dist/modules/communication_channels/lib/outbound-recipient.js +33 -0
  114. package/dist/modules/communication_channels/lib/outbound-recipient.js.map +7 -0
  115. package/dist/modules/communication_channels/lib/resolve-channel-type.js +51 -0
  116. package/dist/modules/communication_channels/lib/resolve-channel-type.js.map +7 -0
  117. package/dist/modules/communication_channels/lib/test-seed.js +41 -2
  118. package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
  119. package/dist/modules/configs/lib/system-status.js +9 -0
  120. package/dist/modules/configs/lib/system-status.js.map +2 -2
  121. package/dist/modules/currencies/backend/currencies/page.js +3 -1
  122. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  123. package/dist/modules/currencies/backend/exchange-rates/page.js +3 -1
  124. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  125. package/dist/modules/currencies/services/rateFetchingService.js +6 -1
  126. package/dist/modules/currencies/services/rateFetchingService.js.map +2 -2
  127. package/dist/modules/customer_accounts/api/admin/domain-mappings.js +9 -0
  128. package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +2 -2
  129. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +3 -1
  130. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  131. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +3 -1
  132. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +2 -2
  133. package/dist/modules/customer_accounts/services/domainMappingService.js +10 -0
  134. package/dist/modules/customer_accounts/services/domainMappingService.js.map +2 -2
  135. package/dist/modules/customers/ai-tools/companies-pack.js +4 -1
  136. package/dist/modules/customers/ai-tools/companies-pack.js.map +2 -2
  137. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +13 -2
  138. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +2 -2
  139. package/dist/modules/customers/ai-tools/deals-pack.js +52 -6
  140. package/dist/modules/customers/ai-tools/deals-pack.js.map +2 -2
  141. package/dist/modules/customers/ai-tools/people-pack.js +4 -1
  142. package/dist/modules/customers/ai-tools/people-pack.js.map +2 -2
  143. package/dist/modules/customers/api/activities/route.js +48 -6
  144. package/dist/modules/customers/api/activities/route.js.map +2 -2
  145. package/dist/modules/customers/api/companies/[id]/people/route.js +20 -64
  146. package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
  147. package/dist/modules/customers/api/companies/[id]/route.js +17 -94
  148. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  149. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +8 -5
  150. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
  151. package/dist/modules/customers/api/deals/[id]/companies/route.js +1 -1
  152. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
  153. package/dist/modules/customers/api/deals/[id]/people/route.js +1 -1
  154. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  155. package/dist/modules/customers/api/deals/[id]/route.js +8 -25
  156. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  157. package/dist/modules/customers/api/deals/[id]/stats/route.js +3 -22
  158. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +2 -2
  159. package/dist/modules/customers/api/deals/aggregate/route.js +11 -4
  160. package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
  161. package/dist/modules/customers/api/deals/map/route.js +2 -1
  162. package/dist/modules/customers/api/deals/map/route.js.map +2 -2
  163. package/dist/modules/customers/api/deals/route.js +38 -1
  164. package/dist/modules/customers/api/deals/route.js.map +2 -2
  165. package/dist/modules/customers/api/entity-roles-factory.js +4 -4
  166. package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
  167. package/dist/modules/customers/api/interactions/route.js +3 -1
  168. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  169. package/dist/modules/customers/api/interactions/tasks/route.js +27 -4
  170. package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
  171. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +4 -3
  172. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
  173. package/dist/modules/customers/api/people/[id]/companies/context.js +1 -1
  174. package/dist/modules/customers/api/people/[id]/companies/context.js.map +2 -2
  175. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +1 -1
  176. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
  177. package/dist/modules/customers/api/people/[id]/route.js +11 -10
  178. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  179. package/dist/modules/customers/api/people/check-phone/route.js +51 -9
  180. package/dist/modules/customers/api/people/check-phone/route.js.map +2 -2
  181. package/dist/modules/customers/api/todos/route.js +30 -5
  182. package/dist/modules/customers/api/todos/route.js.map +2 -2
  183. package/dist/modules/customers/backend/customers/companies/page.js +4 -2
  184. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  185. package/dist/modules/customers/backend/customers/deals/[id]/page.js +6 -1
  186. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  187. package/dist/modules/customers/backend/customers/deals/page.js +5 -2
  188. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  189. package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js +4 -13
  190. package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js.map +2 -2
  191. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js +85 -14
  192. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js.map +2 -2
  193. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js +18 -0
  194. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js.map +7 -0
  195. package/dist/modules/customers/backend/customers/people/page.js +4 -2
  196. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  197. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js +9 -3
  198. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js.map +2 -2
  199. package/dist/modules/customers/commands/deals.js +21 -34
  200. package/dist/modules/customers/commands/deals.js.map +2 -2
  201. package/dist/modules/customers/commands/interactions.js.map +1 -1
  202. package/dist/modules/customers/commands/personCompanyLinks.js +131 -2
  203. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  204. package/dist/modules/customers/components/CustomerTodosTable.js +1 -0
  205. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  206. package/dist/modules/customers/components/DealsKpiStrip.js +7 -6
  207. package/dist/modules/customers/components/DealsKpiStrip.js.map +2 -2
  208. package/dist/modules/customers/components/calendar/AgendaList.js +2 -2
  209. package/dist/modules/customers/components/calendar/AgendaList.js.map +2 -2
  210. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -1
  211. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
  212. package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
  213. package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
  214. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +1 -1
  215. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
  216. package/dist/modules/customers/components/calendar/EventBlock.js +1 -1
  217. package/dist/modules/customers/components/calendar/EventBlock.js.map +2 -2
  218. package/dist/modules/customers/components/calendar/EventPeekPopover.js +3 -2
  219. package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +2 -2
  220. package/dist/modules/customers/components/calendar/editor/PeopleField.js +40 -5
  221. package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
  222. package/dist/modules/customers/components/calendar/editor/hooks.js +2 -1
  223. package/dist/modules/customers/components/calendar/editor/hooks.js.map +2 -2
  224. package/dist/modules/customers/components/calendar/types.js +1 -1
  225. package/dist/modules/customers/components/calendar/types.js.map +2 -2
  226. package/dist/modules/customers/components/detail/CompanyKpiBar.js +5 -4
  227. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
  228. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +3 -1
  229. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  230. package/dist/modules/customers/components/detail/DealForm.js +19 -7
  231. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  232. package/dist/modules/customers/components/detail/DealsSection.js +6 -5
  233. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  234. package/dist/modules/customers/components/detail/EntityTagsDialog.js +35 -11
  235. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  236. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +3 -1
  237. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
  238. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +19 -13
  239. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
  240. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +4 -4
  241. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
  242. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +3 -3
  243. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  244. package/dist/modules/customers/components/detail/utils.js +5 -5
  245. package/dist/modules/customers/components/detail/utils.js.map +2 -2
  246. package/dist/modules/customers/data/entities.js.map +1 -1
  247. package/dist/modules/customers/data/validators.js +32 -3
  248. package/dist/modules/customers/data/validators.js.map +2 -2
  249. package/dist/modules/customers/events.js +5 -0
  250. package/dist/modules/customers/events.js.map +2 -2
  251. package/dist/modules/customers/lib/calendar/conflicts.js +8 -2
  252. package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
  253. package/dist/modules/customers/lib/calendar/editorPayload.js +3 -2
  254. package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
  255. package/dist/modules/customers/lib/calendar/mapItem.js +8 -3
  256. package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
  257. package/dist/modules/customers/lib/calendar/participantIdentity.js +9 -0
  258. package/dist/modules/customers/lib/calendar/participantIdentity.js.map +7 -0
  259. package/dist/modules/customers/lib/closureStage.js +45 -0
  260. package/dist/modules/customers/lib/closureStage.js.map +7 -0
  261. package/dist/modules/customers/lib/dealStatus.js +30 -0
  262. package/dist/modules/customers/lib/dealStatus.js.map +2 -2
  263. package/dist/modules/customers/lib/detailReadAccess.js +12 -0
  264. package/dist/modules/customers/lib/detailReadAccess.js.map +7 -0
  265. package/dist/modules/customers/lib/findPeopleByAddresses.js +1 -0
  266. package/dist/modules/customers/lib/findPeopleByAddresses.js.map +2 -2
  267. package/dist/modules/customers/lib/personCompanies.js +100 -2
  268. package/dist/modules/customers/lib/personCompanies.js.map +2 -2
  269. package/dist/modules/customers/lib/todoCompatibility.js +12 -0
  270. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  271. package/dist/modules/dashboards/lib/widgetScope.js +6 -1
  272. package/dist/modules/dashboards/lib/widgetScope.js.map +2 -2
  273. package/dist/modules/data_sync/backend/data-sync/page.js +3 -1
  274. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  275. package/dist/modules/data_sync/lib/abandoned-run.js +19 -0
  276. package/dist/modules/data_sync/lib/abandoned-run.js.map +7 -0
  277. package/dist/modules/data_sync/lib/sync-engine.js +72 -6
  278. package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
  279. package/dist/modules/data_sync/workers/sync-export.js +5 -1
  280. package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
  281. package/dist/modules/data_sync/workers/sync-import.js +5 -1
  282. package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
  283. package/dist/modules/devices/acl.js +9 -1
  284. package/dist/modules/devices/acl.js.map +2 -2
  285. package/dist/modules/devices/api/admin/devices/[id]/route.js +5 -32
  286. package/dist/modules/devices/api/admin/devices/[id]/route.js.map +2 -2
  287. package/dist/modules/devices/api/admin/devices/route.js +14 -1
  288. package/dist/modules/devices/api/admin/devices/route.js.map +2 -2
  289. package/dist/modules/devices/api/deviceList.js +99 -12
  290. package/dist/modules/devices/api/deviceList.js.map +2 -2
  291. package/dist/modules/devices/api/deviceSerialization.js +46 -0
  292. package/dist/modules/devices/api/deviceSerialization.js.map +7 -0
  293. package/dist/modules/devices/api/openapi.js +3 -1
  294. package/dist/modules/devices/api/openapi.js.map +2 -2
  295. package/dist/modules/devices/api/route.js +9 -1
  296. package/dist/modules/devices/api/route.js.map +2 -2
  297. package/dist/modules/devices/backend/devices/[id]/page.js +10 -26
  298. package/dist/modules/devices/backend/devices/[id]/page.js.map +2 -2
  299. package/dist/modules/devices/backend/devices/create/page.js +17 -1
  300. package/dist/modules/devices/backend/devices/create/page.js.map +2 -2
  301. package/dist/modules/devices/backend/devices/page.js +28 -34
  302. package/dist/modules/devices/backend/devices/page.js.map +2 -2
  303. package/dist/modules/devices/backend/devices/useDeviceUserLabels.js +34 -0
  304. package/dist/modules/devices/backend/devices/useDeviceUserLabels.js.map +7 -0
  305. package/dist/modules/devices/backend/devices/userOptions.js +52 -0
  306. package/dist/modules/devices/backend/devices/userOptions.js.map +7 -0
  307. package/dist/modules/devices/setup.js +6 -2
  308. package/dist/modules/devices/setup.js.map +2 -2
  309. package/dist/modules/directory/backend/directory/organizations/page.js +2 -1
  310. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  311. package/dist/modules/directory/backend/directory/tenants/page.js +2 -1
  312. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  313. package/dist/modules/directory/di.js +9 -0
  314. package/dist/modules/directory/di.js.map +2 -2
  315. package/dist/modules/directory/services/organizationHierarchyService.js +29 -0
  316. package/dist/modules/directory/services/organizationHierarchyService.js.map +7 -0
  317. package/dist/modules/directory/services/organizationScopeService.js +56 -0
  318. package/dist/modules/directory/services/organizationScopeService.js.map +7 -0
  319. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  320. package/dist/modules/entities/api/records.js +4 -2
  321. package/dist/modules/entities/api/records.js.map +2 -2
  322. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +3 -1
  323. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  324. package/dist/modules/eudr/api/plots/route.js +5 -1
  325. package/dist/modules/eudr/api/plots/route.js.map +2 -2
  326. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +3 -0
  327. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
  328. package/dist/modules/eudr/backend/eudr/plots/page.js +3 -0
  329. package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
  330. package/dist/modules/eudr/backend/eudr/product-mappings/page.js +3 -0
  331. package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
  332. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +3 -0
  333. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
  334. package/dist/modules/eudr/backend/eudr/statements/page.js +3 -0
  335. package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
  336. package/dist/modules/eudr/commands/statements.js +0 -3
  337. package/dist/modules/eudr/commands/statements.js.map +2 -2
  338. package/dist/modules/eudr/data/validators.js +4 -1
  339. package/dist/modules/eudr/data/validators.js.map +2 -2
  340. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +1 -0
  341. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  342. package/dist/modules/feature_toggles/components/OverridesTable.js +1 -0
  343. package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
  344. package/dist/modules/feature_toggles/defaults.json +0 -8
  345. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +3 -0
  346. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
  347. package/dist/modules/inbox_ops/backend/inbox-ops/page.js +3 -0
  348. package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
  349. package/dist/modules/inbox_ops/lib/htmlToPlainText.js +1 -12
  350. package/dist/modules/inbox_ops/lib/htmlToPlainText.js.map +2 -2
  351. package/dist/modules/integrations/api/[id]/credentials/route.js +6 -1
  352. package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
  353. package/dist/modules/integrations/backend/integrations/[id]/page.js +38 -29
  354. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  355. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +36 -9
  356. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  357. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js +55 -0
  358. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js.map +7 -0
  359. package/dist/modules/integrations/data/validators.js +11 -3
  360. package/dist/modules/integrations/data/validators.js.map +2 -2
  361. package/dist/modules/integrations/lib/credentials-masking.js +6 -2
  362. package/dist/modules/integrations/lib/credentials-masking.js.map +2 -2
  363. package/dist/modules/messages/api/[id]/route.js +29 -1
  364. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  365. package/dist/modules/messages/api/openapi.js +17 -2
  366. package/dist/modules/messages/api/openapi.js.map +2 -2
  367. package/dist/modules/messages/api/route.js +17 -2
  368. package/dist/modules/messages/api/route.js.map +2 -2
  369. package/dist/modules/messages/components/MessagesInboxPageClient.js +7 -14
  370. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  371. package/dist/modules/messages/components/inboxFilters.js +15 -0
  372. package/dist/modules/messages/components/inboxFilters.js.map +2 -2
  373. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +11 -1
  374. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +2 -2
  375. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +3 -1
  376. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +2 -2
  377. package/dist/modules/messages/components/message-detail/panels/thread-panel.js +2 -1
  378. package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +2 -2
  379. package/dist/modules/messages/components/messageListLabels.js +14 -2
  380. package/dist/modules/messages/components/messageListLabels.js.map +2 -2
  381. package/dist/modules/messages/data/validators.js +18 -4
  382. package/dist/modules/messages/data/validators.js.map +2 -2
  383. package/dist/modules/messages/lib/channel-sender-identity.js +26 -0
  384. package/dist/modules/messages/lib/channel-sender-identity.js.map +7 -0
  385. package/dist/modules/messages/lib/composeSourceChannelType.js +41 -0
  386. package/dist/modules/messages/lib/composeSourceChannelType.js.map +7 -0
  387. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +4 -6
  388. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
  389. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +3 -1
  390. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  391. package/dist/modules/payment_gateways/lib/webhook-processor.js +7 -0
  392. package/dist/modules/payment_gateways/lib/webhook-processor.js.map +2 -2
  393. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +3 -0
  394. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  395. package/dist/modules/push_notifications/backend/push_notifications/page.js +3 -1
  396. package/dist/modules/push_notifications/backend/push_notifications/page.js.map +2 -2
  397. package/dist/modules/push_notifications/backend/push_notifications/send/page.js +1 -1
  398. package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +2 -2
  399. package/dist/modules/query_index/lib/engine.js +150 -51
  400. package/dist/modules/query_index/lib/engine.js.map +2 -2
  401. package/dist/modules/query_index/lib/search-entity-policy.js +14 -0
  402. package/dist/modules/query_index/lib/search-entity-policy.js.map +7 -0
  403. package/dist/modules/query_index/lib/search-tokens.js +79 -3
  404. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  405. package/dist/modules/resources/backend/resources/resource-types/page.js +3 -1
  406. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  407. package/dist/modules/resources/backend/resources/resources/page.js +3 -1
  408. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  409. package/dist/modules/sales/backend/sales/channels/offers/page.js +3 -0
  410. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  411. package/dist/modules/sales/backend/sales/channels/page.js +3 -0
  412. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  413. package/dist/modules/sales/backend/sales/documents/[id]/page.js +10 -8
  414. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  415. package/dist/modules/sales/commands/documents.js +79 -1
  416. package/dist/modules/sales/commands/documents.js.map +2 -2
  417. package/dist/modules/sales/components/PriceWithCurrency.js +7 -5
  418. package/dist/modules/sales/components/PriceWithCurrency.js.map +2 -2
  419. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +3 -0
  420. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  421. package/dist/modules/sales/components/documents/AdjustmentsSection.js +8 -6
  422. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  423. package/dist/modules/sales/components/documents/ItemsSection.js +51 -22
  424. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  425. package/dist/modules/sales/components/documents/LineItemDialog.js +83 -18
  426. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  427. package/dist/modules/sales/components/documents/PaymentsSection.js +23 -9
  428. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  429. package/dist/modules/sales/components/documents/ReturnsSection.js +8 -6
  430. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  431. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +68 -14
  432. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  433. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +6 -5
  434. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +2 -2
  435. package/dist/modules/sales/components/documents/ShipmentDialog.js +5 -4
  436. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  437. package/dist/modules/sales/components/documents/ShipmentsSection.js +8 -6
  438. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  439. package/dist/modules/sales/components/documents/lineItemShipmentLock.js +54 -0
  440. package/dist/modules/sales/components/documents/lineItemShipmentLock.js.map +7 -0
  441. package/dist/modules/sales/components/documents/lineItemUtils.js +2 -2
  442. package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
  443. package/dist/modules/sales/data/entities.js +8 -2
  444. package/dist/modules/sales/data/entities.js.map +2 -2
  445. package/dist/modules/sales/extension-points.js +1 -0
  446. package/dist/modules/sales/extension-points.js.map +2 -2
  447. package/dist/modules/sales/lib/salesChannelsToggleSeed.js +33 -0
  448. package/dist/modules/sales/lib/salesChannelsToggleSeed.js.map +7 -0
  449. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js +32 -0
  450. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js.map +7 -0
  451. package/dist/modules/sales/setup.js +2 -0
  452. package/dist/modules/sales/setup.js.map +2 -2
  453. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +10 -2
  454. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +2 -2
  455. package/dist/modules/sales/widgets/injection-table.js +4 -7
  456. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  457. package/dist/modules/staff/backend/staff/leave-requests/page.js +3 -0
  458. package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
  459. package/dist/modules/staff/backend/staff/my-leave-requests/page.js +3 -0
  460. package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
  461. package/dist/modules/staff/backend/staff/team-members/page.js +3 -0
  462. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  463. package/dist/modules/staff/backend/staff/team-roles/page.js +3 -0
  464. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  465. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +3 -0
  466. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  467. package/dist/modules/staff/backend/staff/teams/page.js +3 -0
  468. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  469. package/dist/modules/staff/backend/staff/timesheets/page.js +29 -18
  470. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  471. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +3 -0
  472. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  473. package/dist/modules/sync_excel/lib/adapters/customers.js +1 -0
  474. package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
  475. package/dist/modules/warranty_claims/api/assignees/route.js +3 -3
  476. package/dist/modules/warranty_claims/api/assignees/route.js.map +2 -2
  477. package/dist/modules/warranty_claims/api/portal/attachments/route.js +2 -2
  478. package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
  479. package/dist/modules/warranty_claims/api/portal/claims/route.js +12 -9
  480. package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
  481. package/dist/modules/warranty_claims/backend/page.js +3 -0
  482. package/dist/modules/warranty_claims/backend/page.js.map +2 -2
  483. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js +3 -0
  484. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js.map +2 -2
  485. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js +3 -0
  486. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map +2 -2
  487. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js +3 -0
  488. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js.map +2 -2
  489. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +3 -0
  490. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
  491. package/dist/modules/wms/api/warehouseSearch.js +21 -0
  492. package/dist/modules/wms/api/warehouseSearch.js.map +7 -0
  493. package/dist/modules/wms/api/warehouses/route.js +13 -9
  494. package/dist/modules/wms/api/warehouses/route.js.map +2 -2
  495. package/dist/modules/wms/api/zones/route.js +15 -2
  496. package/dist/modules/wms/api/zones/route.js.map +2 -2
  497. package/dist/modules/wms/commands/configuration.js +121 -9
  498. package/dist/modules/wms/commands/configuration.js.map +2 -2
  499. package/dist/modules/wms/commands/inventory-actions.js +3 -0
  500. package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
  501. package/dist/modules/wms/commands/shared.js +9 -1
  502. package/dist/modules/wms/commands/shared.js.map +2 -2
  503. package/dist/modules/wms/components/backend/WarehouseEditDialog.js +158 -0
  504. package/dist/modules/wms/components/backend/WarehouseEditDialog.js.map +7 -0
  505. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +76 -111
  506. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +3 -3
  507. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +1 -0
  508. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
  509. package/dist/modules/wms/components/backend/WmsLotsListPage.js +1 -0
  510. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
  511. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +27 -20
  512. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
  513. package/dist/modules/wms/components/backend/warehouseFormOptions.js +66 -0
  514. package/dist/modules/wms/components/backend/warehouseFormOptions.js.map +7 -0
  515. package/dist/modules/workflows/backend/definitions/page.js +3 -1
  516. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  517. package/dist/modules/workflows/backend/events/page.js +3 -1
  518. package/dist/modules/workflows/backend/events/page.js.map +2 -2
  519. package/dist/modules/workflows/backend/instances/page.js +3 -1
  520. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  521. package/dist/modules/workflows/backend/tasks/page.js +3 -1
  522. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  523. package/dist/modules/workflows/lib/activity-executor.js +4 -0
  524. package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
  525. package/package.json +9 -10
  526. package/src/helpers/integration/api.ts +33 -1
  527. package/src/helpers/integration/communicationChannelsFixtures.ts +69 -1
  528. package/src/modules/api_keys/api/keys/route.ts +3 -1
  529. package/src/modules/api_keys/backend/api-keys/page.tsx +4 -1
  530. package/src/modules/api_keys/di.ts +7 -0
  531. package/src/modules/api_keys/services/principalService.ts +33 -0
  532. package/src/modules/attachments/AGENTS.md +15 -0
  533. package/src/modules/attachments/api/route.ts +2 -2
  534. package/src/modules/attachments/components/AttachmentLibrary.tsx +3 -0
  535. package/src/modules/attachments/di.ts +16 -0
  536. package/src/modules/attachments/i18n/de.json +5 -0
  537. package/src/modules/attachments/i18n/en.json +5 -0
  538. package/src/modules/attachments/i18n/es.json +5 -0
  539. package/src/modules/attachments/i18n/ko.json +5 -0
  540. package/src/modules/attachments/i18n/pl.json +5 -0
  541. package/src/modules/attachments/index.ts +10 -0
  542. package/src/modules/attachments/lib/attachment-service.ts +468 -0
  543. package/src/modules/attachments/lib/scoped-upload-service.ts +46 -0
  544. package/src/modules/attachments/lib/upload-limits.ts +6 -2
  545. package/src/modules/audit_logs/backend/audit-logs/page.tsx +8 -0
  546. package/src/modules/audit_logs/lib/display-helpers.tsx +42 -32
  547. package/src/modules/audit_logs/services/actionLogService.ts +74 -11
  548. package/src/modules/auth/acl.ts +30 -6
  549. package/src/modules/auth/api/feature-check.ts +10 -3
  550. package/src/modules/auth/api/login.ts +9 -1
  551. package/src/modules/auth/api/reset/validate.ts +57 -0
  552. package/src/modules/auth/api/roles/acl/route.ts +42 -39
  553. package/src/modules/auth/api/session/refresh.ts +32 -1
  554. package/src/modules/auth/api/users/acl/route.ts +177 -53
  555. package/src/modules/auth/api/users/route.ts +18 -5
  556. package/src/modules/auth/backend/roles/[id]/edit/page.meta.ts +5 -2
  557. package/src/modules/auth/backend/roles/page.tsx +4 -2
  558. package/src/modules/auth/backend/users/[id]/edit/page.meta.ts +5 -2
  559. package/src/modules/auth/backend/users/page.tsx +3 -2
  560. package/src/modules/auth/commands/acl.ts +495 -0
  561. package/src/modules/auth/components/AclEditor.tsx +63 -33
  562. package/src/modules/auth/data/entities.ts +4 -1
  563. package/src/modules/auth/data/validators.ts +5 -0
  564. package/src/modules/auth/di.ts +46 -16
  565. package/src/modules/auth/frontend/reset/[token]/page.tsx +74 -0
  566. package/src/modules/auth/i18n/de.json +389 -0
  567. package/src/modules/auth/i18n/en.json +389 -0
  568. package/src/modules/auth/i18n/es.json +389 -0
  569. package/src/modules/auth/i18n/ko.json +389 -0
  570. package/src/modules/auth/i18n/pl.json +391 -2
  571. package/src/modules/auth/lib/grantChecks.ts +6 -0
  572. package/src/modules/auth/lib/userIdFilter.ts +31 -0
  573. package/src/modules/auth/services/authService.ts +18 -2
  574. package/src/modules/auth/services/principalService.ts +266 -0
  575. package/src/modules/auth/services/rbacService.ts +110 -24
  576. package/src/modules/auth/services/roleOrganizationScope.ts +70 -0
  577. package/src/modules/business_rules/backend/logs/page.tsx +4 -1
  578. package/src/modules/business_rules/backend/rules/page.tsx +4 -1
  579. package/src/modules/business_rules/backend/sets/page.tsx +4 -1
  580. package/src/modules/business_rules/lib/expression-evaluator.ts +9 -9
  581. package/src/modules/business_rules/lib/rule-evaluator.ts +10 -9
  582. package/src/modules/catalog/ai-agents.ts +1 -1
  583. package/src/modules/catalog/ai-tools/merchandising-pack.ts +2 -2
  584. package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +12 -5
  585. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +3 -0
  586. package/src/modules/catalog/components/products/ProductsDataTable.tsx +7 -0
  587. package/src/modules/catalog/i18n/de.json +1 -0
  588. package/src/modules/catalog/i18n/en.json +1 -0
  589. package/src/modules/catalog/i18n/es.json +1 -0
  590. package/src/modules/catalog/i18n/ko.json +1 -0
  591. package/src/modules/catalog/i18n/pl.json +1 -0
  592. package/src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx +4 -0
  593. package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +17 -1
  594. package/src/modules/communication_channels/api/post/test-seed/route.ts +155 -16
  595. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +4 -0
  596. package/src/modules/communication_channels/commands/ingest-inbound-message.ts +38 -1
  597. package/src/modules/communication_channels/di.ts +7 -0
  598. package/src/modules/communication_channels/lib/adapter.ts +14 -0
  599. package/src/modules/communication_channels/lib/email-capabilities.ts +4 -0
  600. package/src/modules/communication_channels/lib/outbound-recipient.ts +71 -0
  601. package/src/modules/communication_channels/lib/resolve-channel-type.ts +99 -0
  602. package/src/modules/communication_channels/lib/test-seed.ts +64 -4
  603. package/src/modules/configs/i18n/de.json +2 -0
  604. package/src/modules/configs/i18n/en.json +2 -0
  605. package/src/modules/configs/i18n/es.json +2 -0
  606. package/src/modules/configs/i18n/ko.json +2 -0
  607. package/src/modules/configs/i18n/pl.json +2 -0
  608. package/src/modules/configs/lib/system-status.ts +9 -0
  609. package/src/modules/currencies/AGENTS.md +3 -0
  610. package/src/modules/currencies/backend/currencies/page.tsx +4 -1
  611. package/src/modules/currencies/backend/exchange-rates/page.tsx +4 -1
  612. package/src/modules/currencies/services/README.md +45 -0
  613. package/src/modules/currencies/services/rateFetchingService.ts +6 -1
  614. package/src/modules/customer_accounts/api/admin/domain-mappings.ts +7 -0
  615. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +4 -1
  616. package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +4 -1
  617. package/src/modules/customer_accounts/services/domainMappingService.ts +10 -0
  618. package/src/modules/customers/ai-tools/companies-pack.ts +4 -1
  619. package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +17 -2
  620. package/src/modules/customers/ai-tools/deals-pack.ts +66 -1
  621. package/src/modules/customers/ai-tools/people-pack.ts +4 -1
  622. package/src/modules/customers/api/activities/route.ts +45 -0
  623. package/src/modules/customers/api/companies/[id]/people/route.ts +24 -73
  624. package/src/modules/customers/api/companies/[id]/route.ts +24 -107
  625. package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +16 -8
  626. package/src/modules/customers/api/deals/[id]/companies/route.ts +4 -1
  627. package/src/modules/customers/api/deals/[id]/people/route.ts +4 -1
  628. package/src/modules/customers/api/deals/[id]/route.ts +17 -28
  629. package/src/modules/customers/api/deals/[id]/stats/route.ts +10 -25
  630. package/src/modules/customers/api/deals/aggregate/route.ts +14 -4
  631. package/src/modules/customers/api/deals/map/route.ts +1 -0
  632. package/src/modules/customers/api/deals/route.ts +50 -1
  633. package/src/modules/customers/api/entity-roles-factory.ts +8 -4
  634. package/src/modules/customers/api/interactions/route.ts +8 -2
  635. package/src/modules/customers/api/interactions/tasks/route.ts +24 -1
  636. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +12 -4
  637. package/src/modules/customers/api/people/[id]/companies/context.ts +4 -1
  638. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +4 -1
  639. package/src/modules/customers/api/people/[id]/route.ts +16 -11
  640. package/src/modules/customers/api/people/check-phone/route.ts +75 -10
  641. package/src/modules/customers/api/todos/route.ts +27 -2
  642. package/src/modules/customers/backend/customers/companies/page.tsx +5 -2
  643. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +7 -2
  644. package/src/modules/customers/backend/customers/deals/page.tsx +8 -2
  645. package/src/modules/customers/backend/customers/deals/pipeline/components/Lane.tsx +5 -14
  646. package/src/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.tsx +109 -27
  647. package/src/modules/customers/backend/customers/deals/pipeline/components/toneClasses.ts +21 -0
  648. package/src/modules/customers/backend/customers/people/page.tsx +5 -2
  649. package/src/modules/customers/backend/hooks/useEmailDuplicateCheck.ts +12 -4
  650. package/src/modules/customers/commands/deals.ts +34 -59
  651. package/src/modules/customers/commands/interactions.ts +1 -1
  652. package/src/modules/customers/commands/personCompanyLinks.ts +224 -8
  653. package/src/modules/customers/components/CustomerTodosTable.tsx +2 -0
  654. package/src/modules/customers/components/DealsKpiStrip.tsx +7 -7
  655. package/src/modules/customers/components/calendar/AgendaList.tsx +3 -3
  656. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -1
  657. package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
  658. package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +1 -1
  659. package/src/modules/customers/components/calendar/EventBlock.tsx +2 -2
  660. package/src/modules/customers/components/calendar/EventPeekPopover.tsx +4 -2
  661. package/src/modules/customers/components/calendar/editor/PeopleField.tsx +61 -5
  662. package/src/modules/customers/components/calendar/editor/hooks.ts +7 -1
  663. package/src/modules/customers/components/calendar/types.ts +2 -2
  664. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +5 -4
  665. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +8 -1
  666. package/src/modules/customers/components/detail/DealForm.tsx +22 -2
  667. package/src/modules/customers/components/detail/DealsSection.tsx +11 -5
  668. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +58 -12
  669. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +8 -1
  670. package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +23 -14
  671. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +5 -5
  672. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +5 -5
  673. package/src/modules/customers/components/detail/types.ts +1 -1
  674. package/src/modules/customers/components/detail/utils.ts +15 -5
  675. package/src/modules/customers/data/entities.ts +1 -1
  676. package/src/modules/customers/data/validators.ts +50 -9
  677. package/src/modules/customers/events.ts +5 -0
  678. package/src/modules/customers/i18n/de.json +9 -1
  679. package/src/modules/customers/i18n/en.json +9 -1
  680. package/src/modules/customers/i18n/es.json +9 -1
  681. package/src/modules/customers/i18n/ko.json +9 -1
  682. package/src/modules/customers/i18n/pl.json +9 -1
  683. package/src/modules/customers/lib/calendar/conflicts.ts +10 -2
  684. package/src/modules/customers/lib/calendar/editorPayload.ts +4 -3
  685. package/src/modules/customers/lib/calendar/mapItem.ts +8 -3
  686. package/src/modules/customers/lib/calendar/participantIdentity.ts +17 -0
  687. package/src/modules/customers/lib/closureStage.ts +76 -0
  688. package/src/modules/customers/lib/dealStatus.ts +42 -0
  689. package/src/modules/customers/lib/detailReadAccess.ts +35 -0
  690. package/src/modules/customers/lib/findPeopleByAddresses.ts +8 -6
  691. package/src/modules/customers/lib/personCompanies.ts +136 -1
  692. package/src/modules/customers/lib/todoCompatibility.ts +19 -1
  693. package/src/modules/dashboards/i18n/es.json +4 -4
  694. package/src/modules/dashboards/i18n/pl.json +7 -7
  695. package/src/modules/dashboards/lib/widgetScope.ts +6 -0
  696. package/src/modules/data_sync/AGENTS.md +1 -1
  697. package/src/modules/data_sync/backend/data-sync/page.tsx +4 -1
  698. package/src/modules/data_sync/lib/abandoned-run.ts +56 -0
  699. package/src/modules/data_sync/lib/adapter.ts +36 -0
  700. package/src/modules/data_sync/lib/sync-engine.ts +113 -5
  701. package/src/modules/data_sync/workers/sync-export.ts +4 -0
  702. package/src/modules/data_sync/workers/sync-import.ts +4 -0
  703. package/src/modules/devices/AGENTS.md +20 -1
  704. package/src/modules/devices/acl.ts +9 -1
  705. package/src/modules/devices/api/admin/devices/[id]/route.ts +5 -34
  706. package/src/modules/devices/api/admin/devices/route.ts +14 -1
  707. package/src/modules/devices/api/deviceList.ts +135 -11
  708. package/src/modules/devices/api/deviceSerialization.ts +50 -0
  709. package/src/modules/devices/api/openapi.ts +9 -1
  710. package/src/modules/devices/api/route.ts +9 -1
  711. package/src/modules/devices/backend/devices/[id]/page.tsx +18 -32
  712. package/src/modules/devices/backend/devices/create/page.tsx +17 -1
  713. package/src/modules/devices/backend/devices/page.tsx +44 -45
  714. package/src/modules/devices/backend/devices/useDeviceUserLabels.ts +45 -0
  715. package/src/modules/devices/backend/devices/userOptions.ts +99 -0
  716. package/src/modules/devices/i18n/de.json +3 -2
  717. package/src/modules/devices/i18n/en.json +3 -2
  718. package/src/modules/devices/i18n/es.json +3 -2
  719. package/src/modules/devices/i18n/ko.json +3 -2
  720. package/src/modules/devices/i18n/pl.json +3 -2
  721. package/src/modules/devices/setup.ts +6 -2
  722. package/src/modules/directory/backend/directory/organizations/page.tsx +3 -1
  723. package/src/modules/directory/backend/directory/tenants/page.tsx +3 -1
  724. package/src/modules/directory/di.ts +14 -2
  725. package/src/modules/directory/services/organizationHierarchyService.ts +34 -0
  726. package/src/modules/directory/services/organizationScopeService.ts +85 -0
  727. package/src/modules/directory/utils/organizationScope.ts +4 -15
  728. package/src/modules/entities/api/records.ts +2 -0
  729. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +4 -1
  730. package/src/modules/eudr/api/plots/route.ts +4 -0
  731. package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +4 -0
  732. package/src/modules/eudr/backend/eudr/plots/page.tsx +4 -0
  733. package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +4 -0
  734. package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +4 -0
  735. package/src/modules/eudr/backend/eudr/statements/page.tsx +4 -0
  736. package/src/modules/eudr/commands/statements.ts +0 -3
  737. package/src/modules/eudr/data/validators.ts +16 -1
  738. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +2 -1
  739. package/src/modules/feature_toggles/components/OverridesTable.tsx +2 -1
  740. package/src/modules/feature_toggles/defaults.json +0 -8
  741. package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +4 -0
  742. package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +4 -0
  743. package/src/modules/inbox_ops/lib/htmlToPlainText.ts +1 -17
  744. package/src/modules/integrations/api/[id]/credentials/route.ts +6 -4
  745. package/src/modules/integrations/backend/integrations/[id]/page.tsx +61 -31
  746. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +44 -9
  747. package/src/modules/integrations/backend/integrations/credential-secret-fields.ts +84 -0
  748. package/src/modules/integrations/data/validators.ts +12 -2
  749. package/src/modules/integrations/i18n/de.json +1 -0
  750. package/src/modules/integrations/i18n/en.json +1 -0
  751. package/src/modules/integrations/i18n/es.json +1 -0
  752. package/src/modules/integrations/i18n/ko.json +1 -0
  753. package/src/modules/integrations/i18n/pl.json +1 -0
  754. package/src/modules/integrations/lib/credentials-masking.ts +10 -6
  755. package/src/modules/messages/api/[id]/route.ts +55 -1
  756. package/src/modules/messages/api/openapi.ts +20 -0
  757. package/src/modules/messages/api/route.ts +31 -2
  758. package/src/modules/messages/components/MessagesInboxPageClient.tsx +9 -16
  759. package/src/modules/messages/components/inboxFilters.ts +36 -0
  760. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +14 -1
  761. package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +3 -1
  762. package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +2 -1
  763. package/src/modules/messages/components/message-detail/types.ts +3 -0
  764. package/src/modules/messages/components/messageListLabels.ts +52 -3
  765. package/src/modules/messages/data/validators.ts +43 -4
  766. package/src/modules/messages/lib/channel-sender-identity.ts +55 -0
  767. package/src/modules/messages/lib/composeSourceChannelType.ts +95 -0
  768. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +4 -6
  769. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +4 -1
  770. package/src/modules/payment_gateways/lib/webhook-processor.ts +11 -0
  771. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +4 -0
  772. package/src/modules/push_notifications/backend/push_notifications/page.tsx +4 -1
  773. package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +4 -4
  774. package/src/modules/query_index/lib/engine.ts +249 -61
  775. package/src/modules/query_index/lib/search-entity-policy.ts +46 -0
  776. package/src/modules/query_index/lib/search-tokens.ts +135 -3
  777. package/src/modules/resources/backend/resources/resource-types/page.tsx +4 -1
  778. package/src/modules/resources/backend/resources/resources/page.tsx +4 -1
  779. package/src/modules/sales/backend/sales/channels/offers/page.tsx +4 -0
  780. package/src/modules/sales/backend/sales/channels/page.tsx +4 -0
  781. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +14 -8
  782. package/src/modules/sales/commands/documents.ts +93 -0
  783. package/src/modules/sales/components/PriceWithCurrency.tsx +17 -5
  784. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +4 -0
  785. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +6 -5
  786. package/src/modules/sales/components/documents/ItemsSection.tsx +56 -18
  787. package/src/modules/sales/components/documents/LineItemDialog.tsx +137 -20
  788. package/src/modules/sales/components/documents/PaymentsSection.tsx +20 -9
  789. package/src/modules/sales/components/documents/ReturnsSection.tsx +6 -5
  790. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +106 -14
  791. package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +6 -5
  792. package/src/modules/sales/components/documents/ShipmentDialog.tsx +5 -4
  793. package/src/modules/sales/components/documents/ShipmentsSection.tsx +6 -5
  794. package/src/modules/sales/components/documents/lineItemShipmentLock.ts +74 -0
  795. package/src/modules/sales/components/documents/lineItemUtils.ts +7 -2
  796. package/src/modules/sales/data/entities.ts +6 -0
  797. package/src/modules/sales/extension-points.ts +1 -0
  798. package/src/modules/sales/i18n/de.json +8 -0
  799. package/src/modules/sales/i18n/en.json +8 -0
  800. package/src/modules/sales/i18n/es.json +8 -0
  801. package/src/modules/sales/i18n/ko.json +8 -0
  802. package/src/modules/sales/i18n/pl.json +8 -0
  803. package/src/modules/sales/lib/salesChannelsToggleSeed.ts +42 -0
  804. package/src/modules/sales/migrations/.snapshot-open-mercato.json +60 -0
  805. package/src/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.ts +87 -0
  806. package/src/modules/sales/setup.ts +2 -0
  807. package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +9 -1
  808. package/src/modules/sales/widgets/injection-table.ts +4 -7
  809. package/src/modules/staff/backend/staff/leave-requests/page.tsx +4 -0
  810. package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +4 -0
  811. package/src/modules/staff/backend/staff/team-members/page.tsx +6 -0
  812. package/src/modules/staff/backend/staff/team-roles/page.tsx +4 -0
  813. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +4 -0
  814. package/src/modules/staff/backend/staff/teams/page.tsx +4 -0
  815. package/src/modules/staff/backend/staff/timesheets/page.tsx +12 -1
  816. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +4 -0
  817. package/src/modules/sync_excel/lib/adapters/customers.ts +5 -0
  818. package/src/modules/warranty_claims/api/assignees/route.ts +3 -3
  819. package/src/modules/warranty_claims/api/portal/attachments/route.ts +2 -2
  820. package/src/modules/warranty_claims/api/portal/claims/route.ts +12 -9
  821. package/src/modules/warranty_claims/backend/page.tsx +4 -0
  822. package/src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx +4 -0
  823. package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx +4 -0
  824. package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx +4 -0
  825. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +4 -0
  826. package/src/modules/wms/api/warehouseSearch.ts +23 -0
  827. package/src/modules/wms/api/warehouses/route.ts +13 -9
  828. package/src/modules/wms/api/zones/route.ts +16 -0
  829. package/src/modules/wms/commands/configuration.ts +159 -10
  830. package/src/modules/wms/commands/inventory-actions.ts +3 -0
  831. package/src/modules/wms/commands/shared.ts +17 -0
  832. package/src/modules/wms/components/backend/WarehouseEditDialog.tsx +216 -0
  833. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +95 -141
  834. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +2 -0
  835. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +2 -0
  836. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +36 -20
  837. package/src/modules/wms/components/backend/warehouseFormOptions.ts +72 -0
  838. package/src/modules/wms/i18n/de.json +2 -0
  839. package/src/modules/wms/i18n/en.json +2 -0
  840. package/src/modules/wms/i18n/es.json +2 -0
  841. package/src/modules/wms/i18n/ko.json +2 -0
  842. package/src/modules/wms/i18n/pl.json +2 -0
  843. package/src/modules/workflows/backend/definitions/page.tsx +4 -1
  844. package/src/modules/workflows/backend/events/page.tsx +4 -1
  845. package/src/modules/workflows/backend/instances/page.tsx +4 -1
  846. package/src/modules/workflows/backend/tasks/page.tsx +4 -1
  847. package/src/modules/workflows/lib/activity-executor.ts +9 -0
@@ -20,7 +20,13 @@ import {
20
20
  } from '../data/validators'
21
21
  import { resolveDeviceActorUserId } from './auth'
22
22
  import { createDevicesCrudOpenApi, createPagedListResponseSchema } from './openapi'
23
- import { deviceListSchema, deviceListFields, deviceListSortFieldMap, deviceListItemSchema } from './deviceList'
23
+ import {
24
+ deviceListSchema,
25
+ deviceListFields,
26
+ deviceListSortFieldMap,
27
+ deviceListItemSchema,
28
+ transformDeviceListItem,
29
+ } from './deviceList'
24
30
  import { executeRegister, type DeviceMutationContext } from './deviceOps'
25
31
 
26
32
  const logger = createLogger('devices')
@@ -59,6 +65,8 @@ const crud = makeCrudRoute({
59
65
  // push_token is a secret and is never exposed via the list API.
60
66
  fields: deviceListFields,
61
67
  sortFieldMap: deviceListSortFieldMap,
68
+ // The query engine projects raw column names; expose them in camelCase like every other module.
69
+ transformItem: transformDeviceListItem,
62
70
  // Exports are off for the self-serve list. The factory enables them for every list that does not
63
71
  // declare `export` (resolveAvailableExportFormats falls back to csv/json/xml/markdown), and its
64
72
  // full-export branch replaces the filters with `{}` instead of calling `buildFilters`
@@ -9,16 +9,17 @@ import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
9
9
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
10
10
  import { LoadingMessage, ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'
11
11
  import { useT } from '@open-mercato/shared/lib/i18n/context'
12
+ import { useDeviceUserLabels } from '../useDeviceUserLabels'
12
13
 
13
14
  type DeviceDetail = {
14
15
  id: string
15
- user_id: string
16
- device_id: string
16
+ userId: string
17
+ deviceId: string
17
18
  platform: string
18
- client_app_version: string | null
19
- os_version: string | null
20
- push_provider: string | null
21
- updated_at: string | null
19
+ clientAppVersion: string | null
20
+ osVersion: string | null
21
+ pushProvider: string | null
22
+ updatedAt: string | null
22
23
  }
23
24
 
24
25
  type FormValues = {
@@ -35,7 +36,6 @@ export default function DeviceAdminEditPage({ params }: { params?: { id?: string
35
36
  const [isLoading, setIsLoading] = React.useState(true)
36
37
  const [error, setError] = React.useState<string | null>(null)
37
38
  const [notFound, setNotFound] = React.useState(false)
38
- const [userLabel, setUserLabel] = React.useState<string | null>(null)
39
39
 
40
40
  React.useEffect(() => {
41
41
  let cancelled = false
@@ -63,24 +63,10 @@ export default function DeviceAdminEditPage({ params }: { params?: { id?: string
63
63
  }, [id, t])
64
64
 
65
65
  // Resolve the owner's display name for a link to their profile. Devices admins may not hold
66
- // auth.users.list, so fall back to the raw id (rendered without a link) instead of redirecting.
67
- React.useEffect(() => {
68
- const userId = device?.user_id
69
- if (!userId) return
70
- let cancelled = false
71
- void (async () => {
72
- const call = await apiCall<{ items?: { id: string; name?: string | null; email?: string | null }[] }>(
73
- `/api/auth/users?id=${encodeURIComponent(userId)}`,
74
- { headers: { 'x-om-forbidden-redirect': '0' } },
75
- { fallback: null },
76
- ).catch(() => null)
77
- if (cancelled || !call || !call.ok) return
78
- const found = call.result?.items?.find((u) => u.id === userId)
79
- const label = found?.name?.trim() || found?.email?.trim() || null
80
- if (label) setUserLabel(label)
81
- })()
82
- return () => { cancelled = true }
83
- }, [device?.user_id])
66
+ // auth.users.list, so this falls back to the raw id (rendered without a link) instead of redirecting.
67
+ const ownerIds = React.useMemo(() => [device?.userId], [device?.userId])
68
+ const userLabels = useDeviceUserLabels(ownerIds)
69
+ const userLabel = device?.userId ? userLabels[device.userId] ?? null : null
84
70
 
85
71
  const fields = React.useMemo<CrudField[]>(() => [
86
72
  { id: 'clientAppVersion', label: t('devices.form.appVersion'), type: 'text' },
@@ -122,7 +108,7 @@ export default function DeviceAdminEditPage({ params }: { params?: { id?: string
122
108
  <dl className="grid grid-cols-1 gap-3 rounded-md border bg-muted p-4 text-sm sm:grid-cols-3">
123
109
  <div>
124
110
  <dt className="text-xs font-medium text-muted-foreground">{t('devices.form.deviceId')}</dt>
125
- <dd className="mt-1"><code className="text-xs">{device.device_id}</code></dd>
111
+ <dd className="mt-1"><code className="text-xs">{device.deviceId}</code></dd>
126
112
  </div>
127
113
  <div>
128
114
  <dt className="text-xs font-medium text-muted-foreground">{t('devices.form.platform')}</dt>
@@ -131,20 +117,20 @@ export default function DeviceAdminEditPage({ params }: { params?: { id?: string
131
117
  <div>
132
118
  <dt className="text-xs font-medium text-muted-foreground">{t('devices.form.userId')}</dt>
133
119
  <dd className="mt-1">{userLabel ? (
134
- <Link href={`/backend/users/${encodeURIComponent(device.user_id)}/edit`} className="text-primary hover:underline">{userLabel}</Link>
120
+ <Link href={`/backend/users/${encodeURIComponent(device.userId)}/edit`} className="text-primary hover:underline">{userLabel}</Link>
135
121
  ) : (
136
- <code className="text-xs">{device.user_id}</code>
122
+ <code className="text-xs">{device.userId}</code>
137
123
  )}</dd>
138
124
  </div>
139
125
  </dl>
140
126
  )}
141
127
  fields={fields}
142
128
  groups={groups}
143
- optimisticLockUpdatedAt={device.updated_at}
129
+ optimisticLockUpdatedAt={device.updatedAt}
144
130
  initialValues={{
145
- clientAppVersion: device.client_app_version ?? '',
146
- osVersion: device.os_version ?? '',
147
- pushProvider: device.push_provider ?? '',
131
+ clientAppVersion: device.clientAppVersion ?? '',
132
+ osVersion: device.osVersion ?? '',
133
+ pushProvider: device.pushProvider ?? '',
148
134
  }}
149
135
  submitLabel={t('common.save')}
150
136
  cancelHref="/backend/devices"
@@ -6,6 +6,7 @@ import { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/b
6
6
  import { createCrud } from '@open-mercato/ui/backend/utils/crud'
7
7
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
8
8
  import { useT } from '@open-mercato/shared/lib/i18n/context'
9
+ import { loadDeviceUserOptions } from '../userOptions'
9
10
 
10
11
  type FormValues = {
11
12
  userId: string
@@ -27,7 +28,22 @@ export default function DeviceAdminCreatePage() {
27
28
  const t = useT()
28
29
 
29
30
  const fields = React.useMemo<CrudField[]>(() => [
30
- { id: 'userId', label: t('devices.form.userId'), type: 'text', required: true, description: t('devices.form.userIdHint') },
31
+ {
32
+ id: 'userId',
33
+ label: t('devices.form.userId'),
34
+ type: 'combobox',
35
+ required: true,
36
+ description: t('devices.form.userIdHint'),
37
+ placeholder: t('devices.form.userIdPlaceholder'),
38
+ loadOptions: loadDeviceUserOptions,
39
+ // The owner must resolve to a real directory entry: `ComboboxInput` reverts anything that is
40
+ // not a known option on blur, so free text and an id belonging to nobody never reach submit.
41
+ // (A raw id that IS a known option still resolves — `findOptionForInput` matches on value, and
42
+ // `CrudForm` keeps the unfiltered first page as suggestions — which is a real user either way.)
43
+ // `devices.admin` declares `dependsOn: ['auth.users.list']` in `acl.ts`, so a role that can
44
+ // reach this form can also search the directory that fills the picker.
45
+ allowCustomValues: false,
46
+ },
31
47
  { id: 'deviceId', label: t('devices.form.deviceId'), type: 'text', required: true },
32
48
  {
33
49
  id: 'platform',
@@ -12,18 +12,20 @@ import { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/u
12
12
  import { useT } from '@open-mercato/shared/lib/i18n/context'
13
13
  import { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'
14
14
  import type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'
15
+ import { loadDeviceUserOptions, type DeviceUserOption } from './userOptions'
16
+ import { useDeviceUserLabels } from './useDeviceUserLabels'
15
17
 
16
18
  type Row = {
17
19
  id: string
18
- user_id: string
19
- device_id: string
20
+ userId: string
21
+ deviceId: string
20
22
  platform: string
21
- client_app_version: string | null
22
- os_version: string | null
23
- push_provider: string | null
24
- push_token_updated_at: string | null
25
- last_seen_at: string | null
26
- created_at: string | null
23
+ clientAppVersion: string | null
24
+ osVersion: string | null
25
+ pushProvider: string | null
26
+ pushTokenUpdatedAt: string | null
27
+ lastSeenAt: string | null
28
+ createdAt: string | null
27
29
  }
28
30
 
29
31
  type ResponsePayload = {
@@ -32,6 +34,7 @@ type ResponsePayload = {
32
34
  page?: number
33
35
  pageSize?: number
34
36
  totalPages: number
37
+ totalIsCapped?: boolean
35
38
  }
36
39
 
37
40
  function formatDate(value: string | null, t: (key: string) => string) {
@@ -50,49 +53,44 @@ export default function DevicesAdminListPage() {
50
53
  const [page, setPage] = React.useState(1)
51
54
  const [total, setTotal] = React.useState(0)
52
55
  const [totalPages, setTotalPages] = React.useState(1)
56
+ const [totalIsCapped, setTotalIsCapped] = React.useState(false)
53
57
  const [isLoading, setIsLoading] = React.useState(true)
54
58
  const [reloadToken, setReloadToken] = React.useState(0)
55
59
  const scopeVersion = useOrganizationScopeVersion()
56
60
  const t = useT()
57
61
  const { confirm, ConfirmDialogElement } = useConfirmDialog()
58
62
  const [filterValues, setFilterValues] = React.useState<FilterValues>({})
59
- const [userOptions, setUserOptions] = React.useState<{ value: string; label: string; description?: string | null }[]>([])
63
+ const [userOptions, setUserOptions] = React.useState<DeviceUserOption[]>([])
60
64
 
61
- // Devices admins may not hold auth.users.list; degrade gracefully (no options) instead of redirecting.
62
- const loadUserOptions = React.useCallback(async (query?: string) => {
63
- const params = new URLSearchParams()
64
- params.set('page', '1')
65
- params.set('pageSize', '20')
66
- if (query && query.trim().length > 0) params.set('search', query.trim())
67
- const call = await apiCall<{ items?: { id: string; name?: string | null; email?: string | null }[] }>(
68
- `/api/auth/users?${params.toString()}`,
69
- { headers: { 'x-om-forbidden-redirect': '0' } },
70
- { fallback: null },
71
- ).catch(() => null)
72
- if (!call || !call.ok) return []
73
- const next = (call.result?.items ?? []).flatMap((item) => {
74
- if (!item || typeof item.id !== 'string' || !item.id.trim()) return []
75
- const name = typeof item.name === 'string' && item.name.trim() ? item.name.trim() : null
76
- const email = typeof item.email === 'string' && item.email.trim() ? item.email.trim() : null
77
- const label = name ?? email ?? item.id
78
- return [{ value: item.id, label, description: email && email !== label ? email : null }]
79
- })
65
+ const mergeUserOptions = React.useCallback((next: DeviceUserOption[]) => {
66
+ if (next.length === 0) return
80
67
  setUserOptions((prev) => {
81
68
  const map = new Map(prev.map((opt) => [opt.value, opt]))
82
69
  for (const opt of next) map.set(opt.value, opt)
83
70
  return Array.from(map.values())
84
71
  })
85
- return next
86
72
  }, [])
87
73
 
74
+ // Devices admins may not hold auth.users.list; the helper degrades to no options instead of
75
+ // redirecting the whole page to /login.
76
+ const loadUserOptions = React.useCallback(async (query?: string) => {
77
+ const next = await loadDeviceUserOptions(query)
78
+ mergeUserOptions(next)
79
+ return next
80
+ }, [mergeUserOptions])
81
+
88
82
  React.useEffect(() => { void loadUserOptions() }, [loadUserOptions, scopeVersion])
89
83
 
90
- // Reuse the picker cache to label the User column; rows whose owner isn't cached still link by id.
91
84
  const userLabelById = React.useMemo(
92
85
  () => new Map(userOptions.map((opt) => [opt.value, opt.label])),
93
86
  [userOptions],
94
87
  )
95
88
 
89
+ // The picker only ever caches the users it happened to prefetch, so resolve the owners of the rows
90
+ // actually on this page. Without it most rows render a bare UUID.
91
+ const rowUserIds = React.useMemo(() => rows.map((row) => row.userId), [rows])
92
+ const resolvedUserLabels = useDeviceUserLabels(rowUserIds)
93
+
96
94
  const filters = React.useMemo<FilterDef[]>(() => [
97
95
  {
98
96
  id: 'platform',
@@ -138,6 +136,7 @@ export default function DevicesAdminListPage() {
138
136
  setRows(Array.isArray(payload.items) ? payload.items : [])
139
137
  setTotal(payload.total || 0)
140
138
  setTotalPages(payload.totalPages || 1)
139
+ setTotalIsCapped(payload?.totalIsCapped === true)
141
140
  }
142
141
  } catch (error) {
143
142
  if (!cancelled) {
@@ -181,17 +180,17 @@ export default function DevicesAdminListPage() {
181
180
 
182
181
  const columns = React.useMemo<ColumnDef<Row>[]>(() => [
183
182
  {
184
- accessorKey: 'device_id',
183
+ accessorKey: 'deviceId',
185
184
  header: t('devices.list.columns.device'),
186
- cell: ({ row }) => <code className="text-xs">{row.original.device_id}</code>,
185
+ cell: ({ row }) => <code className="text-xs">{row.original.deviceId}</code>,
187
186
  },
188
187
  { accessorKey: 'platform', header: t('devices.list.columns.platform') },
189
188
  {
190
- accessorKey: 'user_id',
189
+ accessorKey: 'userId',
191
190
  header: t('devices.list.columns.user'),
192
191
  cell: ({ row }) => {
193
- const userId = row.original.user_id
194
- const label = userLabelById.get(userId)
192
+ const userId = row.original.userId
193
+ const label = resolvedUserLabels[userId] ?? userLabelById.get(userId)
195
194
  return (
196
195
  // Stop the click bubbling to the row, whose default action navigates to the device edit page.
197
196
  <Link
@@ -205,26 +204,26 @@ export default function DevicesAdminListPage() {
205
204
  },
206
205
  },
207
206
  {
208
- accessorKey: 'client_app_version',
207
+ accessorKey: 'clientAppVersion',
209
208
  header: t('devices.list.columns.appVersion'),
210
- cell: ({ row }) => row.original.client_app_version || t('devices.list.noValue'),
209
+ cell: ({ row }) => row.original.clientAppVersion || t('devices.list.noValue'),
211
210
  },
212
211
  {
213
- accessorKey: 'os_version',
212
+ accessorKey: 'osVersion',
214
213
  header: t('devices.list.columns.osVersion'),
215
- cell: ({ row }) => row.original.os_version || t('devices.list.noValue'),
214
+ cell: ({ row }) => row.original.osVersion || t('devices.list.noValue'),
216
215
  },
217
216
  {
218
- accessorKey: 'push_provider',
217
+ accessorKey: 'pushProvider',
219
218
  header: t('devices.list.columns.pushProvider'),
220
- cell: ({ row }) => row.original.push_provider || t('devices.list.noValue'),
219
+ cell: ({ row }) => row.original.pushProvider || t('devices.list.noValue'),
221
220
  },
222
221
  {
223
- accessorKey: 'last_seen_at',
222
+ accessorKey: 'lastSeenAt',
224
223
  header: t('devices.list.columns.lastSeen'),
225
- cell: ({ row }) => formatDate(row.original.last_seen_at, t),
224
+ cell: ({ row }) => formatDate(row.original.lastSeenAt, t),
226
225
  },
227
- ], [t, userLabelById])
226
+ ], [t, userLabelById, resolvedUserLabels])
228
227
 
229
228
  return (
230
229
  <Page>
@@ -249,7 +248,7 @@ export default function DevicesAdminListPage() {
249
248
  { id: 'deactivate', label: t('devices.list.actions.deactivate'), destructive: true, onSelect: () => { void handleDeactivate(row) } },
250
249
  ]} />
251
250
  )}
252
- pagination={{ page, pageSize: 50, total, totalPages, onPageChange: setPage }}
251
+ pagination={{ page, pageSize: 50, total, totalPages, totalIsCapped, onPageChange: setPage }}
253
252
  isLoading={isLoading}
254
253
  />
255
254
  </PageBody>
@@ -0,0 +1,45 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { resolveDeviceUserOptions } from './userOptions'
5
+
6
+ // Resolves owner ids that are on screen into display labels. Modelled on
7
+ // warranty_claims/backend/components/useUserDisplayNames, but every failure degrades to an empty
8
+ // map instead of throwing: a devices admin without `auth.users.list` must still see the page.
9
+ export function useDeviceUserLabels(userIds: readonly (string | null | undefined)[]): Record<string, string> {
10
+ const [labels, setLabels] = React.useState<Record<string, string>>({})
11
+ const resolvedIdsRef = React.useRef<Set<string>>(new Set())
12
+
13
+ const idsKey = React.useMemo(() => {
14
+ const normalized = new Set<string>()
15
+ for (const userId of userIds) {
16
+ if (typeof userId === 'string' && userId.trim()) normalized.add(userId.trim())
17
+ }
18
+ return Array.from(normalized)
19
+ .sort((left, right) => (left < right ? -1 : left > right ? 1 : 0))
20
+ .join(',')
21
+ }, [userIds])
22
+
23
+ React.useEffect(() => {
24
+ if (!idsKey) return
25
+ const unresolved = idsKey.split(',').filter((userId) => !resolvedIdsRef.current.has(userId))
26
+ if (unresolved.length === 0) return
27
+
28
+ const controller = new AbortController()
29
+ void resolveDeviceUserOptions(unresolved, controller.signal)
30
+ .then(({ options, resolvedIds }) => {
31
+ if (controller.signal.aborted) return
32
+ // Only ids the server actually answered for are remembered. Marking an id whose request
33
+ // failed would keep its row showing a bare UUID for the life of the component, even though
34
+ // the next attempt would have worked.
35
+ for (const userId of resolvedIds) resolvedIdsRef.current.add(userId)
36
+ const next: Record<string, string> = {}
37
+ for (const option of options) next[option.value] = option.label
38
+ if (Object.keys(next).length) setLabels((current) => ({ ...current, ...next }))
39
+ })
40
+ .catch(() => {})
41
+ return () => controller.abort()
42
+ }, [idsKey])
43
+
44
+ return labels
45
+ }
@@ -0,0 +1,99 @@
1
+ import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
2
+ import { MAX_USER_LOOKUP_IDS } from '@open-mercato/core/modules/auth/lib/userIdFilter'
3
+
4
+ export type DeviceUserOption = {
5
+ value: string
6
+ label: string
7
+ }
8
+
9
+ type AuthUserItem = {
10
+ id?: unknown
11
+ name?: unknown
12
+ email?: unknown
13
+ }
14
+
15
+ const SEARCH_PAGE_SIZE = 20
16
+ // Imported rather than restated: `parseIdsParam` slices past the route's cap without complaining,
17
+ // so a client batch larger than the server accepts loses the overflow ids silently.
18
+ const MAX_IDS_PER_LOOKUP = MAX_USER_LOOKUP_IDS
19
+
20
+ /**
21
+ * Two label styles on purpose. A picker suggestion has to disambiguate two people with the same
22
+ * display name, and neither `CrudForm`'s combobox nor `FilterBar` renders anything but the label —
23
+ * so the email has to live in the label there. A resolved column label is read next to a device,
24
+ * where the email is noise.
25
+ */
26
+ type LabelStyle = 'search' | 'compact'
27
+
28
+ function toOption(item: AuthUserItem | null | undefined, style: LabelStyle): DeviceUserOption[] {
29
+ if (!item || typeof item.id !== 'string' || !item.id.trim()) return []
30
+ const id = item.id.trim()
31
+ const name = typeof item.name === 'string' && item.name.trim() ? item.name.trim() : null
32
+ const email = typeof item.email === 'string' && item.email.trim() ? item.email.trim() : null
33
+ const label = style === 'search' && name && email ? `${name} — ${email}` : name ?? email ?? id
34
+ return [{ value: id, label }]
35
+ }
36
+
37
+ // `devices.admin` declares `dependsOn: ['auth.users.list']`, but dependsOn only diagnoses — a
38
+ // hand-built role can still reach these screens without it until the ACL editor or
39
+ // `sync-role-acls` fixes it. `x-om-forbidden-redirect: 0` keeps that 403 from bouncing the whole
40
+ // page to /login. `null` means the call itself failed, which callers must not
41
+ // confuse with a successful call that matched nobody — a caller caching "already resolved" would
42
+ // otherwise remember a transient network error forever.
43
+ async function fetchUsers(
44
+ params: URLSearchParams,
45
+ style: LabelStyle,
46
+ signal?: AbortSignal,
47
+ ): Promise<DeviceUserOption[] | null> {
48
+ const call = await apiCall<{ items?: AuthUserItem[] }>(
49
+ `/api/auth/users?${params.toString()}`,
50
+ { headers: { 'x-om-forbidden-redirect': '0' }, signal },
51
+ { fallback: null },
52
+ ).catch(() => null)
53
+ if (!call || !call.ok) return null
54
+ return (call.result?.items ?? []).flatMap((item) => toOption(item, style))
55
+ }
56
+
57
+ export async function loadDeviceUserOptions(query?: string): Promise<DeviceUserOption[]> {
58
+ const params = new URLSearchParams()
59
+ params.set('page', '1')
60
+ params.set('pageSize', String(SEARCH_PAGE_SIZE))
61
+ const trimmed = query?.trim()
62
+ if (trimmed) params.set('search', trimmed)
63
+ // A picker has nothing to cache, so a failed lookup is just an empty suggestion list.
64
+ return (await fetchUsers(params, 'search')) ?? []
65
+ }
66
+
67
+ /**
68
+ * The outcome of a batch lookup. `resolvedIds` lists the ids the server actually answered for —
69
+ * an id that came back without a row (deleted user) still counts as resolved, an id whose request
70
+ * failed does not. Callers cache on `resolvedIds`, so a transient failure is retried rather than
71
+ * remembered as a permanent blank.
72
+ */
73
+ export type DeviceUserLookup = {
74
+ options: DeviceUserOption[]
75
+ resolvedIds: string[]
76
+ }
77
+
78
+ // Batch id → label resolution for rows already on screen, so a device whose owner never appeared in
79
+ // a search result still renders a name instead of a bare UUID.
80
+ export async function resolveDeviceUserOptions(ids: string[], signal?: AbortSignal): Promise<DeviceUserLookup> {
81
+ const unique = Array.from(new Set(ids.map((id) => id.trim()).filter(Boolean)))
82
+ if (unique.length === 0) return { options: [], resolvedIds: [] }
83
+ const options: DeviceUserOption[] = []
84
+ const resolvedIds: string[] = []
85
+ for (let offset = 0; offset < unique.length; offset += MAX_IDS_PER_LOOKUP) {
86
+ const batch = unique.slice(offset, offset + MAX_IDS_PER_LOOKUP)
87
+ const params = new URLSearchParams()
88
+ params.set('page', '1')
89
+ params.set('pageSize', String(batch.length))
90
+ // URLSearchParams encodes on toString(); pre-encoding here would double-escape the commas.
91
+ params.set('ids', batch.join(','))
92
+ const batchOptions = await fetchUsers(params, 'compact', signal)
93
+ // One failed batch must not cost the batches that did answer.
94
+ if (batchOptions === null) continue
95
+ options.push(...batchOptions)
96
+ resolvedIds.push(...batch)
97
+ }
98
+ return { options, resolvedIds }
99
+ }
@@ -23,8 +23,9 @@
23
23
  "devices.form.pushTokenHint": "Optional. Sicher gespeichert und nie wieder angezeigt.",
24
24
  "devices.form.success.created": "Gerät registriert",
25
25
  "devices.form.success.updated": "Gerät aktualisiert",
26
- "devices.form.userId": "Benutzer-ID",
27
- "devices.form.userIdHint": "UUID des Benutzers, dem dieses Gerät gehört.",
26
+ "devices.form.userId": "Benutzer",
27
+ "devices.form.userIdHint": "Namen oder E-Mail eingeben und den Besitzer aus der Liste auswählen.",
28
+ "devices.form.userIdPlaceholder": "Benutzer suchen",
28
29
  "devices.list.actions.deactivate": "Deaktivieren",
29
30
  "devices.list.actions.edit": "Bearbeiten",
30
31
  "devices.list.actions.register": "Gerät registrieren",
@@ -23,8 +23,9 @@
23
23
  "devices.form.pushTokenHint": "Optional. Stored securely and never shown again.",
24
24
  "devices.form.success.created": "Device registered",
25
25
  "devices.form.success.updated": "Device updated",
26
- "devices.form.userId": "User ID",
27
- "devices.form.userIdHint": "UUID of the user who owns this device.",
26
+ "devices.form.userId": "User",
27
+ "devices.form.userIdHint": "Start typing a name or email, then pick the owner from the list.",
28
+ "devices.form.userIdPlaceholder": "Search users",
28
29
  "devices.list.actions.deactivate": "Deactivate",
29
30
  "devices.list.actions.edit": "Edit",
30
31
  "devices.list.actions.register": "Register device",
@@ -23,8 +23,9 @@
23
23
  "devices.form.pushTokenHint": "Opcional. Se almacena de forma segura y no se vuelve a mostrar.",
24
24
  "devices.form.success.created": "Dispositivo registrado",
25
25
  "devices.form.success.updated": "Dispositivo actualizado",
26
- "devices.form.userId": "ID de usuario",
27
- "devices.form.userIdHint": "UUID del usuario propietario de este dispositivo.",
26
+ "devices.form.userId": "Usuario",
27
+ "devices.form.userIdHint": "Empieza a escribir un nombre o correo electrónico y elige el propietario de la lista.",
28
+ "devices.form.userIdPlaceholder": "Buscar usuarios",
28
29
  "devices.list.actions.deactivate": "Desactivar",
29
30
  "devices.list.actions.edit": "Editar",
30
31
  "devices.list.actions.register": "Registrar dispositivo",
@@ -23,8 +23,9 @@
23
23
  "devices.form.pushTokenHint": "선택 사항입니다. 안전하게 저장되며 다시 표시되지 않습니다.",
24
24
  "devices.form.success.created": "기기가 등록되었습니다",
25
25
  "devices.form.success.updated": "기기가 수정되었습니다",
26
- "devices.form.userId": "사용자 ID",
27
- "devices.form.userIdHint": " 기기를 소유한 사용자의 UUID입니다.",
26
+ "devices.form.userId": "사용자",
27
+ "devices.form.userIdHint": "이름 또는 이메일을 입력한 다음 목록에서 소유자를 선택하세요.",
28
+ "devices.form.userIdPlaceholder": "사용자 검색",
28
29
  "devices.list.actions.deactivate": "비활성화",
29
30
  "devices.list.actions.edit": "수정",
30
31
  "devices.list.actions.register": "기기 등록",
@@ -23,8 +23,9 @@
23
23
  "devices.form.pushTokenHint": "Opcjonalne. Token jest przechowywany bezpiecznie i nigdy więcej niewyświetlany.",
24
24
  "devices.form.success.created": "Urządzenie zarejestrowane",
25
25
  "devices.form.success.updated": "Urządzenie zaktualizowane",
26
- "devices.form.userId": "ID użytkownika",
27
- "devices.form.userIdHint": "UUID użytkownika, do którego należy to urządzenie.",
26
+ "devices.form.userId": "Użytkownik",
27
+ "devices.form.userIdHint": "Zacznij wpisywać nazwę lub e-mail, a następnie wybierz właściciela z listy.",
28
+ "devices.form.userIdPlaceholder": "Szukaj użytkowników",
28
29
  "devices.list.actions.deactivate": "Dezaktywuj",
29
30
  "devices.list.actions.edit": "Edytuj",
30
31
  "devices.list.actions.register": "Zarejestruj urządzenie",
@@ -2,8 +2,12 @@ import type { ModuleSetupConfig } from '@open-mercato/shared/modules/setup'
2
2
 
3
3
  export const setup: ModuleSetupConfig = {
4
4
  defaultRoleFeatures: {
5
- superadmin: ['devices.*'],
6
- admin: ['devices.*'],
5
+ // `auth.users.list` is granted alongside `devices.admin` rather than left to the auth module's
6
+ // own `admin: ['auth.*']`, so the dependency declared in `acl.ts` holds even where that grant
7
+ // was narrowed. Without it the owner picker has nothing to offer and the register form cannot
8
+ // be completed. Existing tenants pick this up via `yarn mercato auth sync-role-acls`.
9
+ superadmin: ['devices.*', 'auth.users.list'],
10
+ admin: ['devices.*', 'auth.users.list'],
7
11
  employee: ['devices.view', 'devices.manage'],
8
12
  },
9
13
  }
@@ -46,6 +46,7 @@ type OrganizationsResponse = {
46
46
  page: number
47
47
  pageSize: number
48
48
  totalPages: number
49
+ totalIsCapped?: boolean
49
50
  isSuperAdmin?: boolean
50
51
  }
51
52
 
@@ -179,6 +180,7 @@ export default function DirectoryOrganizationsPage() {
179
180
  }, [isSuperAdmin, t])
180
181
  const total = data?.total ?? 0
181
182
  const totalPages = data?.totalPages ?? 0
183
+ const totalIsCapped = data?.totalIsCapped === true
182
184
 
183
185
  const deleteMutationContextId = 'directory-organizations-list:single-delete'
184
186
  const { runMutation: runDeleteMutation, retryLastMutation: retryDeleteMutation } = useGuardedMutation<{
@@ -290,7 +292,7 @@ export default function DirectoryOrganizationsPage() {
290
292
  createLabel={t('directory.organizations.list.actions.create', 'Create')}
291
293
  />
292
294
  )}
293
- pagination={{ page, pageSize: 50, total, totalPages, onPageChange: setPage }}
295
+ pagination={{ page, pageSize: 50, total, totalPages, totalIsCapped, onPageChange: setPage }}
294
296
  isLoading={isLoading}
295
297
  />
296
298
  </PageBody>
@@ -35,6 +35,7 @@ type TenantsResponse = {
35
35
  page: number
36
36
  pageSize: number
37
37
  totalPages: number
38
+ totalIsCapped?: boolean
38
39
  }
39
40
 
40
41
 
@@ -119,6 +120,7 @@ export default function DirectoryTenantsPage() {
119
120
  const rows = data?.items ?? []
120
121
  const total = data?.total ?? 0
121
122
  const totalPages = data?.totalPages ?? 0
123
+ const totalIsCapped = data?.totalIsCapped === true
122
124
 
123
125
  const deleteMutationContextId = 'directory-tenants-list:single-delete'
124
126
  const { runMutation: runDeleteMutation, retryLastMutation: retryDeleteMutation } = useGuardedMutation<{
@@ -213,7 +215,7 @@ export default function DirectoryTenantsPage() {
213
215
  createLabel={t('directory.tenants.list.actions.create', 'Create')}
214
216
  />
215
217
  )}
216
- pagination={{ page, pageSize: 20, total, totalPages, onPageChange: setPage }}
218
+ pagination={{ page, pageSize: 20, total, totalPages, totalIsCapped, onPageChange: setPage }}
217
219
  isLoading={isLoading}
218
220
  />
219
221
  </PageBody>
@@ -1,6 +1,18 @@
1
+ import { asClass, asFunction } from 'awilix'
2
+ import type { EntityManager } from '@mikro-orm/postgresql'
1
3
  import type { AppContainer } from '@open-mercato/shared/lib/di/container'
4
+ import { DefaultOrganizationScopeService } from './services/organizationScopeService'
5
+ import { DefaultOrganizationHierarchyService } from './services/organizationHierarchyService'
6
+
7
+ type OrganizationScopeRbac = ConstructorParameters<typeof DefaultOrganizationScopeService>[1]
2
8
 
3
9
  export function register(container: AppContainer) {
4
- // Directory module has no services yet; placeholder for future overrides
10
+ container.register({
11
+ organizationHierarchyService: asClass(DefaultOrganizationHierarchyService).scoped(),
12
+ organizationScopeService: asFunction((cradle: { em: EntityManager; rbacService: OrganizationScopeRbac }) =>
13
+ new DefaultOrganizationScopeService(cradle.em, cradle.rbacService, container),
14
+ )
15
+ .scoped()
16
+ .proxy(),
17
+ })
5
18
  }
6
-