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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (941) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/helpers/integration/api.js +1 -13
  3. package/dist/helpers/integration/api.js.map +2 -2
  4. package/dist/helpers/integration/communicationChannelsFixtures.js +0 -19
  5. package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
  6. package/dist/modules/api_keys/api/keys/route.js +1 -1
  7. package/dist/modules/api_keys/api/keys/route.js.map +2 -2
  8. package/dist/modules/api_keys/backend/api-keys/page.js +1 -3
  9. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  10. package/dist/modules/attachments/api/route.js +2 -2
  11. package/dist/modules/attachments/api/route.js.map +2 -2
  12. package/dist/modules/attachments/components/AttachmentLibrary.js +0 -2
  13. package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
  14. package/dist/modules/attachments/di.js +1 -11
  15. package/dist/modules/attachments/di.js.map +2 -2
  16. package/dist/modules/attachments/index.js.map +1 -1
  17. package/dist/modules/attachments/lib/scoped-upload-service.js +2 -15
  18. package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
  19. package/dist/modules/attachments/lib/upload-limits.js +2 -6
  20. package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
  21. package/dist/modules/audit_logs/backend/audit-logs/page.js +0 -6
  22. package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
  23. package/dist/modules/audit_logs/lib/display-helpers.js +11 -19
  24. package/dist/modules/audit_logs/lib/display-helpers.js.map +2 -2
  25. package/dist/modules/audit_logs/services/actionLogService.js +12 -57
  26. package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
  27. package/dist/modules/auth/acl.js +5 -30
  28. package/dist/modules/auth/acl.js.map +2 -2
  29. package/dist/modules/auth/api/feature-check.js +2 -8
  30. package/dist/modules/auth/api/feature-check.js.map +2 -2
  31. package/dist/modules/auth/api/login.js +20 -4
  32. package/dist/modules/auth/api/login.js.map +2 -2
  33. package/dist/modules/auth/api/roles/acl/route.js +33 -28
  34. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  35. package/dist/modules/auth/api/routeError.js +11 -0
  36. package/dist/modules/auth/api/routeError.js.map +7 -0
  37. package/dist/modules/auth/api/session/refresh.js +1 -25
  38. package/dist/modules/auth/api/session/refresh.js.map +2 -2
  39. package/dist/modules/auth/api/users/acl/route.js +73 -102
  40. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  41. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js +1 -5
  42. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js.map +2 -2
  43. package/dist/modules/auth/backend/roles/page.js +1 -3
  44. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  45. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js +1 -5
  46. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js.map +2 -2
  47. package/dist/modules/auth/backend/users/page.js +1 -2
  48. package/dist/modules/auth/backend/users/page.js.map +2 -2
  49. package/dist/modules/auth/components/AclEditor.js +30 -39
  50. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  51. package/dist/modules/auth/data/entities.js.map +2 -2
  52. package/dist/modules/auth/data/validators.js +1 -5
  53. package/dist/modules/auth/data/validators.js.map +2 -2
  54. package/dist/modules/auth/di.js +9 -35
  55. package/dist/modules/auth/di.js.map +2 -2
  56. package/dist/modules/auth/frontend/reset/[token]/page.js +0 -46
  57. package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
  58. package/dist/modules/auth/lib/grantChecks.js.map +2 -2
  59. package/dist/modules/auth/services/authService.js +2 -16
  60. package/dist/modules/auth/services/authService.js.map +2 -2
  61. package/dist/modules/auth/services/rbacService.js +24 -67
  62. package/dist/modules/auth/services/rbacService.js.map +3 -3
  63. package/dist/modules/business_rules/backend/logs/page.js +1 -3
  64. package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
  65. package/dist/modules/business_rules/backend/rules/[id]/page.meta.js +6 -1
  66. package/dist/modules/business_rules/backend/rules/[id]/page.meta.js.map +2 -2
  67. package/dist/modules/business_rules/backend/rules/create/page.meta.js +5 -1
  68. package/dist/modules/business_rules/backend/rules/create/page.meta.js.map +2 -2
  69. package/dist/modules/business_rules/backend/rules/page.js +1 -3
  70. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  71. package/dist/modules/business_rules/backend/sets/[id]/page.meta.js +6 -1
  72. package/dist/modules/business_rules/backend/sets/[id]/page.meta.js.map +2 -2
  73. package/dist/modules/business_rules/backend/sets/create/page.meta.js +5 -1
  74. package/dist/modules/business_rules/backend/sets/create/page.meta.js.map +2 -2
  75. package/dist/modules/business_rules/backend/sets/page.js +1 -3
  76. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  77. package/dist/modules/business_rules/lib/expression-evaluator.js +9 -9
  78. package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
  79. package/dist/modules/business_rules/lib/rule-evaluator.js +9 -10
  80. package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
  81. package/dist/modules/catalog/ai-agents.js +1 -1
  82. package/dist/modules/catalog/ai-agents.js.map +1 -1
  83. package/dist/modules/catalog/ai-tools/merchandising-pack.js +2 -2
  84. package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
  85. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +2 -5
  86. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
  87. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +0 -2
  88. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  89. package/dist/modules/catalog/components/products/ProductsDataTable.js +1 -7
  90. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  91. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js +0 -2
  92. package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js.map +2 -2
  93. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +1 -9
  94. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +2 -2
  95. package/dist/modules/communication_channels/api/post/test-seed/route.js +10 -95
  96. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  97. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +0 -3
  98. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
  99. package/dist/modules/communication_channels/commands/ingest-inbound-message.js +1 -14
  100. package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
  101. package/dist/modules/communication_channels/di.js +1 -7
  102. package/dist/modules/communication_channels/di.js.map +2 -2
  103. package/dist/modules/communication_channels/lib/email-capabilities.js +1 -4
  104. package/dist/modules/communication_channels/lib/email-capabilities.js.map +2 -2
  105. package/dist/modules/communication_channels/lib/test-seed.js +2 -41
  106. package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
  107. package/dist/modules/configs/lib/system-status.js +0 -9
  108. package/dist/modules/configs/lib/system-status.js.map +2 -2
  109. package/dist/modules/currencies/backend/currencies/page.js +1 -3
  110. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  111. package/dist/modules/currencies/backend/exchange-rates/page.js +1 -3
  112. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  113. package/dist/modules/customer_accounts/api/admin/domain-mappings.js +0 -9
  114. package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +2 -2
  115. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +1 -3
  116. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  117. package/dist/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.js +84 -0
  118. package/dist/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.js.map +7 -0
  119. package/dist/modules/customer_accounts/backend/customer_accounts/settings/page.js +7 -81
  120. package/dist/modules/customer_accounts/backend/customer_accounts/settings/page.js.map +2 -2
  121. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +523 -0
  122. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +7 -0
  123. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.js +731 -0
  124. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.js.map +7 -0
  125. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +7 -727
  126. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  127. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +7 -521
  128. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  129. package/dist/modules/customer_accounts/extension-points.js +1 -1
  130. package/dist/modules/customer_accounts/extension-points.js.map +2 -2
  131. package/dist/modules/customer_accounts/lib/portalUrl.js +69 -0
  132. package/dist/modules/customer_accounts/lib/portalUrl.js.map +7 -0
  133. package/dist/modules/customer_accounts/services/domainMappingService.js +0 -10
  134. package/dist/modules/customer_accounts/services/domainMappingService.js.map +2 -2
  135. package/dist/modules/customers/ai-tools/companies-pack.js +1 -4
  136. package/dist/modules/customers/ai-tools/companies-pack.js.map +2 -2
  137. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +2 -13
  138. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +2 -2
  139. package/dist/modules/customers/ai-tools/deals-pack.js +6 -52
  140. package/dist/modules/customers/ai-tools/deals-pack.js.map +2 -2
  141. package/dist/modules/customers/ai-tools/people-pack.js +1 -4
  142. package/dist/modules/customers/ai-tools/people-pack.js.map +2 -2
  143. package/dist/modules/customers/api/activities/route.js +6 -48
  144. package/dist/modules/customers/api/activities/route.js.map +2 -2
  145. package/dist/modules/customers/api/companies/[id]/people/route.js +64 -20
  146. package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
  147. package/dist/modules/customers/api/companies/[id]/route.js +94 -17
  148. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  149. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +5 -8
  150. package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
  151. package/dist/modules/customers/api/deals/[id]/companies/route.js +1 -1
  152. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
  153. package/dist/modules/customers/api/deals/[id]/people/route.js +1 -1
  154. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  155. package/dist/modules/customers/api/deals/[id]/route.js +25 -8
  156. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  157. package/dist/modules/customers/api/deals/[id]/stats/route.js +22 -3
  158. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +2 -2
  159. package/dist/modules/customers/api/deals/aggregate/route.js +4 -11
  160. package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
  161. package/dist/modules/customers/api/deals/map/route.js +1 -2
  162. package/dist/modules/customers/api/deals/map/route.js.map +2 -2
  163. package/dist/modules/customers/api/deals/route.js +1 -38
  164. package/dist/modules/customers/api/deals/route.js.map +2 -2
  165. package/dist/modules/customers/api/entity-roles-factory.js +4 -4
  166. package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
  167. package/dist/modules/customers/api/interactions/route.js +1 -3
  168. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  169. package/dist/modules/customers/api/interactions/tasks/route.js +4 -27
  170. package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
  171. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +3 -4
  172. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
  173. package/dist/modules/customers/api/people/[id]/companies/context.js +1 -1
  174. package/dist/modules/customers/api/people/[id]/companies/context.js.map +2 -2
  175. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +1 -1
  176. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
  177. package/dist/modules/customers/api/people/[id]/route.js +10 -11
  178. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  179. package/dist/modules/customers/api/people/check-phone/route.js +9 -51
  180. package/dist/modules/customers/api/people/check-phone/route.js.map +2 -2
  181. package/dist/modules/customers/api/todos/route.js +5 -30
  182. package/dist/modules/customers/api/todos/route.js.map +2 -2
  183. package/dist/modules/customers/backend/customers/companies/page.js +4 -6
  184. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  185. package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -6
  186. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  187. package/dist/modules/customers/backend/customers/deals/page.js +4 -7
  188. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  189. package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js +13 -4
  190. package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js.map +2 -2
  191. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js +14 -85
  192. package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js.map +2 -2
  193. package/dist/modules/customers/backend/customers/people/page.js +4 -6
  194. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  195. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js +3 -9
  196. package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js.map +2 -2
  197. package/dist/modules/customers/commands/deals.js +34 -21
  198. package/dist/modules/customers/commands/deals.js.map +2 -2
  199. package/dist/modules/customers/commands/interactions.js.map +1 -1
  200. package/dist/modules/customers/commands/personCompanyLinks.js +2 -131
  201. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  202. package/dist/modules/customers/components/CustomerTodosTable.js +0 -1
  203. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  204. package/dist/modules/customers/components/DealsKpiStrip.js +6 -7
  205. package/dist/modules/customers/components/DealsKpiStrip.js.map +2 -2
  206. package/dist/modules/customers/components/calendar/AgendaList.js +2 -2
  207. package/dist/modules/customers/components/calendar/AgendaList.js.map +2 -2
  208. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -1
  209. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
  210. package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
  211. package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
  212. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +1 -1
  213. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
  214. package/dist/modules/customers/components/calendar/EventBlock.js +1 -1
  215. package/dist/modules/customers/components/calendar/EventBlock.js.map +2 -2
  216. package/dist/modules/customers/components/calendar/EventPeekPopover.js +2 -3
  217. package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +2 -2
  218. package/dist/modules/customers/components/calendar/editor/PeopleField.js +5 -40
  219. package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
  220. package/dist/modules/customers/components/calendar/editor/hooks.js +1 -2
  221. package/dist/modules/customers/components/calendar/editor/hooks.js.map +2 -2
  222. package/dist/modules/customers/components/calendar/types.js +1 -1
  223. package/dist/modules/customers/components/calendar/types.js.map +2 -2
  224. package/dist/modules/customers/components/detail/AssignRoleDialog.js +33 -28
  225. package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +2 -2
  226. package/dist/modules/customers/components/detail/CompanyKpiBar.js +4 -5
  227. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
  228. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +1 -3
  229. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  230. package/dist/modules/customers/components/detail/DealForm.js +7 -19
  231. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  232. package/dist/modules/customers/components/detail/DealsSection.js +5 -6
  233. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  234. package/dist/modules/customers/components/detail/EntityTagsDialog.js +11 -35
  235. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  236. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +1 -3
  237. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
  238. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +13 -19
  239. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
  240. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +4 -4
  241. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
  242. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +3 -3
  243. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  244. package/dist/modules/customers/components/detail/utils.js +5 -5
  245. package/dist/modules/customers/components/detail/utils.js.map +2 -2
  246. package/dist/modules/customers/data/entities.js.map +1 -1
  247. package/dist/modules/customers/data/validators.js +3 -32
  248. package/dist/modules/customers/data/validators.js.map +2 -2
  249. package/dist/modules/customers/events.js +0 -5
  250. package/dist/modules/customers/events.js.map +2 -2
  251. package/dist/modules/customers/lib/calendar/conflicts.js +2 -8
  252. package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
  253. package/dist/modules/customers/lib/calendar/editorPayload.js +2 -3
  254. package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
  255. package/dist/modules/customers/lib/calendar/mapItem.js +3 -8
  256. package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
  257. package/dist/modules/customers/lib/dealStatus.js +0 -30
  258. package/dist/modules/customers/lib/dealStatus.js.map +2 -2
  259. package/dist/modules/customers/lib/findPeopleByAddresses.js +0 -1
  260. package/dist/modules/customers/lib/findPeopleByAddresses.js.map +2 -2
  261. package/dist/modules/customers/lib/personCompanies.js +2 -100
  262. package/dist/modules/customers/lib/personCompanies.js.map +2 -2
  263. package/dist/modules/customers/lib/todoCompatibility.js +0 -12
  264. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  265. package/dist/modules/dashboards/lib/widgetScope.js +1 -6
  266. package/dist/modules/dashboards/lib/widgetScope.js.map +2 -2
  267. package/dist/modules/data_sync/backend/data-sync/page.js +1 -3
  268. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  269. package/dist/modules/data_sync/lib/sync-engine.js +6 -72
  270. package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
  271. package/dist/modules/data_sync/workers/sync-export.js +1 -5
  272. package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
  273. package/dist/modules/data_sync/workers/sync-import.js +1 -5
  274. package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
  275. package/dist/modules/devices/api/admin/devices/[id]/route.js +32 -5
  276. package/dist/modules/devices/api/admin/devices/[id]/route.js.map +2 -2
  277. package/dist/modules/devices/api/admin/devices/route.js +1 -14
  278. package/dist/modules/devices/api/admin/devices/route.js.map +2 -2
  279. package/dist/modules/devices/api/deviceList.js +12 -99
  280. package/dist/modules/devices/api/deviceList.js.map +2 -2
  281. package/dist/modules/devices/api/openapi.js +1 -3
  282. package/dist/modules/devices/api/openapi.js.map +2 -2
  283. package/dist/modules/devices/api/route.js +1 -9
  284. package/dist/modules/devices/api/route.js.map +2 -2
  285. package/dist/modules/devices/backend/devices/[id]/page.js +8 -8
  286. package/dist/modules/devices/backend/devices/[id]/page.js.map +2 -2
  287. package/dist/modules/devices/backend/devices/page.js +13 -15
  288. package/dist/modules/devices/backend/devices/page.js.map +2 -2
  289. package/dist/modules/directory/backend/directory/organizations/page.js +1 -2
  290. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  291. package/dist/modules/directory/backend/directory/tenants/page.js +1 -2
  292. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  293. package/dist/modules/directory/di.js +0 -9
  294. package/dist/modules/directory/di.js.map +2 -2
  295. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  296. package/dist/modules/entities/api/records.js +2 -4
  297. package/dist/modules/entities/api/records.js.map +2 -2
  298. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +1 -3
  299. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  300. package/dist/modules/eudr/api/plots/route.js +1 -5
  301. package/dist/modules/eudr/api/plots/route.js.map +2 -2
  302. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js +3 -1
  303. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js.map +2 -2
  304. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js +1 -0
  305. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js.map +2 -2
  306. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +0 -3
  307. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
  308. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js +4 -1
  309. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js.map +2 -2
  310. package/dist/modules/eudr/backend/eudr/page.meta.js +2 -2
  311. package/dist/modules/eudr/backend/eudr/page.meta.js.map +2 -2
  312. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js +8 -2
  313. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js.map +2 -2
  314. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js +3 -1
  315. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js.map +2 -2
  316. package/dist/modules/eudr/backend/eudr/plots/create/page.js +8 -2
  317. package/dist/modules/eudr/backend/eudr/plots/create/page.js.map +2 -2
  318. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js +1 -0
  319. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js.map +2 -2
  320. package/dist/modules/eudr/backend/eudr/plots/page.js +0 -3
  321. package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
  322. package/dist/modules/eudr/backend/eudr/plots/page.meta.js +4 -1
  323. package/dist/modules/eudr/backend/eudr/plots/page.meta.js.map +2 -2
  324. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js +3 -1
  325. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js.map +2 -2
  326. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js +1 -0
  327. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js.map +2 -2
  328. package/dist/modules/eudr/backend/eudr/product-mappings/page.js +0 -3
  329. package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
  330. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js +4 -1
  331. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js.map +2 -2
  332. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js +3 -1
  333. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js.map +2 -2
  334. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js +1 -0
  335. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js.map +2 -2
  336. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +0 -3
  337. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
  338. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js +4 -1
  339. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js.map +2 -2
  340. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js +2 -0
  341. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js.map +2 -2
  342. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js +3 -1
  343. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js.map +2 -2
  344. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js +1 -0
  345. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js.map +2 -2
  346. package/dist/modules/eudr/backend/eudr/statements/page.js +30 -28
  347. package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
  348. package/dist/modules/eudr/backend/eudr/statements/page.meta.js +4 -1
  349. package/dist/modules/eudr/backend/eudr/statements/page.meta.js.map +2 -2
  350. package/dist/modules/eudr/commands/statements.js +8 -3
  351. package/dist/modules/eudr/commands/statements.js.map +2 -2
  352. package/dist/modules/eudr/components/crudErrorI18n.js +21 -1
  353. package/dist/modules/eudr/components/crudErrorI18n.js.map +2 -2
  354. package/dist/modules/eudr/components/formConfig.js +6 -2
  355. package/dist/modules/eudr/components/formConfig.js.map +2 -2
  356. package/dist/modules/eudr/data/validators.js +1 -4
  357. package/dist/modules/eudr/data/validators.js.map +2 -2
  358. package/dist/modules/eudr/lib/statement-lifecycle.js +9 -1
  359. package/dist/modules/eudr/lib/statement-lifecycle.js.map +2 -2
  360. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +0 -1
  361. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  362. package/dist/modules/feature_toggles/components/OverridesTable.js +0 -1
  363. package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
  364. package/dist/modules/feature_toggles/defaults.json +8 -0
  365. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +0 -3
  366. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
  367. package/dist/modules/inbox_ops/backend/inbox-ops/page.js +0 -3
  368. package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
  369. package/dist/modules/inbox_ops/lib/htmlToPlainText.js +12 -1
  370. package/dist/modules/inbox_ops/lib/htmlToPlainText.js.map +2 -2
  371. package/dist/modules/integrations/api/[id]/credentials/route.js +1 -6
  372. package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
  373. package/dist/modules/integrations/backend/integrations/[id]/page.js +29 -38
  374. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  375. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +9 -36
  376. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  377. package/dist/modules/integrations/data/validators.js +3 -11
  378. package/dist/modules/integrations/data/validators.js.map +2 -2
  379. package/dist/modules/integrations/lib/credentials-masking.js +2 -6
  380. package/dist/modules/integrations/lib/credentials-masking.js.map +2 -2
  381. package/dist/modules/messages/api/[id]/route.js +1 -29
  382. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  383. package/dist/modules/messages/api/openapi.js +2 -17
  384. package/dist/modules/messages/api/openapi.js.map +2 -2
  385. package/dist/modules/messages/api/route.js +2 -17
  386. package/dist/modules/messages/api/route.js.map +2 -2
  387. package/dist/modules/messages/components/MessagesInboxPageClient.js +14 -7
  388. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  389. package/dist/modules/messages/components/inboxFilters.js +0 -15
  390. package/dist/modules/messages/components/inboxFilters.js.map +2 -2
  391. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +1 -11
  392. package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +2 -2
  393. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +1 -3
  394. package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +2 -2
  395. package/dist/modules/messages/components/message-detail/panels/thread-panel.js +1 -2
  396. package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +2 -2
  397. package/dist/modules/messages/components/messageListLabels.js +2 -14
  398. package/dist/modules/messages/components/messageListLabels.js.map +2 -2
  399. package/dist/modules/messages/data/validators.js +4 -18
  400. package/dist/modules/messages/data/validators.js.map +2 -2
  401. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +6 -4
  402. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
  403. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +1 -3
  404. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  405. package/dist/modules/payment_gateways/lib/webhook-processor.js +0 -7
  406. package/dist/modules/payment_gateways/lib/webhook-processor.js.map +2 -2
  407. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +0 -3
  408. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  409. package/dist/modules/push_notifications/backend/push_notifications/page.js +1 -3
  410. package/dist/modules/push_notifications/backend/push_notifications/page.js.map +2 -2
  411. package/dist/modules/push_notifications/backend/push_notifications/send/page.js +1 -1
  412. package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +2 -2
  413. package/dist/modules/query_index/lib/engine.js +51 -150
  414. package/dist/modules/query_index/lib/engine.js.map +2 -2
  415. package/dist/modules/query_index/lib/search-tokens.js +3 -79
  416. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  417. package/dist/modules/resources/backend/resources/resource-types/page.js +1 -3
  418. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  419. package/dist/modules/resources/backend/resources/resources/page.js +1 -3
  420. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  421. package/dist/modules/sales/backend/sales/channels/offers/page.js +0 -3
  422. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  423. package/dist/modules/sales/backend/sales/channels/page.js +0 -3
  424. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  425. package/dist/modules/sales/backend/sales/documents/[id]/page.js +8 -10
  426. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  427. package/dist/modules/sales/commands/documents.js +1 -79
  428. package/dist/modules/sales/commands/documents.js.map +2 -2
  429. package/dist/modules/sales/components/PriceWithCurrency.js +5 -7
  430. package/dist/modules/sales/components/PriceWithCurrency.js.map +2 -2
  431. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +0 -3
  432. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  433. package/dist/modules/sales/components/documents/AdjustmentsSection.js +6 -8
  434. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  435. package/dist/modules/sales/components/documents/ItemsSection.js +22 -51
  436. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  437. package/dist/modules/sales/components/documents/LineItemDialog.js +19 -84
  438. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  439. package/dist/modules/sales/components/documents/PaymentsSection.js +9 -23
  440. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  441. package/dist/modules/sales/components/documents/ReturnsSection.js +6 -8
  442. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  443. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +14 -68
  444. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  445. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +5 -6
  446. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +2 -2
  447. package/dist/modules/sales/components/documents/ShipmentDialog.js +4 -5
  448. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  449. package/dist/modules/sales/components/documents/ShipmentsSection.js +6 -8
  450. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  451. package/dist/modules/sales/components/documents/lineItemUtils.js +2 -2
  452. package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
  453. package/dist/modules/sales/data/entities.js +2 -8
  454. package/dist/modules/sales/data/entities.js.map +2 -2
  455. package/dist/modules/sales/extension-points.js +0 -1
  456. package/dist/modules/sales/extension-points.js.map +2 -2
  457. package/dist/modules/sales/setup.js +0 -2
  458. package/dist/modules/sales/setup.js.map +2 -2
  459. package/dist/modules/sales/widgets/injection/document-history/widget.client.js +44 -2
  460. package/dist/modules/sales/widgets/injection/document-history/widget.client.js.map +2 -2
  461. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +2 -10
  462. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +2 -2
  463. package/dist/modules/sales/widgets/injection-table.js +7 -4
  464. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  465. package/dist/modules/staff/backend/staff/leave-requests/page.js +0 -3
  466. package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
  467. package/dist/modules/staff/backend/staff/my-leave-requests/page.js +0 -3
  468. package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
  469. package/dist/modules/staff/backend/staff/team-members/page.js +0 -3
  470. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  471. package/dist/modules/staff/backend/staff/team-roles/page.js +0 -3
  472. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  473. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +0 -3
  474. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  475. package/dist/modules/staff/backend/staff/teams/page.js +0 -3
  476. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  477. package/dist/modules/staff/backend/staff/timesheets/page.js +18 -29
  478. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  479. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +0 -3
  480. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  481. package/dist/modules/sync_excel/lib/adapters/customers.js +0 -1
  482. package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
  483. package/dist/modules/warranty_claims/api/assignees/route.js +3 -3
  484. package/dist/modules/warranty_claims/api/assignees/route.js.map +2 -2
  485. package/dist/modules/warranty_claims/api/portal/attachments/route.js +2 -2
  486. package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
  487. package/dist/modules/warranty_claims/api/portal/claims/route.js +9 -12
  488. package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
  489. package/dist/modules/warranty_claims/backend/page.js +0 -3
  490. package/dist/modules/warranty_claims/backend/page.js.map +2 -2
  491. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js +0 -3
  492. package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js.map +2 -2
  493. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js +0 -3
  494. package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map +2 -2
  495. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js +0 -3
  496. package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js.map +2 -2
  497. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +0 -3
  498. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
  499. package/dist/modules/wms/api/warehouses/route.js +9 -13
  500. package/dist/modules/wms/api/warehouses/route.js.map +2 -2
  501. package/dist/modules/wms/api/zones/route.js +2 -15
  502. package/dist/modules/wms/api/zones/route.js.map +2 -2
  503. package/dist/modules/wms/commands/configuration.js +9 -121
  504. package/dist/modules/wms/commands/configuration.js.map +2 -2
  505. package/dist/modules/wms/commands/inventory-actions.js +0 -3
  506. package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
  507. package/dist/modules/wms/commands/shared.js +1 -9
  508. package/dist/modules/wms/commands/shared.js.map +2 -2
  509. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +111 -76
  510. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +3 -3
  511. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +0 -1
  512. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
  513. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +20 -16
  514. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  515. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +10 -6
  516. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  517. package/dist/modules/wms/components/backend/WmsLotsListPage.js +0 -1
  518. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
  519. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js +11 -7
  520. package/dist/modules/wms/components/backend/WmsOperationalDashboardPage.js.map +2 -2
  521. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +10 -6
  522. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  523. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +20 -27
  524. package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
  525. package/dist/modules/workflows/backend/definitions/page.js +1 -3
  526. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  527. package/dist/modules/workflows/backend/events/page.js +1 -3
  528. package/dist/modules/workflows/backend/events/page.js.map +2 -2
  529. package/dist/modules/workflows/backend/instances/page.js +1 -3
  530. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  531. package/dist/modules/workflows/backend/tasks/page.js +1 -3
  532. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  533. package/dist/modules/workflows/lib/activity-executor.js +0 -4
  534. package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
  535. package/package.json +10 -9
  536. package/src/helpers/integration/api.ts +1 -33
  537. package/src/helpers/integration/communicationChannelsFixtures.ts +1 -69
  538. package/src/modules/api_keys/api/keys/route.ts +1 -3
  539. package/src/modules/api_keys/backend/api-keys/page.tsx +1 -4
  540. package/src/modules/attachments/AGENTS.md +0 -15
  541. package/src/modules/attachments/api/route.ts +2 -2
  542. package/src/modules/attachments/components/AttachmentLibrary.tsx +0 -3
  543. package/src/modules/attachments/di.ts +0 -16
  544. package/src/modules/attachments/i18n/de.json +0 -5
  545. package/src/modules/attachments/i18n/en.json +0 -5
  546. package/src/modules/attachments/i18n/es.json +0 -5
  547. package/src/modules/attachments/i18n/ko.json +0 -5
  548. package/src/modules/attachments/i18n/pl.json +0 -5
  549. package/src/modules/attachments/index.ts +0 -10
  550. package/src/modules/attachments/lib/scoped-upload-service.ts +0 -46
  551. package/src/modules/attachments/lib/upload-limits.ts +2 -6
  552. package/src/modules/audit_logs/backend/audit-logs/page.tsx +0 -8
  553. package/src/modules/audit_logs/lib/display-helpers.tsx +32 -42
  554. package/src/modules/audit_logs/services/actionLogService.ts +11 -74
  555. package/src/modules/auth/acl.ts +6 -30
  556. package/src/modules/auth/api/feature-check.ts +3 -10
  557. package/src/modules/auth/api/login.ts +24 -9
  558. package/src/modules/auth/api/roles/acl/route.ts +39 -42
  559. package/src/modules/auth/api/routeError.ts +30 -0
  560. package/src/modules/auth/api/session/refresh.ts +1 -32
  561. package/src/modules/auth/api/users/acl/route.ts +101 -185
  562. package/src/modules/auth/backend/roles/[id]/edit/page.meta.ts +2 -5
  563. package/src/modules/auth/backend/roles/page.tsx +2 -4
  564. package/src/modules/auth/backend/users/[id]/edit/page.meta.ts +2 -5
  565. package/src/modules/auth/backend/users/page.tsx +2 -3
  566. package/src/modules/auth/components/AclEditor.tsx +33 -63
  567. package/src/modules/auth/data/entities.ts +1 -4
  568. package/src/modules/auth/data/validators.ts +0 -5
  569. package/src/modules/auth/di.ts +16 -46
  570. package/src/modules/auth/frontend/reset/[token]/page.tsx +0 -74
  571. package/src/modules/auth/i18n/de.json +0 -389
  572. package/src/modules/auth/i18n/en.json +0 -389
  573. package/src/modules/auth/i18n/es.json +0 -389
  574. package/src/modules/auth/i18n/ko.json +0 -389
  575. package/src/modules/auth/i18n/pl.json +2 -391
  576. package/src/modules/auth/lib/grantChecks.ts +0 -6
  577. package/src/modules/auth/services/authService.ts +2 -18
  578. package/src/modules/auth/services/rbacService.ts +24 -110
  579. package/src/modules/business_rules/backend/logs/page.tsx +1 -4
  580. package/src/modules/business_rules/backend/rules/[id]/page.meta.ts +5 -0
  581. package/src/modules/business_rules/backend/rules/create/page.meta.ts +5 -1
  582. package/src/modules/business_rules/backend/rules/page.tsx +1 -4
  583. package/src/modules/business_rules/backend/sets/[id]/page.meta.ts +5 -0
  584. package/src/modules/business_rules/backend/sets/create/page.meta.ts +5 -1
  585. package/src/modules/business_rules/backend/sets/page.tsx +1 -4
  586. package/src/modules/business_rules/lib/expression-evaluator.ts +9 -9
  587. package/src/modules/business_rules/lib/rule-evaluator.ts +9 -10
  588. package/src/modules/catalog/ai-agents.ts +1 -1
  589. package/src/modules/catalog/ai-tools/merchandising-pack.ts +2 -2
  590. package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +5 -12
  591. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +0 -3
  592. package/src/modules/catalog/components/products/ProductsDataTable.tsx +0 -7
  593. package/src/modules/catalog/i18n/de.json +0 -1
  594. package/src/modules/catalog/i18n/en.json +0 -1
  595. package/src/modules/catalog/i18n/es.json +0 -1
  596. package/src/modules/catalog/i18n/ko.json +0 -1
  597. package/src/modules/catalog/i18n/pl.json +0 -1
  598. package/src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx +0 -4
  599. package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +1 -17
  600. package/src/modules/communication_channels/api/post/test-seed/route.ts +16 -155
  601. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +0 -4
  602. package/src/modules/communication_channels/commands/ingest-inbound-message.ts +1 -38
  603. package/src/modules/communication_channels/di.ts +0 -7
  604. package/src/modules/communication_channels/lib/adapter.ts +0 -14
  605. package/src/modules/communication_channels/lib/email-capabilities.ts +0 -4
  606. package/src/modules/communication_channels/lib/test-seed.ts +4 -64
  607. package/src/modules/configs/i18n/de.json +0 -2
  608. package/src/modules/configs/i18n/en.json +0 -2
  609. package/src/modules/configs/i18n/es.json +0 -2
  610. package/src/modules/configs/i18n/ko.json +0 -2
  611. package/src/modules/configs/i18n/pl.json +0 -2
  612. package/src/modules/configs/lib/system-status.ts +0 -9
  613. package/src/modules/currencies/backend/currencies/page.tsx +1 -4
  614. package/src/modules/currencies/backend/exchange-rates/page.tsx +1 -4
  615. package/src/modules/customer_accounts/api/admin/domain-mappings.ts +0 -7
  616. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +1 -4
  617. package/src/modules/customer_accounts/backend/customer_accounts/settings/CustomerAccountsSettingsPageClient.tsx +138 -0
  618. package/src/modules/customer_accounts/backend/customer_accounts/settings/page.tsx +8 -132
  619. package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +598 -0
  620. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/PortalUserDetailPageClient.tsx +838 -0
  621. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +6 -838
  622. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +6 -590
  623. package/src/modules/customer_accounts/extension-points.ts +1 -1
  624. package/src/modules/customer_accounts/lib/portalUrl.ts +112 -0
  625. package/src/modules/customer_accounts/services/domainMappingService.ts +0 -10
  626. package/src/modules/customers/ai-tools/companies-pack.ts +1 -4
  627. package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +2 -17
  628. package/src/modules/customers/ai-tools/deals-pack.ts +1 -66
  629. package/src/modules/customers/ai-tools/people-pack.ts +1 -4
  630. package/src/modules/customers/api/activities/route.ts +0 -45
  631. package/src/modules/customers/api/companies/[id]/people/route.ts +73 -24
  632. package/src/modules/customers/api/companies/[id]/route.ts +107 -24
  633. package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +8 -16
  634. package/src/modules/customers/api/deals/[id]/companies/route.ts +1 -4
  635. package/src/modules/customers/api/deals/[id]/people/route.ts +1 -4
  636. package/src/modules/customers/api/deals/[id]/route.ts +28 -17
  637. package/src/modules/customers/api/deals/[id]/stats/route.ts +25 -10
  638. package/src/modules/customers/api/deals/aggregate/route.ts +4 -14
  639. package/src/modules/customers/api/deals/map/route.ts +0 -1
  640. package/src/modules/customers/api/deals/route.ts +1 -50
  641. package/src/modules/customers/api/entity-roles-factory.ts +4 -8
  642. package/src/modules/customers/api/interactions/route.ts +2 -8
  643. package/src/modules/customers/api/interactions/tasks/route.ts +1 -24
  644. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +4 -12
  645. package/src/modules/customers/api/people/[id]/companies/context.ts +1 -4
  646. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +1 -4
  647. package/src/modules/customers/api/people/[id]/route.ts +11 -16
  648. package/src/modules/customers/api/people/check-phone/route.ts +10 -75
  649. package/src/modules/customers/api/todos/route.ts +2 -27
  650. package/src/modules/customers/backend/customers/companies/page.tsx +4 -7
  651. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +2 -7
  652. package/src/modules/customers/backend/customers/deals/page.tsx +4 -10
  653. package/src/modules/customers/backend/customers/deals/pipeline/components/Lane.tsx +14 -5
  654. package/src/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.tsx +27 -109
  655. package/src/modules/customers/backend/customers/people/page.tsx +4 -7
  656. package/src/modules/customers/backend/hooks/useEmailDuplicateCheck.ts +4 -12
  657. package/src/modules/customers/commands/deals.ts +59 -34
  658. package/src/modules/customers/commands/interactions.ts +1 -1
  659. package/src/modules/customers/commands/personCompanyLinks.ts +8 -224
  660. package/src/modules/customers/components/CustomerTodosTable.tsx +0 -2
  661. package/src/modules/customers/components/DealsKpiStrip.tsx +7 -7
  662. package/src/modules/customers/components/calendar/AgendaList.tsx +3 -3
  663. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -1
  664. package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
  665. package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +1 -1
  666. package/src/modules/customers/components/calendar/EventBlock.tsx +2 -2
  667. package/src/modules/customers/components/calendar/EventPeekPopover.tsx +2 -4
  668. package/src/modules/customers/components/calendar/editor/PeopleField.tsx +5 -61
  669. package/src/modules/customers/components/calendar/editor/hooks.ts +1 -7
  670. package/src/modules/customers/components/calendar/types.ts +2 -2
  671. package/src/modules/customers/components/detail/AssignRoleDialog.tsx +12 -7
  672. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +4 -5
  673. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +1 -8
  674. package/src/modules/customers/components/detail/DealForm.tsx +2 -22
  675. package/src/modules/customers/components/detail/DealsSection.tsx +5 -11
  676. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +12 -58
  677. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +1 -8
  678. package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +14 -23
  679. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +5 -5
  680. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +5 -5
  681. package/src/modules/customers/components/detail/types.ts +1 -1
  682. package/src/modules/customers/components/detail/utils.ts +5 -15
  683. package/src/modules/customers/data/entities.ts +1 -1
  684. package/src/modules/customers/data/validators.ts +9 -50
  685. package/src/modules/customers/events.ts +0 -5
  686. package/src/modules/customers/i18n/de.json +1 -9
  687. package/src/modules/customers/i18n/en.json +1 -9
  688. package/src/modules/customers/i18n/es.json +1 -9
  689. package/src/modules/customers/i18n/ko.json +1 -9
  690. package/src/modules/customers/i18n/pl.json +1 -9
  691. package/src/modules/customers/lib/calendar/conflicts.ts +2 -10
  692. package/src/modules/customers/lib/calendar/editorPayload.ts +3 -4
  693. package/src/modules/customers/lib/calendar/mapItem.ts +3 -8
  694. package/src/modules/customers/lib/dealStatus.ts +0 -42
  695. package/src/modules/customers/lib/findPeopleByAddresses.ts +6 -8
  696. package/src/modules/customers/lib/personCompanies.ts +1 -136
  697. package/src/modules/customers/lib/todoCompatibility.ts +1 -19
  698. package/src/modules/dashboards/i18n/es.json +4 -4
  699. package/src/modules/dashboards/i18n/pl.json +7 -7
  700. package/src/modules/dashboards/lib/widgetScope.ts +0 -6
  701. package/src/modules/data_sync/AGENTS.md +1 -1
  702. package/src/modules/data_sync/backend/data-sync/page.tsx +1 -4
  703. package/src/modules/data_sync/lib/adapter.ts +0 -36
  704. package/src/modules/data_sync/lib/sync-engine.ts +5 -113
  705. package/src/modules/data_sync/workers/sync-export.ts +0 -4
  706. package/src/modules/data_sync/workers/sync-import.ts +0 -4
  707. package/src/modules/devices/AGENTS.md +0 -8
  708. package/src/modules/devices/api/admin/devices/[id]/route.ts +34 -5
  709. package/src/modules/devices/api/admin/devices/route.ts +1 -14
  710. package/src/modules/devices/api/deviceList.ts +11 -135
  711. package/src/modules/devices/api/openapi.ts +1 -9
  712. package/src/modules/devices/api/route.ts +1 -9
  713. package/src/modules/devices/backend/devices/[id]/page.tsx +15 -15
  714. package/src/modules/devices/backend/devices/page.tsx +21 -24
  715. package/src/modules/directory/backend/directory/organizations/page.tsx +1 -3
  716. package/src/modules/directory/backend/directory/tenants/page.tsx +1 -3
  717. package/src/modules/directory/di.ts +2 -14
  718. package/src/modules/directory/utils/organizationScope.ts +15 -4
  719. package/src/modules/entities/api/records.ts +0 -2
  720. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +1 -4
  721. package/src/modules/eudr/api/plots/route.ts +0 -4
  722. package/src/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.ts +2 -0
  723. package/src/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.ts +1 -0
  724. package/src/modules/eudr/backend/eudr/evidence-submissions/page.meta.ts +4 -1
  725. package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +0 -4
  726. package/src/modules/eudr/backend/eudr/page.meta.ts +2 -2
  727. package/src/modules/eudr/backend/eudr/plots/[id]/page.meta.ts +2 -0
  728. package/src/modules/eudr/backend/eudr/plots/[id]/page.tsx +8 -2
  729. package/src/modules/eudr/backend/eudr/plots/create/page.meta.ts +1 -0
  730. package/src/modules/eudr/backend/eudr/plots/create/page.tsx +8 -2
  731. package/src/modules/eudr/backend/eudr/plots/page.meta.ts +4 -1
  732. package/src/modules/eudr/backend/eudr/plots/page.tsx +0 -4
  733. package/src/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.ts +2 -0
  734. package/src/modules/eudr/backend/eudr/product-mappings/create/page.meta.ts +1 -0
  735. package/src/modules/eudr/backend/eudr/product-mappings/page.meta.ts +4 -1
  736. package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +0 -4
  737. package/src/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.ts +2 -0
  738. package/src/modules/eudr/backend/eudr/risk-assessments/create/page.meta.ts +1 -0
  739. package/src/modules/eudr/backend/eudr/risk-assessments/page.meta.ts +4 -1
  740. package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +0 -4
  741. package/src/modules/eudr/backend/eudr/statements/[id]/page.meta.ts +2 -0
  742. package/src/modules/eudr/backend/eudr/statements/[id]/page.tsx +2 -0
  743. package/src/modules/eudr/backend/eudr/statements/create/page.meta.ts +1 -0
  744. package/src/modules/eudr/backend/eudr/statements/page.meta.ts +4 -1
  745. package/src/modules/eudr/backend/eudr/statements/page.tsx +32 -30
  746. package/src/modules/eudr/commands/statements.ts +7 -2
  747. package/src/modules/eudr/components/crudErrorI18n.ts +31 -0
  748. package/src/modules/eudr/components/formConfig.tsx +9 -1
  749. package/src/modules/eudr/data/validators.ts +1 -16
  750. package/src/modules/eudr/i18n/de.json +3 -2
  751. package/src/modules/eudr/i18n/en.json +3 -2
  752. package/src/modules/eudr/i18n/es.json +3 -2
  753. package/src/modules/eudr/i18n/ko.json +3 -2
  754. package/src/modules/eudr/i18n/pl.json +3 -2
  755. package/src/modules/eudr/lib/statement-lifecycle.ts +8 -0
  756. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +1 -2
  757. package/src/modules/feature_toggles/components/OverridesTable.tsx +1 -2
  758. package/src/modules/feature_toggles/defaults.json +8 -0
  759. package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +0 -4
  760. package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +0 -4
  761. package/src/modules/inbox_ops/lib/htmlToPlainText.ts +17 -1
  762. package/src/modules/integrations/api/[id]/credentials/route.ts +4 -6
  763. package/src/modules/integrations/backend/integrations/[id]/page.tsx +31 -61
  764. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +9 -44
  765. package/src/modules/integrations/data/validators.ts +2 -12
  766. package/src/modules/integrations/i18n/de.json +0 -1
  767. package/src/modules/integrations/i18n/en.json +0 -1
  768. package/src/modules/integrations/i18n/es.json +0 -1
  769. package/src/modules/integrations/i18n/ko.json +0 -1
  770. package/src/modules/integrations/i18n/pl.json +0 -1
  771. package/src/modules/integrations/lib/credentials-masking.ts +6 -10
  772. package/src/modules/messages/api/[id]/route.ts +1 -55
  773. package/src/modules/messages/api/openapi.ts +0 -20
  774. package/src/modules/messages/api/route.ts +2 -31
  775. package/src/modules/messages/components/MessagesInboxPageClient.tsx +16 -9
  776. package/src/modules/messages/components/inboxFilters.ts +0 -36
  777. package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +1 -14
  778. package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +1 -3
  779. package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +1 -2
  780. package/src/modules/messages/components/message-detail/types.ts +0 -3
  781. package/src/modules/messages/components/messageListLabels.ts +3 -52
  782. package/src/modules/messages/data/validators.ts +4 -43
  783. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +6 -4
  784. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +1 -4
  785. package/src/modules/payment_gateways/lib/webhook-processor.ts +0 -11
  786. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +0 -4
  787. package/src/modules/push_notifications/backend/push_notifications/page.tsx +1 -4
  788. package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +4 -4
  789. package/src/modules/query_index/lib/engine.ts +61 -249
  790. package/src/modules/query_index/lib/search-tokens.ts +3 -135
  791. package/src/modules/resources/backend/resources/resource-types/page.tsx +1 -4
  792. package/src/modules/resources/backend/resources/resources/page.tsx +1 -4
  793. package/src/modules/sales/backend/sales/channels/offers/page.tsx +0 -4
  794. package/src/modules/sales/backend/sales/channels/page.tsx +0 -4
  795. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +8 -14
  796. package/src/modules/sales/commands/documents.ts +0 -93
  797. package/src/modules/sales/components/PriceWithCurrency.tsx +5 -17
  798. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +0 -4
  799. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +5 -6
  800. package/src/modules/sales/components/documents/ItemsSection.tsx +18 -56
  801. package/src/modules/sales/components/documents/LineItemDialog.tsx +21 -138
  802. package/src/modules/sales/components/documents/PaymentsSection.tsx +9 -20
  803. package/src/modules/sales/components/documents/ReturnsSection.tsx +5 -6
  804. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +14 -106
  805. package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +5 -6
  806. package/src/modules/sales/components/documents/ShipmentDialog.tsx +4 -5
  807. package/src/modules/sales/components/documents/ShipmentsSection.tsx +5 -6
  808. package/src/modules/sales/components/documents/lineItemUtils.ts +2 -7
  809. package/src/modules/sales/data/entities.ts +0 -6
  810. package/src/modules/sales/extension-points.ts +0 -1
  811. package/src/modules/sales/i18n/de.json +37 -8
  812. package/src/modules/sales/i18n/en.json +37 -8
  813. package/src/modules/sales/i18n/es.json +37 -8
  814. package/src/modules/sales/i18n/ko.json +37 -8
  815. package/src/modules/sales/i18n/pl.json +37 -8
  816. package/src/modules/sales/migrations/.snapshot-open-mercato.json +0 -60
  817. package/src/modules/sales/setup.ts +0 -2
  818. package/src/modules/sales/widgets/injection/document-history/widget.client.tsx +42 -2
  819. package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +1 -9
  820. package/src/modules/sales/widgets/injection-table.ts +7 -4
  821. package/src/modules/staff/backend/staff/leave-requests/page.tsx +0 -4
  822. package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +0 -4
  823. package/src/modules/staff/backend/staff/team-members/page.tsx +0 -6
  824. package/src/modules/staff/backend/staff/team-roles/page.tsx +0 -4
  825. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +0 -4
  826. package/src/modules/staff/backend/staff/teams/page.tsx +0 -4
  827. package/src/modules/staff/backend/staff/timesheets/page.tsx +1 -12
  828. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +0 -4
  829. package/src/modules/sync_excel/lib/adapters/customers.ts +0 -5
  830. package/src/modules/warranty_claims/api/assignees/route.ts +3 -3
  831. package/src/modules/warranty_claims/api/portal/attachments/route.ts +2 -2
  832. package/src/modules/warranty_claims/api/portal/claims/route.ts +9 -12
  833. package/src/modules/warranty_claims/backend/page.tsx +0 -4
  834. package/src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx +0 -4
  835. package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx +0 -4
  836. package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx +0 -4
  837. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +0 -4
  838. package/src/modules/wms/api/warehouses/route.ts +9 -13
  839. package/src/modules/wms/api/zones/route.ts +0 -16
  840. package/src/modules/wms/commands/configuration.ts +10 -159
  841. package/src/modules/wms/commands/inventory-actions.ts +0 -3
  842. package/src/modules/wms/commands/shared.ts +0 -17
  843. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +141 -95
  844. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +0 -2
  845. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +30 -26
  846. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +21 -17
  847. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +0 -2
  848. package/src/modules/wms/components/backend/WmsOperationalDashboardPage.tsx +17 -13
  849. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +16 -12
  850. package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +20 -36
  851. package/src/modules/wms/i18n/de.json +0 -2
  852. package/src/modules/wms/i18n/en.json +0 -2
  853. package/src/modules/wms/i18n/es.json +0 -2
  854. package/src/modules/wms/i18n/ko.json +0 -2
  855. package/src/modules/wms/i18n/pl.json +0 -2
  856. package/src/modules/workflows/backend/definitions/page.tsx +1 -4
  857. package/src/modules/workflows/backend/events/page.tsx +1 -4
  858. package/src/modules/workflows/backend/instances/page.tsx +1 -4
  859. package/src/modules/workflows/backend/tasks/page.tsx +1 -4
  860. package/src/modules/workflows/lib/activity-executor.ts +0 -9
  861. package/dist/modules/api_keys/di.js +0 -9
  862. package/dist/modules/api_keys/di.js.map +0 -7
  863. package/dist/modules/api_keys/services/principalService.js +0 -31
  864. package/dist/modules/api_keys/services/principalService.js.map +0 -7
  865. package/dist/modules/attachments/lib/attachment-service.js +0 -313
  866. package/dist/modules/attachments/lib/attachment-service.js.map +0 -7
  867. package/dist/modules/auth/api/reset/validate.js +0 -55
  868. package/dist/modules/auth/api/reset/validate.js.map +0 -7
  869. package/dist/modules/auth/commands/acl.js +0 -254
  870. package/dist/modules/auth/commands/acl.js.map +0 -7
  871. package/dist/modules/auth/services/principalService.js +0 -200
  872. package/dist/modules/auth/services/principalService.js.map +0 -7
  873. package/dist/modules/auth/services/roleOrganizationScope.js +0 -41
  874. package/dist/modules/auth/services/roleOrganizationScope.js.map +0 -7
  875. package/dist/modules/communication_channels/lib/outbound-recipient.js +0 -33
  876. package/dist/modules/communication_channels/lib/outbound-recipient.js.map +0 -7
  877. package/dist/modules/communication_channels/lib/resolve-channel-type.js +0 -51
  878. package/dist/modules/communication_channels/lib/resolve-channel-type.js.map +0 -7
  879. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js +0 -18
  880. package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js.map +0 -7
  881. package/dist/modules/customers/lib/calendar/participantIdentity.js +0 -9
  882. package/dist/modules/customers/lib/calendar/participantIdentity.js.map +0 -7
  883. package/dist/modules/customers/lib/closureStage.js +0 -45
  884. package/dist/modules/customers/lib/closureStage.js.map +0 -7
  885. package/dist/modules/customers/lib/detailReadAccess.js +0 -12
  886. package/dist/modules/customers/lib/detailReadAccess.js.map +0 -7
  887. package/dist/modules/data_sync/lib/abandoned-run.js +0 -19
  888. package/dist/modules/data_sync/lib/abandoned-run.js.map +0 -7
  889. package/dist/modules/devices/api/deviceSerialization.js +0 -46
  890. package/dist/modules/devices/api/deviceSerialization.js.map +0 -7
  891. package/dist/modules/directory/services/organizationHierarchyService.js +0 -29
  892. package/dist/modules/directory/services/organizationHierarchyService.js.map +0 -7
  893. package/dist/modules/directory/services/organizationScopeService.js +0 -56
  894. package/dist/modules/directory/services/organizationScopeService.js.map +0 -7
  895. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js +0 -55
  896. package/dist/modules/integrations/backend/integrations/credential-secret-fields.js.map +0 -7
  897. package/dist/modules/messages/lib/channel-sender-identity.js +0 -26
  898. package/dist/modules/messages/lib/channel-sender-identity.js.map +0 -7
  899. package/dist/modules/messages/lib/composeSourceChannelType.js +0 -41
  900. package/dist/modules/messages/lib/composeSourceChannelType.js.map +0 -7
  901. package/dist/modules/query_index/lib/search-entity-policy.js +0 -14
  902. package/dist/modules/query_index/lib/search-entity-policy.js.map +0 -7
  903. package/dist/modules/sales/components/documents/lineItemShipmentLock.js +0 -54
  904. package/dist/modules/sales/components/documents/lineItemShipmentLock.js.map +0 -7
  905. package/dist/modules/sales/lib/salesChannelsToggleSeed.js +0 -33
  906. package/dist/modules/sales/lib/salesChannelsToggleSeed.js.map +0 -7
  907. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js +0 -32
  908. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js.map +0 -7
  909. package/dist/modules/wms/api/warehouseSearch.js +0 -21
  910. package/dist/modules/wms/api/warehouseSearch.js.map +0 -7
  911. package/dist/modules/wms/components/backend/WarehouseEditDialog.js +0 -158
  912. package/dist/modules/wms/components/backend/WarehouseEditDialog.js.map +0 -7
  913. package/dist/modules/wms/components/backend/warehouseFormOptions.js +0 -66
  914. package/dist/modules/wms/components/backend/warehouseFormOptions.js.map +0 -7
  915. package/src/modules/api_keys/di.ts +0 -7
  916. package/src/modules/api_keys/services/principalService.ts +0 -33
  917. package/src/modules/attachments/lib/attachment-service.ts +0 -468
  918. package/src/modules/auth/api/reset/validate.ts +0 -57
  919. package/src/modules/auth/commands/acl.ts +0 -495
  920. package/src/modules/auth/services/principalService.ts +0 -266
  921. package/src/modules/auth/services/roleOrganizationScope.ts +0 -70
  922. package/src/modules/communication_channels/lib/outbound-recipient.ts +0 -71
  923. package/src/modules/communication_channels/lib/resolve-channel-type.ts +0 -99
  924. package/src/modules/customers/backend/customers/deals/pipeline/components/toneClasses.ts +0 -21
  925. package/src/modules/customers/lib/calendar/participantIdentity.ts +0 -17
  926. package/src/modules/customers/lib/closureStage.ts +0 -76
  927. package/src/modules/customers/lib/detailReadAccess.ts +0 -35
  928. package/src/modules/data_sync/lib/abandoned-run.ts +0 -56
  929. package/src/modules/devices/api/deviceSerialization.ts +0 -50
  930. package/src/modules/directory/services/organizationHierarchyService.ts +0 -34
  931. package/src/modules/directory/services/organizationScopeService.ts +0 -85
  932. package/src/modules/integrations/backend/integrations/credential-secret-fields.ts +0 -84
  933. package/src/modules/messages/lib/channel-sender-identity.ts +0 -55
  934. package/src/modules/messages/lib/composeSourceChannelType.ts +0 -95
  935. package/src/modules/query_index/lib/search-entity-policy.ts +0 -46
  936. package/src/modules/sales/components/documents/lineItemShipmentLock.ts +0 -74
  937. package/src/modules/sales/lib/salesChannelsToggleSeed.ts +0 -42
  938. package/src/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.ts +0 -87
  939. package/src/modules/wms/api/warehouseSearch.ts +0 -23
  940. package/src/modules/wms/components/backend/WarehouseEditDialog.tsx +0 -216
  941. package/src/modules/wms/components/backend/warehouseFormOptions.ts +0 -72
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/data_sync/lib/sync-engine.ts"],
4
- "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { CredentialsService } from '../../integrations/lib/credentials-service'\nimport type { IntegrationLogService } from '../../integrations/lib/log-service'\nimport type { IntegrationStateService } from '../../integrations/lib/state-service'\nimport type { ProgressService } from '../../progress/lib/progressService'\nimport { STALE_JOB_TIMEOUT_SECONDS } from '../../progress/lib/progressService'\nimport { refreshCoverageSnapshot } from '../../query_index/lib/coverage'\nimport { emitDataSyncEvent } from '../events'\nimport type { DataSyncAdapter, DataMapping, ExportBatch, ImportBatch, RunParameterValue } from './adapter'\nimport { getDataSyncAdapter, resolveProviderKey } from './adapter-registry'\nimport type { SyncRunService } from './sync-run-service'\nimport { SyncRunOwnershipConflictError } from './sync-run-service'\nimport { forEachBatch } from './batch-stream'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport {\n captureTelemetryTrace,\n type TelemetrySpanAttributes,\n} from '@open-mercato/shared/lib/telemetry/runtime'\nimport type { SyncRun } from '../data/entities'\n\nconst logger = createLogger('data_sync').child({ component: 'sync-engine' })\n\ntype RunParameters = Record<string, RunParameterValue>\n\ntype SyncScope = {\n organizationId: string\n tenantId: string\n userId?: string | null\n}\n\ntype EngineDeps = {\n em: EntityManager\n syncRunService: SyncRunService\n integrationCredentialsService: CredentialsService\n integrationLogService: IntegrationLogService\n integrationStateService?: IntegrationStateService\n progressService: ProgressService\n}\n\n/** Repeated on every batch span so a rooted batch trace identifies its run on its own. */\nfunction runSpanAttributes(run: SyncRun, providerKey: string, scope: SyncScope): TelemetrySpanAttributes {\n return {\n 'data_sync.run_id': run.id,\n 'data_sync.integration_id': run.integrationId,\n 'data_sync.provider_key': providerKey,\n 'data_sync.entity_type': run.entityType,\n 'data_sync.direction': run.direction,\n 'om.tenant_id': scope.tenantId,\n 'om.organization_id': scope.organizationId,\n }\n}\n\nfunction applyImportCounters(batch: ImportBatch): Pick<Required<SyncCounterDelta>, 'createdCount' | 'updatedCount' | 'skippedCount' | 'failedCount'> {\n let createdCount = 0\n let updatedCount = 0\n let skippedCount = 0\n let failedCount = 0\n\n for (const item of batch.items) {\n if (item.action === 'create') createdCount += 1\n else if (item.action === 'update') updatedCount += 1\n else if (item.action === 'failed') failedCount += 1\n else skippedCount += 1\n }\n\n return { createdCount, updatedCount, skippedCount, failedCount }\n}\n\ntype SyncCounterDelta = {\n createdCount?: number\n updatedCount?: number\n skippedCount?: number\n failedCount?: number\n processedCount: number\n}\n\nfunction applyExportCounters(batch: ExportBatch): SyncCounterDelta {\n let failedCount = 0\n let skippedCount = 0\n let updatedCount = 0\n\n for (const result of batch.results) {\n if (result.status === 'error') failedCount += 1\n else if (result.status === 'skipped') skippedCount += 1\n else updatedCount += 1\n }\n\n return {\n failedCount,\n skippedCount,\n updatedCount,\n processedCount: batch.results.length,\n }\n}\n\n// Adapter batches can legitimately outlast the stale-job sweep window (slow upstream\n// APIs), so the engine must heartbeat while a batch is still being produced. The same\n// tick also polls cancellation, so a cancel lands within one interval instead of waiting\n// out the batch \u2014 sharing this timer rather than adding a second one that would double\n// the per-interval round-trips for the whole life of a run.\nconst HEARTBEAT_TICK_MS = (STALE_JOB_TIMEOUT_SECONDS * 1000) / 4\n\n// Runs `tick` on an interval only while the source iterator is pending, so heartbeats\n// stop the moment the producer dies and genuinely stale jobs still get swept. The outer\n// finally closes the adapter generator on early exits (cancellation, ownership conflict).\n// Our own abort, as opposed to a failure that merely coincided with one. Adapters are told to\n// return rather than throw, but `signal.throwIfAborted()` and an aborted `fetch` both surface as\n// this, and either is a cancellation rather than a fault.\n//\n// Matched structurally on `name` rather than with `instanceof Error`, because those two throw a\n// `DOMException`, and whether that inherits from `Error` depends on the runtime \u2014 it does under\n// bare Node 24 and does NOT under the jest environment this is tested in. An `instanceof` test\n// therefore passes or fails on where the code runs, which is not something cancellation should\n// depend on.\nfunction isAbortError(error: unknown): boolean {\n return typeof error === 'object' && error !== null && (error as { name?: unknown }).name === 'AbortError'\n}\n\nasync function* withHeartbeat<T>(source: AsyncIterable<T>, tick: () => void, intervalMs: number): AsyncGenerator<T, void, undefined> {\n const iterator = source[Symbol.asyncIterator]()\n try {\n while (true) {\n const timer = setInterval(tick, intervalMs)\n let result: IteratorResult<T>\n try {\n result = await iterator.next()\n } finally {\n clearInterval(timer)\n }\n if (result.done) return\n yield result.value\n }\n } finally {\n await iterator.return?.()\n }\n}\n\nexport function createSyncEngine(deps: EngineDeps) {\n const { syncRunService, integrationCredentialsService, integrationLogService, integrationStateService, progressService } = deps\n\n async function resolveMapping(adapter: DataSyncAdapter, entityType: string, scope: SyncScope): Promise<DataMapping> {\n return adapter.getMapping({\n entityType,\n scope: { organizationId: scope.organizationId, tenantId: scope.tenantId },\n })\n }\n\n async function updateProgress(progressJobId: string | null | undefined, processedCount: number, totalCount: number | null, scope: SyncScope): Promise<void> {\n if (!progressJobId) return\n\n await progressService.updateProgress(\n progressJobId,\n {\n processedCount,\n totalCount: totalCount ?? undefined,\n },\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n )\n }\n\n // On redelivery the progress counter must resume where the last delivery left off the\n // same way committedBatches does \u2014 updateProgress writes absolute counts, so starting at\n // zero would regress the visible count. The progress job's own processedCount is the only\n // persisted value already in the engine's unit: `batch.processedCount ?? items.length`,\n // i.e. source records. The run's created/updated/skipped/failed counters count emitted\n // items, which adapters may explode several-per-source-record (Akeneo yields a product\n // plus its variants), so seeding from them would overshoot the total and pin the bar.\n async function seedProcessedCount(progressJobId: string | null | undefined, scope: SyncScope): Promise<number> {\n if (!progressJobId) return 0\n const job = await progressService.getJob(progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n return job?.processedCount ?? 0\n }\n\n function makeHeartbeatTick(progressJobId: string | null | undefined, scope: SyncScope): () => void {\n const touchJobHeartbeat = progressService.touchJobHeartbeat?.bind(progressService)\n if (!progressJobId || !touchJobHeartbeat) return () => {}\n let inFlight = false\n return () => {\n if (inFlight) return\n inFlight = true\n touchJobHeartbeat(progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n .catch((error) => {\n logger.warn('Progress heartbeat failed', {\n progressJobId,\n error: error instanceof Error ? error.message : String(error),\n })\n })\n .finally(() => {\n inFlight = false\n })\n }\n }\n\n // Rides the heartbeat timer, which is the only thing that runs while the adapter is still\n // producing a batch \u2014 the engine's own cancellation check sits in the batch handler and is\n // reached only after a yield. Swallows its own errors because it runs on a timer, where an\n // unhandled rejection is fatal, and stops polling once it has aborted.\n function makeCancellationTick(progressJobId: string | null | undefined, scope: SyncScope, controller: AbortController): () => void {\n if (!progressJobId) return () => {}\n let inFlight = false\n return () => {\n if (inFlight || controller.signal.aborted) return\n inFlight = true\n progressService.isCancellationRequested(progressJobId, scope.tenantId, scope.organizationId)\n .then((cancelled) => {\n if (cancelled) controller.abort()\n })\n .catch((error) => {\n logger.warn('Cancellation poll failed', {\n progressJobId,\n error: error instanceof Error ? error.message : String(error),\n })\n })\n .finally(() => {\n inFlight = false\n })\n }\n }\n\n async function refreshCoverageSnapshots(entityTypes: string[] | undefined, scope: SyncScope): Promise<void> {\n if (!entityTypes || entityTypes.length === 0) return\n\n await Promise.allSettled(\n Array.from(new Set(entityTypes.filter((value) => typeof value === 'string' && value.trim().length > 0)))\n .map((entityType) => refreshCoverageSnapshot(deps.em, {\n entityType,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })),\n )\n }\n\n async function logImportItemFailures(\n runId: string,\n integrationId: string,\n items: ImportBatch['items'],\n scope: SyncScope,\n ): Promise<void> {\n const failedItems = items.filter((item) => item.action === 'failed')\n for (const item of failedItems) {\n const errorMessage = typeof item.data.errorMessage === 'string' && item.data.errorMessage.trim().length > 0\n ? item.data.errorMessage.trim()\n : 'Import item failed'\n const sourceProductUuid = typeof item.data.sourceProductUuid === 'string' && item.data.sourceProductUuid.trim().length > 0\n ? item.data.sourceProductUuid.trim()\n : null\n const sourceIdentifier = typeof item.data.sourceIdentifier === 'string' && item.data.sourceIdentifier.trim().length > 0\n ? item.data.sourceIdentifier.trim()\n : null\n const message = [\n `Failed to import item ${item.externalId}`,\n sourceProductUuid ? `(uuid: ${sourceProductUuid})` : null,\n sourceIdentifier ? `(identifier: ${sourceIdentifier})` : null,\n `: ${errorMessage}`,\n ].filter((part) => part !== null).join(' ')\n\n await integrationLogService.write(\n {\n integrationId,\n runId,\n level: 'error',\n message,\n payload: item.data,\n },\n scope,\n )\n }\n }\n\n async function logExportItemFailures(\n runId: string,\n integrationId: string,\n results: ExportBatch['results'],\n scope: SyncScope,\n ): Promise<void> {\n const failedResults = results.filter((result) => result.status === 'error' && result.error)\n for (const result of failedResults) {\n const label = result.externalId ? `${result.externalId} (id: ${result.localId})` : result.localId\n const errorMessage = result.error!.split('\\n')[0]\n const message = `Failed to export item ${label}: ${errorMessage}`\n\n await integrationLogService.write(\n {\n integrationId,\n runId,\n level: 'error',\n message,\n payload: { kind: 'export-item-failure', summary: result.error },\n },\n scope,\n )\n }\n }\n\n async function writeOperationalLog(params: {\n integrationId: string\n runId: string\n level: 'info' | 'warn' | 'error'\n message: string\n scope: SyncScope\n enabled: boolean\n payload?: Record<string, unknown>\n }): Promise<void> {\n if (!params.enabled) return\n\n await integrationLogService.write(\n {\n integrationId: params.integrationId,\n runId: params.runId,\n level: params.level,\n message: params.message,\n payload: params.payload,\n },\n params.scope,\n )\n }\n\n async function updateOperationalState(params: {\n integrationId: string\n status: 'healthy' | 'degraded' | 'unhealthy'\n scope: SyncScope\n enabled: boolean\n }): Promise<void> {\n if (!params.enabled || !integrationStateService) return\n\n await integrationStateService.upsert(\n params.integrationId,\n {\n lastHealthStatus: params.status,\n lastHealthCheckedAt: new Date(),\n },\n params.scope,\n )\n }\n\n async function finalizeRun(\n runId: string,\n status: 'completed' | 'failed' | 'cancelled',\n scope: SyncScope,\n error?: string,\n operationalTelemetry = false,\n ): Promise<void> {\n const existingRun = await syncRunService.getRun(runId, scope)\n const alreadyFinalizedWithSameStatus = existingRun?.status === status\n && (status === 'completed' || status === 'failed' || status === 'cancelled')\n\n const run = await syncRunService.markStatus(runId, status, scope, error)\n if (!run) return\n\n if (alreadyFinalizedWithSameStatus) {\n return\n }\n\n if (run.status !== status) {\n // `markStatus` refuses a terminal -> different-terminal transition and\n // returns the row unchanged, so the run is already finished under another\n // delivery of this job. Everything below \u2014 the progress job, the\n // operational log and the lifecycle event \u2014 would describe the wrong\n // outcome, and `data_sync.run.failed` is dispatched to tenant webhooks.\n // A displaced worker stays silent instead.\n logger.warn('Skipping finalization of a sync run another worker already finalized', {\n runId,\n requestedStatus: status,\n actualStatus: run.status,\n })\n return\n }\n\n if (run.progressJobId) {\n if (status === 'completed') {\n await progressService.completeJob(\n run.progressJobId,\n {\n resultSummary: {\n createdCount: run.createdCount,\n updatedCount: run.updatedCount,\n skippedCount: run.skippedCount,\n failedCount: run.failedCount,\n batchesCompleted: run.batchesCompleted,\n },\n },\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n )\n } else if (status === 'failed') {\n await progressService.failJob(\n run.progressJobId,\n {\n errorMessage: error ?? 'Sync run failed',\n },\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n )\n } else if (status === 'cancelled') {\n await progressService.markCancelled(\n run.progressJobId,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n )\n }\n }\n\n if (status === 'completed') {\n await updateOperationalState({\n integrationId: run.integrationId,\n status: 'healthy',\n scope,\n enabled: operationalTelemetry,\n })\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'info',\n message: 'Sync run completed',\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'completed',\n summary: `Sync completed with ${run.createdCount} created, ${run.updatedCount} updated, ${run.failedCount} failed.`,\n createdCount: run.createdCount,\n updatedCount: run.updatedCount,\n skippedCount: run.skippedCount,\n failedCount: run.failedCount,\n batchesCompleted: run.batchesCompleted,\n },\n })\n } else if (status === 'cancelled') {\n await updateOperationalState({\n integrationId: run.integrationId,\n status: 'degraded',\n scope,\n enabled: operationalTelemetry,\n })\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'warn',\n message: 'Sync run cancelled',\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'cancelled',\n summary: 'The sync run was cancelled before completion.',\n },\n })\n } else {\n await updateOperationalState({\n integrationId: run.integrationId,\n status: 'unhealthy',\n scope,\n enabled: operationalTelemetry,\n })\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'error',\n message: error ?? 'Sync run failed',\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'failed',\n summary: error ?? 'The sync run failed.',\n },\n })\n }\n\n if (status === 'completed') {\n await emitDataSyncEvent('data_sync.run.completed', {\n runId,\n integrationId: run.integrationId,\n entityType: run.entityType,\n direction: run.direction,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n return\n }\n\n if (status === 'cancelled') {\n await emitDataSyncEvent('data_sync.run.cancelled', {\n runId,\n integrationId: run.integrationId,\n entityType: run.entityType,\n direction: run.direction,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n return\n }\n\n await emitDataSyncEvent('data_sync.run.failed', {\n runId,\n integrationId: run.integrationId,\n entityType: run.entityType,\n direction: run.direction,\n error: error ?? null,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n }\n\n return {\n async runImport(runId: string, batchSize: number, scope: SyncScope): Promise<void> {\n const run = await syncRunService.getRun(runId, scope)\n if (!run) {\n logger.warn('Skipping stale import job for missing run', { runId })\n return\n }\n if (run.status === 'cancelled') {\n if (run.progressJobId) {\n await progressService.markCancelled(run.progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n }\n return\n }\n\n const providerKey = resolveProviderKey(run.integrationId)\n const adapter = getDataSyncAdapter(providerKey)\n if (!adapter?.streamImport) {\n throw new Error(`No import adapter registered for provider ${providerKey}`)\n }\n const operationalTelemetry = adapter.operationalTelemetry === true\n const persistSharedCursor = adapter.persistsSharedCursor?.(run.entityType) ?? true\n\n const credentials = await integrationCredentialsService.resolve(run.integrationId, scope)\n if (!credentials) {\n throw new Error(`Integration ${run.integrationId} is missing credentials`)\n }\n\n // A run already `running` means a stalled job was redelivered, so this is\n // a resume rather than a first start. Consumers see one `started` event per\n // delivery either way; the flag is what lets them tell the two apart.\n const resumed = run.status === 'running'\n const activeRun = await syncRunService.markStatus(run.id, 'running', scope)\n if (!activeRun || activeRun.status !== 'running') {\n return\n }\n await emitDataSyncEvent('data_sync.run.started', {\n runId: run.id,\n integrationId: run.integrationId,\n entityType: run.entityType,\n direction: run.direction,\n resumed,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n await updateOperationalState({\n integrationId: run.integrationId,\n status: 'degraded',\n scope,\n enabled: operationalTelemetry,\n })\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'info',\n message: 'Sync run started',\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'running',\n summary: `Import run started for ${run.entityType}.`,\n entityType: run.entityType,\n direction: run.direction,\n },\n })\n\n if (run.progressJobId) {\n await progressService.startJob(run.progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n }\n\n const mapping = await resolveMapping(adapter, run.entityType, scope)\n let processedCount = await seedProcessedCount(run.progressJobId, scope)\n let totalCount: number | null = null\n let committedBatches = activeRun.batchesCompleted ?? 0\n // Whether the last committed batch said the source was exhausted. Distinguishes a stream that\n // drained from one the adapter stopped early \u2014 see the post-stream finalize below.\n let streamReportedDone = false\n // Captured while the triggering job's span is still the active one, so\n // every rooted batch trace can link back to it.\n const runTrace = captureTelemetryTrace()\n const spanAttributes = runSpanAttributes(run, providerKey, scope)\n // Declared outside the try because both the catch and the completion path below read it.\n const cancellation = new AbortController()\n const heartbeat = makeHeartbeatTick(run.progressJobId, scope)\n const pollCancellation = makeCancellationTick(run.progressJobId, scope, cancellation)\n\n try {\n const streamResult = await forEachBatch(\n withHeartbeat(\n adapter.streamImport({\n entityType: run.entityType,\n cursor: run.cursor ?? undefined,\n batchSize,\n credentials,\n mapping,\n scope: { organizationId: scope.organizationId, tenantId: scope.tenantId },\n runId: run.id,\n parameters: (run.parameters ?? {}) as RunParameters,\n signal: cancellation.signal,\n }),\n // `finally` so a synchronous throw from the heartbeat cannot also stop cancellation\n // from being observed for the rest of the run.\n () => { try { heartbeat() } finally { pollCancellation() } },\n HEARTBEAT_TICK_MS,\n ),\n {\n spanName: 'data_sync.import.batch',\n drainSpanName: 'data_sync.import.drain',\n attributes: spanAttributes,\n linkTo: runTrace,\n },\n async (batch, span) => {\n span.setAttributes({\n 'data_sync.batch_index': batch.batchIndex,\n 'data_sync.batch_size': batch.items.length,\n })\n\n if (cancellation.signal.aborted || (run.progressJobId && await progressService.isCancellationRequested(run.progressJobId, scope.tenantId, scope.organizationId))) {\n await finalizeRun(run.id, 'cancelled', scope, undefined, operationalTelemetry)\n return 'stop'\n }\n\n const delta = applyImportCounters(batch)\n const processedBatchCount = batch.processedCount ?? batch.items.length\n processedCount += processedBatchCount\n totalCount = batch.totalEstimate ?? totalCount\n\n span.setAttributes({\n 'data_sync.processed_count': processedBatchCount,\n 'data_sync.created_count': delta.createdCount,\n 'data_sync.updated_count': delta.updatedCount,\n 'data_sync.skipped_count': delta.skippedCount,\n 'data_sync.failed_count': delta.failedCount,\n })\n\n await syncRunService.commitBatchProgress(\n run.id,\n {\n ...delta,\n batchesCompleted: 1,\n },\n batch.cursor,\n scope,\n { expectedBatchesCompleted: committedBatches, persistSharedCursor },\n )\n committedBatches += 1\n streamReportedDone = batch.hasMore === false\n\n await updateProgress(run.progressJobId, processedCount, totalCount, scope)\n await refreshCoverageSnapshots(batch.refreshCoverageEntityTypes, scope)\n await logImportItemFailures(run.id, run.integrationId, batch.items, scope)\n\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'info',\n message: batch.message?.trim().length\n ? batch.message.trim()\n : `Processed import batch ${batch.batchIndex}`,\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'running',\n summary: `Processed ${processedCount}${totalCount ? ` of ${totalCount}` : ''} rows so far.`,\n processedCount,\n batchSize: batch.items.length,\n processedBatchCount,\n cursor: batch.cursor,\n },\n })\n\n return 'continue'\n },\n )\n if (streamResult === 'stopped') return\n } catch (error) {\n if (error instanceof SyncRunOwnershipConflictError) {\n logger.warn('Yielding import run to a concurrent worker that already advanced it', {\n runId: run.id,\n expectedBatchesCompleted: error.expectedBatchesCompleted,\n })\n return\n }\n // An adapter that honours the signal may reject instead of returning, so our own abort is\n // a cancellation rather than a fault \u2014 and must not leave an `error` entry in the\n // integration log for a run the operator cancelled on purpose. Anything else that merely\n // coincided with the cancel \u2014 a rejecting commit, an upstream 500 \u2014 is a genuine failure\n // and keeps its log entry, its message, its `failed` status and its failed event.\n if (cancellation.signal.aborted && isAbortError(error)) {\n await finalizeRun(run.id, 'cancelled', scope, undefined, operationalTelemetry)\n return\n }\n const message = error instanceof Error ? error.message : 'Sync import failed'\n await integrationLogService.write(\n {\n integrationId: run.integrationId,\n runId: run.id,\n level: 'error',\n message,\n },\n scope,\n )\n await finalizeRun(run.id, 'failed', scope, message, operationalTelemetry)\n return\n }\n\n // An adapter that honours the signal stops mid-batch and returns WITHOUT yielding, so the\n // batch handler \u2014 which owns the only other `cancelled` transition \u2014 never runs and the\n // stream reports `completed`.\n //\n // `streamReportedDone` keeps that from swallowing a run that genuinely finished: an adapter\n // that ignores the signal and drains after reporting `hasMore: false` delivered everything it\n // had, even when the cancel landed during the final read. Calling that cancelled would tell\n // the operator a complete sync was partial and leave a finished run resumable.\n if (cancellation.signal.aborted && !streamReportedDone) {\n await finalizeRun(run.id, 'cancelled', scope, undefined, operationalTelemetry)\n return\n }\n\n await finalizeRun(run.id, 'completed', scope, undefined, operationalTelemetry)\n },\n\n async runExport(runId: string, batchSize: number, scope: SyncScope): Promise<void> {\n const run = await syncRunService.getRun(runId, scope)\n if (!run) {\n logger.warn('Skipping stale export job for missing run', { runId })\n return\n }\n if (run.status === 'cancelled') {\n if (run.progressJobId) {\n await progressService.markCancelled(run.progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n }\n return\n }\n\n const providerKey = resolveProviderKey(run.integrationId)\n const adapter = getDataSyncAdapter(providerKey)\n if (!adapter?.streamExport) {\n throw new Error(`No export adapter registered for provider ${providerKey}`)\n }\n const operationalTelemetry = adapter.operationalTelemetry === true\n const persistSharedCursor = adapter.persistsSharedCursor?.(run.entityType) ?? true\n\n const credentials = await integrationCredentialsService.resolve(run.integrationId, scope)\n if (!credentials) {\n throw new Error(`Integration ${run.integrationId} is missing credentials`)\n }\n\n // A run already `running` means a stalled job was redelivered, so this is\n // a resume rather than a first start. Consumers see one `started` event per\n // delivery either way; the flag is what lets them tell the two apart.\n const resumed = run.status === 'running'\n const activeRun = await syncRunService.markStatus(run.id, 'running', scope)\n if (!activeRun || activeRun.status !== 'running') {\n return\n }\n await emitDataSyncEvent('data_sync.run.started', {\n runId: run.id,\n integrationId: run.integrationId,\n entityType: run.entityType,\n direction: run.direction,\n resumed,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n await updateOperationalState({\n integrationId: run.integrationId,\n status: 'degraded',\n scope,\n enabled: operationalTelemetry,\n })\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'info',\n message: 'Sync run started',\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'running',\n summary: `Export run started for ${run.entityType}.`,\n entityType: run.entityType,\n direction: run.direction,\n },\n })\n\n if (run.progressJobId) {\n await progressService.startJob(run.progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n }\n\n const mapping = await resolveMapping(adapter, run.entityType, scope)\n let processedCount = await seedProcessedCount(run.progressJobId, scope)\n let committedBatches = activeRun.batchesCompleted ?? 0\n // Whether the last committed batch said the source was exhausted. Distinguishes a stream that\n // drained from one the adapter stopped early \u2014 see the post-stream finalize below.\n let streamReportedDone = false\n // Captured while the triggering job's span is still the active one, so\n // every rooted batch trace can link back to it.\n const runTrace = captureTelemetryTrace()\n const spanAttributes = runSpanAttributes(run, providerKey, scope)\n // Declared outside the try because both the catch and the completion path below read it.\n const cancellation = new AbortController()\n const heartbeat = makeHeartbeatTick(run.progressJobId, scope)\n const pollCancellation = makeCancellationTick(run.progressJobId, scope, cancellation)\n\n try {\n const streamResult = await forEachBatch(\n withHeartbeat(\n adapter.streamExport({\n entityType: run.entityType,\n cursor: run.cursor ?? undefined,\n batchSize,\n credentials,\n mapping,\n scope: { organizationId: scope.organizationId, tenantId: scope.tenantId },\n runId: run.id,\n parameters: (run.parameters ?? {}) as RunParameters,\n signal: cancellation.signal,\n }),\n // `finally` so a synchronous throw from the heartbeat cannot also stop cancellation\n // from being observed for the rest of the run.\n () => { try { heartbeat() } finally { pollCancellation() } },\n HEARTBEAT_TICK_MS,\n ),\n {\n spanName: 'data_sync.export.batch',\n drainSpanName: 'data_sync.export.drain',\n attributes: spanAttributes,\n linkTo: runTrace,\n },\n async (batch, span) => {\n span.setAttributes({\n 'data_sync.batch_index': batch.batchIndex,\n 'data_sync.batch_size': batch.results.length,\n })\n\n if (cancellation.signal.aborted || (run.progressJobId && await progressService.isCancellationRequested(run.progressJobId, scope.tenantId, scope.organizationId))) {\n await finalizeRun(run.id, 'cancelled', scope, undefined, operationalTelemetry)\n return 'stop'\n }\n\n const delta = applyExportCounters(batch)\n processedCount += delta.processedCount\n\n span.setAttributes({\n 'data_sync.processed_count': delta.processedCount,\n 'data_sync.updated_count': delta.updatedCount,\n 'data_sync.skipped_count': delta.skippedCount,\n 'data_sync.failed_count': delta.failedCount,\n })\n\n await syncRunService.commitBatchProgress(\n run.id,\n {\n createdCount: 0,\n updatedCount: delta.updatedCount,\n skippedCount: delta.skippedCount,\n failedCount: delta.failedCount,\n batchesCompleted: 1,\n },\n batch.cursor,\n scope,\n { expectedBatchesCompleted: committedBatches, persistSharedCursor },\n )\n committedBatches += 1\n streamReportedDone = batch.hasMore === false\n await updateProgress(run.progressJobId, processedCount, null, scope)\n await logExportItemFailures(run.id, run.integrationId, batch.results, scope)\n\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'info',\n message: `Processed export batch ${batch.batchIndex}`,\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'running',\n summary: `Processed ${processedCount} export items so far.`,\n processedCount,\n batchSize: batch.results.length,\n cursor: batch.cursor,\n },\n })\n\n return 'continue'\n },\n )\n if (streamResult === 'stopped') return\n } catch (error) {\n if (error instanceof SyncRunOwnershipConflictError) {\n logger.warn('Yielding export run to a concurrent worker that already advanced it', {\n runId: run.id,\n expectedBatchesCompleted: error.expectedBatchesCompleted,\n })\n return\n }\n // An adapter that honours the signal may reject instead of returning, so our own abort is\n // a cancellation rather than a fault \u2014 and must not leave an `error` entry in the\n // integration log for a run the operator cancelled on purpose. Anything else that merely\n // coincided with the cancel \u2014 a rejecting commit, an upstream 500 \u2014 is a genuine failure\n // and keeps its log entry, its message, its `failed` status and its failed event.\n if (cancellation.signal.aborted && isAbortError(error)) {\n await finalizeRun(run.id, 'cancelled', scope, undefined, operationalTelemetry)\n return\n }\n const message = error instanceof Error ? error.message : 'Sync export failed'\n await integrationLogService.write(\n {\n integrationId: run.integrationId,\n runId: run.id,\n level: 'error',\n message,\n },\n scope,\n )\n await finalizeRun(run.id, 'failed', scope, message, operationalTelemetry)\n return\n }\n\n // An adapter that honours the signal stops mid-batch and returns WITHOUT yielding, so the\n // batch handler \u2014 which owns the only other `cancelled` transition \u2014 never runs and the\n // stream reports `completed`.\n //\n // `streamReportedDone` keeps that from swallowing a run that genuinely finished: an adapter\n // that ignores the signal and drains after reporting `hasMore: false` delivered everything it\n // had, even when the cancel landed during the final read. Calling that cancelled would tell\n // the operator a complete sync was partial and leave a finished run resumable.\n if (cancellation.signal.aborted && !streamReportedDone) {\n await finalizeRun(run.id, 'cancelled', scope, undefined, operationalTelemetry)\n return\n }\n\n await finalizeRun(run.id, 'completed', scope, undefined, operationalTelemetry)\n },\n }\n}\n\nexport type SyncEngine = ReturnType<typeof createSyncEngine>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { CredentialsService } from '../../integrations/lib/credentials-service'\nimport type { IntegrationLogService } from '../../integrations/lib/log-service'\nimport type { IntegrationStateService } from '../../integrations/lib/state-service'\nimport type { ProgressService } from '../../progress/lib/progressService'\nimport { STALE_JOB_TIMEOUT_SECONDS } from '../../progress/lib/progressService'\nimport { refreshCoverageSnapshot } from '../../query_index/lib/coverage'\nimport { emitDataSyncEvent } from '../events'\nimport type { DataSyncAdapter, DataMapping, ExportBatch, ImportBatch, RunParameterValue } from './adapter'\nimport { getDataSyncAdapter, resolveProviderKey } from './adapter-registry'\nimport type { SyncRunService } from './sync-run-service'\nimport { SyncRunOwnershipConflictError } from './sync-run-service'\nimport { forEachBatch } from './batch-stream'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport {\n captureTelemetryTrace,\n type TelemetrySpanAttributes,\n} from '@open-mercato/shared/lib/telemetry/runtime'\nimport type { SyncRun } from '../data/entities'\n\nconst logger = createLogger('data_sync').child({ component: 'sync-engine' })\n\ntype RunParameters = Record<string, RunParameterValue>\n\ntype SyncScope = {\n organizationId: string\n tenantId: string\n userId?: string | null\n}\n\ntype EngineDeps = {\n em: EntityManager\n syncRunService: SyncRunService\n integrationCredentialsService: CredentialsService\n integrationLogService: IntegrationLogService\n integrationStateService?: IntegrationStateService\n progressService: ProgressService\n}\n\n/** Repeated on every batch span so a rooted batch trace identifies its run on its own. */\nfunction runSpanAttributes(run: SyncRun, providerKey: string, scope: SyncScope): TelemetrySpanAttributes {\n return {\n 'data_sync.run_id': run.id,\n 'data_sync.integration_id': run.integrationId,\n 'data_sync.provider_key': providerKey,\n 'data_sync.entity_type': run.entityType,\n 'data_sync.direction': run.direction,\n 'om.tenant_id': scope.tenantId,\n 'om.organization_id': scope.organizationId,\n }\n}\n\nfunction applyImportCounters(batch: ImportBatch): Pick<Required<SyncCounterDelta>, 'createdCount' | 'updatedCount' | 'skippedCount' | 'failedCount'> {\n let createdCount = 0\n let updatedCount = 0\n let skippedCount = 0\n let failedCount = 0\n\n for (const item of batch.items) {\n if (item.action === 'create') createdCount += 1\n else if (item.action === 'update') updatedCount += 1\n else if (item.action === 'failed') failedCount += 1\n else skippedCount += 1\n }\n\n return { createdCount, updatedCount, skippedCount, failedCount }\n}\n\ntype SyncCounterDelta = {\n createdCount?: number\n updatedCount?: number\n skippedCount?: number\n failedCount?: number\n processedCount: number\n}\n\nfunction applyExportCounters(batch: ExportBatch): SyncCounterDelta {\n let failedCount = 0\n let skippedCount = 0\n let updatedCount = 0\n\n for (const result of batch.results) {\n if (result.status === 'error') failedCount += 1\n else if (result.status === 'skipped') skippedCount += 1\n else updatedCount += 1\n }\n\n return {\n failedCount,\n skippedCount,\n updatedCount,\n processedCount: batch.results.length,\n }\n}\n\n// Adapter batches can legitimately outlast the stale-job sweep window (slow upstream\n// APIs), so the engine must heartbeat while a batch is still being produced.\nconst HEARTBEAT_TICK_MS = (STALE_JOB_TIMEOUT_SECONDS * 1000) / 4\n\n// Runs `tick` on an interval only while the source iterator is pending, so heartbeats\n// stop the moment the producer dies and genuinely stale jobs still get swept. The outer\n// finally closes the adapter generator on early exits (cancellation, ownership conflict).\nasync function* withHeartbeat<T>(source: AsyncIterable<T>, tick: () => void, intervalMs: number): AsyncGenerator<T, void, undefined> {\n const iterator = source[Symbol.asyncIterator]()\n try {\n while (true) {\n const timer = setInterval(tick, intervalMs)\n let result: IteratorResult<T>\n try {\n result = await iterator.next()\n } finally {\n clearInterval(timer)\n }\n if (result.done) return\n yield result.value\n }\n } finally {\n await iterator.return?.()\n }\n}\n\nexport function createSyncEngine(deps: EngineDeps) {\n const { syncRunService, integrationCredentialsService, integrationLogService, integrationStateService, progressService } = deps\n\n async function resolveMapping(adapter: DataSyncAdapter, entityType: string, scope: SyncScope): Promise<DataMapping> {\n return adapter.getMapping({\n entityType,\n scope: { organizationId: scope.organizationId, tenantId: scope.tenantId },\n })\n }\n\n async function updateProgress(progressJobId: string | null | undefined, processedCount: number, totalCount: number | null, scope: SyncScope): Promise<void> {\n if (!progressJobId) return\n\n await progressService.updateProgress(\n progressJobId,\n {\n processedCount,\n totalCount: totalCount ?? undefined,\n },\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n )\n }\n\n // On redelivery the progress counter must resume where the last delivery left off the\n // same way committedBatches does \u2014 updateProgress writes absolute counts, so starting at\n // zero would regress the visible count. The progress job's own processedCount is the only\n // persisted value already in the engine's unit: `batch.processedCount ?? items.length`,\n // i.e. source records. The run's created/updated/skipped/failed counters count emitted\n // items, which adapters may explode several-per-source-record (Akeneo yields a product\n // plus its variants), so seeding from them would overshoot the total and pin the bar.\n async function seedProcessedCount(progressJobId: string | null | undefined, scope: SyncScope): Promise<number> {\n if (!progressJobId) return 0\n const job = await progressService.getJob(progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n return job?.processedCount ?? 0\n }\n\n function makeHeartbeatTick(progressJobId: string | null | undefined, scope: SyncScope): () => void {\n const touchJobHeartbeat = progressService.touchJobHeartbeat?.bind(progressService)\n if (!progressJobId || !touchJobHeartbeat) return () => {}\n let inFlight = false\n return () => {\n if (inFlight) return\n inFlight = true\n touchJobHeartbeat(progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n .catch((error) => {\n logger.warn('Progress heartbeat failed', {\n progressJobId,\n error: error instanceof Error ? error.message : String(error),\n })\n })\n .finally(() => {\n inFlight = false\n })\n }\n }\n\n async function refreshCoverageSnapshots(entityTypes: string[] | undefined, scope: SyncScope): Promise<void> {\n if (!entityTypes || entityTypes.length === 0) return\n\n await Promise.allSettled(\n Array.from(new Set(entityTypes.filter((value) => typeof value === 'string' && value.trim().length > 0)))\n .map((entityType) => refreshCoverageSnapshot(deps.em, {\n entityType,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })),\n )\n }\n\n async function logImportItemFailures(\n runId: string,\n integrationId: string,\n items: ImportBatch['items'],\n scope: SyncScope,\n ): Promise<void> {\n const failedItems = items.filter((item) => item.action === 'failed')\n for (const item of failedItems) {\n const errorMessage = typeof item.data.errorMessage === 'string' && item.data.errorMessage.trim().length > 0\n ? item.data.errorMessage.trim()\n : 'Import item failed'\n const sourceProductUuid = typeof item.data.sourceProductUuid === 'string' && item.data.sourceProductUuid.trim().length > 0\n ? item.data.sourceProductUuid.trim()\n : null\n const sourceIdentifier = typeof item.data.sourceIdentifier === 'string' && item.data.sourceIdentifier.trim().length > 0\n ? item.data.sourceIdentifier.trim()\n : null\n const message = [\n `Failed to import item ${item.externalId}`,\n sourceProductUuid ? `(uuid: ${sourceProductUuid})` : null,\n sourceIdentifier ? `(identifier: ${sourceIdentifier})` : null,\n `: ${errorMessage}`,\n ].filter((part) => part !== null).join(' ')\n\n await integrationLogService.write(\n {\n integrationId,\n runId,\n level: 'error',\n message,\n payload: item.data,\n },\n scope,\n )\n }\n }\n\n async function logExportItemFailures(\n runId: string,\n integrationId: string,\n results: ExportBatch['results'],\n scope: SyncScope,\n ): Promise<void> {\n const failedResults = results.filter((result) => result.status === 'error' && result.error)\n for (const result of failedResults) {\n const label = result.externalId ? `${result.externalId} (id: ${result.localId})` : result.localId\n const errorMessage = result.error!.split('\\n')[0]\n const message = `Failed to export item ${label}: ${errorMessage}`\n\n await integrationLogService.write(\n {\n integrationId,\n runId,\n level: 'error',\n message,\n payload: { kind: 'export-item-failure', summary: result.error },\n },\n scope,\n )\n }\n }\n\n async function writeOperationalLog(params: {\n integrationId: string\n runId: string\n level: 'info' | 'warn' | 'error'\n message: string\n scope: SyncScope\n enabled: boolean\n payload?: Record<string, unknown>\n }): Promise<void> {\n if (!params.enabled) return\n\n await integrationLogService.write(\n {\n integrationId: params.integrationId,\n runId: params.runId,\n level: params.level,\n message: params.message,\n payload: params.payload,\n },\n params.scope,\n )\n }\n\n async function updateOperationalState(params: {\n integrationId: string\n status: 'healthy' | 'degraded' | 'unhealthy'\n scope: SyncScope\n enabled: boolean\n }): Promise<void> {\n if (!params.enabled || !integrationStateService) return\n\n await integrationStateService.upsert(\n params.integrationId,\n {\n lastHealthStatus: params.status,\n lastHealthCheckedAt: new Date(),\n },\n params.scope,\n )\n }\n\n async function finalizeRun(\n runId: string,\n status: 'completed' | 'failed' | 'cancelled',\n scope: SyncScope,\n error?: string,\n operationalTelemetry = false,\n ): Promise<void> {\n const existingRun = await syncRunService.getRun(runId, scope)\n const alreadyFinalizedWithSameStatus = existingRun?.status === status\n && (status === 'completed' || status === 'failed' || status === 'cancelled')\n\n const run = await syncRunService.markStatus(runId, status, scope, error)\n if (!run) return\n\n if (alreadyFinalizedWithSameStatus) {\n return\n }\n\n if (run.status !== status) {\n // `markStatus` refuses a terminal -> different-terminal transition and\n // returns the row unchanged, so the run is already finished under another\n // delivery of this job. Everything below \u2014 the progress job, the\n // operational log and the lifecycle event \u2014 would describe the wrong\n // outcome, and `data_sync.run.failed` is dispatched to tenant webhooks.\n // A displaced worker stays silent instead.\n logger.warn('Skipping finalization of a sync run another worker already finalized', {\n runId,\n requestedStatus: status,\n actualStatus: run.status,\n })\n return\n }\n\n if (run.progressJobId) {\n if (status === 'completed') {\n await progressService.completeJob(\n run.progressJobId,\n {\n resultSummary: {\n createdCount: run.createdCount,\n updatedCount: run.updatedCount,\n skippedCount: run.skippedCount,\n failedCount: run.failedCount,\n batchesCompleted: run.batchesCompleted,\n },\n },\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n )\n } else if (status === 'failed') {\n await progressService.failJob(\n run.progressJobId,\n {\n errorMessage: error ?? 'Sync run failed',\n },\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n )\n } else if (status === 'cancelled') {\n await progressService.markCancelled(\n run.progressJobId,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n },\n )\n }\n }\n\n if (status === 'completed') {\n await updateOperationalState({\n integrationId: run.integrationId,\n status: 'healthy',\n scope,\n enabled: operationalTelemetry,\n })\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'info',\n message: 'Sync run completed',\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'completed',\n summary: `Sync completed with ${run.createdCount} created, ${run.updatedCount} updated, ${run.failedCount} failed.`,\n createdCount: run.createdCount,\n updatedCount: run.updatedCount,\n skippedCount: run.skippedCount,\n failedCount: run.failedCount,\n batchesCompleted: run.batchesCompleted,\n },\n })\n } else if (status === 'cancelled') {\n await updateOperationalState({\n integrationId: run.integrationId,\n status: 'degraded',\n scope,\n enabled: operationalTelemetry,\n })\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'warn',\n message: 'Sync run cancelled',\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'cancelled',\n summary: 'The sync run was cancelled before completion.',\n },\n })\n } else {\n await updateOperationalState({\n integrationId: run.integrationId,\n status: 'unhealthy',\n scope,\n enabled: operationalTelemetry,\n })\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'error',\n message: error ?? 'Sync run failed',\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'failed',\n summary: error ?? 'The sync run failed.',\n },\n })\n }\n\n if (status === 'completed') {\n await emitDataSyncEvent('data_sync.run.completed', {\n runId,\n integrationId: run.integrationId,\n entityType: run.entityType,\n direction: run.direction,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n return\n }\n\n if (status === 'cancelled') {\n await emitDataSyncEvent('data_sync.run.cancelled', {\n runId,\n integrationId: run.integrationId,\n entityType: run.entityType,\n direction: run.direction,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n return\n }\n\n await emitDataSyncEvent('data_sync.run.failed', {\n runId,\n integrationId: run.integrationId,\n entityType: run.entityType,\n direction: run.direction,\n error: error ?? null,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n }\n\n return {\n async runImport(runId: string, batchSize: number, scope: SyncScope): Promise<void> {\n const run = await syncRunService.getRun(runId, scope)\n if (!run) {\n logger.warn('Skipping stale import job for missing run', { runId })\n return\n }\n if (run.status === 'cancelled') {\n if (run.progressJobId) {\n await progressService.markCancelled(run.progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n }\n return\n }\n\n const providerKey = resolveProviderKey(run.integrationId)\n const adapter = getDataSyncAdapter(providerKey)\n if (!adapter?.streamImport) {\n throw new Error(`No import adapter registered for provider ${providerKey}`)\n }\n const operationalTelemetry = adapter.operationalTelemetry === true\n const persistSharedCursor = adapter.persistsSharedCursor?.(run.entityType) ?? true\n\n const credentials = await integrationCredentialsService.resolve(run.integrationId, scope)\n if (!credentials) {\n throw new Error(`Integration ${run.integrationId} is missing credentials`)\n }\n\n // A run already `running` means a stalled job was redelivered, so this is\n // a resume rather than a first start. Consumers see one `started` event per\n // delivery either way; the flag is what lets them tell the two apart.\n const resumed = run.status === 'running'\n const activeRun = await syncRunService.markStatus(run.id, 'running', scope)\n if (!activeRun || activeRun.status !== 'running') {\n return\n }\n await emitDataSyncEvent('data_sync.run.started', {\n runId: run.id,\n integrationId: run.integrationId,\n entityType: run.entityType,\n direction: run.direction,\n resumed,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n await updateOperationalState({\n integrationId: run.integrationId,\n status: 'degraded',\n scope,\n enabled: operationalTelemetry,\n })\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'info',\n message: 'Sync run started',\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'running',\n summary: `Import run started for ${run.entityType}.`,\n entityType: run.entityType,\n direction: run.direction,\n },\n })\n\n if (run.progressJobId) {\n await progressService.startJob(run.progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n }\n\n const mapping = await resolveMapping(adapter, run.entityType, scope)\n let processedCount = await seedProcessedCount(run.progressJobId, scope)\n let totalCount: number | null = null\n let committedBatches = activeRun.batchesCompleted ?? 0\n // Captured while the triggering job's span is still the active one, so\n // every rooted batch trace can link back to it.\n const runTrace = captureTelemetryTrace()\n const spanAttributes = runSpanAttributes(run, providerKey, scope)\n\n try {\n const streamResult = await forEachBatch(\n withHeartbeat(\n adapter.streamImport({\n entityType: run.entityType,\n cursor: run.cursor ?? undefined,\n batchSize,\n credentials,\n mapping,\n scope: { organizationId: scope.organizationId, tenantId: scope.tenantId },\n runId: run.id,\n parameters: (run.parameters ?? {}) as RunParameters,\n }),\n makeHeartbeatTick(run.progressJobId, scope),\n HEARTBEAT_TICK_MS,\n ),\n {\n spanName: 'data_sync.import.batch',\n drainSpanName: 'data_sync.import.drain',\n attributes: spanAttributes,\n linkTo: runTrace,\n },\n async (batch, span) => {\n span.setAttributes({\n 'data_sync.batch_index': batch.batchIndex,\n 'data_sync.batch_size': batch.items.length,\n })\n\n if (run.progressJobId && await progressService.isCancellationRequested(run.progressJobId, scope.tenantId, scope.organizationId)) {\n await finalizeRun(run.id, 'cancelled', scope, undefined, operationalTelemetry)\n return 'stop'\n }\n\n const delta = applyImportCounters(batch)\n const processedBatchCount = batch.processedCount ?? batch.items.length\n processedCount += processedBatchCount\n totalCount = batch.totalEstimate ?? totalCount\n\n span.setAttributes({\n 'data_sync.processed_count': processedBatchCount,\n 'data_sync.created_count': delta.createdCount,\n 'data_sync.updated_count': delta.updatedCount,\n 'data_sync.skipped_count': delta.skippedCount,\n 'data_sync.failed_count': delta.failedCount,\n })\n\n await syncRunService.commitBatchProgress(\n run.id,\n {\n ...delta,\n batchesCompleted: 1,\n },\n batch.cursor,\n scope,\n { expectedBatchesCompleted: committedBatches, persistSharedCursor },\n )\n committedBatches += 1\n\n await updateProgress(run.progressJobId, processedCount, totalCount, scope)\n await refreshCoverageSnapshots(batch.refreshCoverageEntityTypes, scope)\n await logImportItemFailures(run.id, run.integrationId, batch.items, scope)\n\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'info',\n message: batch.message?.trim().length\n ? batch.message.trim()\n : `Processed import batch ${batch.batchIndex}`,\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'running',\n summary: `Processed ${processedCount}${totalCount ? ` of ${totalCount}` : ''} rows so far.`,\n processedCount,\n batchSize: batch.items.length,\n processedBatchCount,\n cursor: batch.cursor,\n },\n })\n\n return 'continue'\n },\n )\n if (streamResult === 'stopped') return\n } catch (error) {\n if (error instanceof SyncRunOwnershipConflictError) {\n logger.warn('Yielding import run to a concurrent worker that already advanced it', {\n runId: run.id,\n expectedBatchesCompleted: error.expectedBatchesCompleted,\n })\n return\n }\n const message = error instanceof Error ? error.message : 'Sync import failed'\n await integrationLogService.write(\n {\n integrationId: run.integrationId,\n runId: run.id,\n level: 'error',\n message,\n },\n scope,\n )\n await finalizeRun(run.id, 'failed', scope, message, operationalTelemetry)\n return\n }\n\n await finalizeRun(run.id, 'completed', scope, undefined, operationalTelemetry)\n },\n\n async runExport(runId: string, batchSize: number, scope: SyncScope): Promise<void> {\n const run = await syncRunService.getRun(runId, scope)\n if (!run) {\n logger.warn('Skipping stale export job for missing run', { runId })\n return\n }\n if (run.status === 'cancelled') {\n if (run.progressJobId) {\n await progressService.markCancelled(run.progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n }\n return\n }\n\n const providerKey = resolveProviderKey(run.integrationId)\n const adapter = getDataSyncAdapter(providerKey)\n if (!adapter?.streamExport) {\n throw new Error(`No export adapter registered for provider ${providerKey}`)\n }\n const operationalTelemetry = adapter.operationalTelemetry === true\n const persistSharedCursor = adapter.persistsSharedCursor?.(run.entityType) ?? true\n\n const credentials = await integrationCredentialsService.resolve(run.integrationId, scope)\n if (!credentials) {\n throw new Error(`Integration ${run.integrationId} is missing credentials`)\n }\n\n // A run already `running` means a stalled job was redelivered, so this is\n // a resume rather than a first start. Consumers see one `started` event per\n // delivery either way; the flag is what lets them tell the two apart.\n const resumed = run.status === 'running'\n const activeRun = await syncRunService.markStatus(run.id, 'running', scope)\n if (!activeRun || activeRun.status !== 'running') {\n return\n }\n await emitDataSyncEvent('data_sync.run.started', {\n runId: run.id,\n integrationId: run.integrationId,\n entityType: run.entityType,\n direction: run.direction,\n resumed,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n await updateOperationalState({\n integrationId: run.integrationId,\n status: 'degraded',\n scope,\n enabled: operationalTelemetry,\n })\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'info',\n message: 'Sync run started',\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'running',\n summary: `Export run started for ${run.entityType}.`,\n entityType: run.entityType,\n direction: run.direction,\n },\n })\n\n if (run.progressJobId) {\n await progressService.startJob(run.progressJobId, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: scope.userId,\n })\n }\n\n const mapping = await resolveMapping(adapter, run.entityType, scope)\n let processedCount = await seedProcessedCount(run.progressJobId, scope)\n let committedBatches = activeRun.batchesCompleted ?? 0\n // Captured while the triggering job's span is still the active one, so\n // every rooted batch trace can link back to it.\n const runTrace = captureTelemetryTrace()\n const spanAttributes = runSpanAttributes(run, providerKey, scope)\n\n try {\n const streamResult = await forEachBatch(\n withHeartbeat(\n adapter.streamExport({\n entityType: run.entityType,\n cursor: run.cursor ?? undefined,\n batchSize,\n credentials,\n mapping,\n scope: { organizationId: scope.organizationId, tenantId: scope.tenantId },\n runId: run.id,\n parameters: (run.parameters ?? {}) as RunParameters,\n }),\n makeHeartbeatTick(run.progressJobId, scope),\n HEARTBEAT_TICK_MS,\n ),\n {\n spanName: 'data_sync.export.batch',\n drainSpanName: 'data_sync.export.drain',\n attributes: spanAttributes,\n linkTo: runTrace,\n },\n async (batch, span) => {\n span.setAttributes({\n 'data_sync.batch_index': batch.batchIndex,\n 'data_sync.batch_size': batch.results.length,\n })\n\n if (run.progressJobId && await progressService.isCancellationRequested(run.progressJobId, scope.tenantId, scope.organizationId)) {\n await finalizeRun(run.id, 'cancelled', scope, undefined, operationalTelemetry)\n return 'stop'\n }\n\n const delta = applyExportCounters(batch)\n processedCount += delta.processedCount\n\n span.setAttributes({\n 'data_sync.processed_count': delta.processedCount,\n 'data_sync.updated_count': delta.updatedCount,\n 'data_sync.skipped_count': delta.skippedCount,\n 'data_sync.failed_count': delta.failedCount,\n })\n\n await syncRunService.commitBatchProgress(\n run.id,\n {\n createdCount: 0,\n updatedCount: delta.updatedCount,\n skippedCount: delta.skippedCount,\n failedCount: delta.failedCount,\n batchesCompleted: 1,\n },\n batch.cursor,\n scope,\n { expectedBatchesCompleted: committedBatches, persistSharedCursor },\n )\n committedBatches += 1\n await updateProgress(run.progressJobId, processedCount, null, scope)\n await logExportItemFailures(run.id, run.integrationId, batch.results, scope)\n\n await writeOperationalLog({\n integrationId: run.integrationId,\n runId: run.id,\n level: 'info',\n message: `Processed export batch ${batch.batchIndex}`,\n scope,\n enabled: operationalTelemetry,\n payload: {\n operationalStatus: 'running',\n summary: `Processed ${processedCount} export items so far.`,\n processedCount,\n batchSize: batch.results.length,\n cursor: batch.cursor,\n },\n })\n\n return 'continue'\n },\n )\n if (streamResult === 'stopped') return\n } catch (error) {\n if (error instanceof SyncRunOwnershipConflictError) {\n logger.warn('Yielding export run to a concurrent worker that already advanced it', {\n runId: run.id,\n expectedBatchesCompleted: error.expectedBatchesCompleted,\n })\n return\n }\n const message = error instanceof Error ? error.message : 'Sync export failed'\n await integrationLogService.write(\n {\n integrationId: run.integrationId,\n runId: run.id,\n level: 'error',\n message,\n },\n scope,\n )\n await finalizeRun(run.id, 'failed', scope, message, operationalTelemetry)\n return\n }\n\n await finalizeRun(run.id, 'completed', scope, undefined, operationalTelemetry)\n },\n }\n}\n\nexport type SyncEngine = ReturnType<typeof createSyncEngine>\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,6 @@ import {
3
3
  DATA_SYNC_LOCK_DURATION_MS,
4
4
  DATA_SYNC_MAX_STALLED_COUNT
5
5
  } from "../lib/queue-policy.js";
6
- import { failAbandonedRun } from "../lib/abandoned-run.js";
7
6
  import { createLogger } from "@open-mercato/shared/lib/logger";
8
7
  const logger = createLogger("data_sync").child({ component: "sync-export" });
9
8
  const metadata = {
@@ -11,10 +10,7 @@ const metadata = {
11
10
  id: "data-sync:export",
12
11
  concurrency: 5,
13
12
  lockDuration: DATA_SYNC_LOCK_DURATION_MS,
14
- maxStalledCount: DATA_SYNC_MAX_STALLED_COUNT,
15
- // Declared on the worker, not on the enqueueing queue: the abandonment this reports is a worker
16
- // restart, and the process that restarts never constructs the producer's queue instance.
17
- onJobAbandoned: failAbandonedRun
13
+ maxStalledCount: DATA_SYNC_MAX_STALLED_COUNT
18
14
  };
19
15
  async function handle(job, ctx) {
20
16
  try {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/data_sync/workers/sync-export.ts"],
4
- "sourcesContent": ["import type { JobContext, QueuedJob, WorkerMeta } from '@open-mercato/queue'\nimport type { ProgressService } from '../../progress/lib/progressService'\nimport type { SyncEngine } from '../lib/sync-engine'\nimport type { SyncRunService } from '../lib/sync-run-service'\nimport {\n DATA_SYNC_EXPORT_QUEUE,\n DATA_SYNC_LOCK_DURATION_MS,\n DATA_SYNC_MAX_STALLED_COUNT,\n} from '../lib/queue-policy'\nimport { failAbandonedRun } from '../lib/abandoned-run'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('data_sync').child({ component: 'sync-export' })\n\ntype SyncJobPayload = {\n runId: string\n batchSize: number\n scope: {\n organizationId: string\n tenantId: string\n userId?: string | null\n }\n}\n\nexport const metadata: WorkerMeta = {\n queue: DATA_SYNC_EXPORT_QUEUE,\n id: 'data-sync:export',\n concurrency: 5,\n lockDuration: DATA_SYNC_LOCK_DURATION_MS,\n maxStalledCount: DATA_SYNC_MAX_STALLED_COUNT,\n // Declared on the worker, not on the enqueueing queue: the abandonment this reports is a worker\n // restart, and the process that restarts never constructs the producer's queue instance.\n onJobAbandoned: failAbandonedRun,\n}\n\ntype HandlerContext = JobContext & {\n resolve: <T = unknown>(name: string) => T\n}\n\nexport default async function handle(job: QueuedJob<SyncJobPayload>, ctx: HandlerContext): Promise<void> {\n try {\n const engine = ctx.resolve<SyncEngine>('dataSyncEngine')\n await engine.runExport(job.payload.runId, job.payload.batchSize, job.payload.scope)\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Data sync export worker failed'\n const errorStack = error instanceof Error ? error.stack : undefined\n\n try {\n const syncRunService = ctx.resolve<SyncRunService>('dataSyncRunService')\n const progressService = ctx.resolve<ProgressService>('progressService')\n const run = await syncRunService.getRun(job.payload.runId, job.payload.scope)\n\n if (run && run.status !== 'completed' && run.status !== 'failed' && run.status !== 'cancelled') {\n await syncRunService.markStatus(run.id, 'failed', job.payload.scope, message)\n if (run.progressJobId) {\n await progressService.failJob(\n run.progressJobId,\n {\n errorMessage: message,\n errorStack,\n },\n job.payload.scope,\n )\n }\n }\n } catch (finalizeError) {\n logger.error('Failed to finalize crashed export worker job', { err: finalizeError })\n }\n\n throw error\n }\n}\n"],
5
- "mappings": "AAIA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,wBAAwB;AACjC,SAAS,oBAAoB;AAE7B,MAAM,SAAS,aAAa,WAAW,EAAE,MAAM,EAAE,WAAW,cAAc,CAAC;AAYpE,MAAM,WAAuB;AAAA,EAClC,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,cAAc;AAAA,EACd,iBAAiB;AAAA;AAAA;AAAA,EAGjB,gBAAgB;AAClB;AAMA,eAAO,OAA8B,KAAgC,KAAoC;AACvG,MAAI;AACF,UAAM,SAAS,IAAI,QAAoB,gBAAgB;AACvD,UAAM,OAAO,UAAU,IAAI,QAAQ,OAAO,IAAI,QAAQ,WAAW,IAAI,QAAQ,KAAK;AAAA,EACpF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,UAAM,aAAa,iBAAiB,QAAQ,MAAM,QAAQ;AAE1D,QAAI;AACF,YAAM,iBAAiB,IAAI,QAAwB,oBAAoB;AACvE,YAAM,kBAAkB,IAAI,QAAyB,iBAAiB;AACtE,YAAM,MAAM,MAAM,eAAe,OAAO,IAAI,QAAQ,OAAO,IAAI,QAAQ,KAAK;AAE5E,UAAI,OAAO,IAAI,WAAW,eAAe,IAAI,WAAW,YAAY,IAAI,WAAW,aAAa;AAC9F,cAAM,eAAe,WAAW,IAAI,IAAI,UAAU,IAAI,QAAQ,OAAO,OAAO;AAC5E,YAAI,IAAI,eAAe;AACrB,gBAAM,gBAAgB;AAAA,YACpB,IAAI;AAAA,YACJ;AAAA,cACE,cAAc;AAAA,cACd;AAAA,YACF;AAAA,YACA,IAAI,QAAQ;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,eAAe;AACtB,aAAO,MAAM,gDAAgD,EAAE,KAAK,cAAc,CAAC;AAAA,IACrF;AAEA,UAAM;AAAA,EACR;AACF;",
4
+ "sourcesContent": ["import type { JobContext, QueuedJob, WorkerMeta } from '@open-mercato/queue'\nimport type { ProgressService } from '../../progress/lib/progressService'\nimport type { SyncEngine } from '../lib/sync-engine'\nimport type { SyncRunService } from '../lib/sync-run-service'\nimport {\n DATA_SYNC_EXPORT_QUEUE,\n DATA_SYNC_LOCK_DURATION_MS,\n DATA_SYNC_MAX_STALLED_COUNT,\n} from '../lib/queue-policy'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('data_sync').child({ component: 'sync-export' })\n\ntype SyncJobPayload = {\n runId: string\n batchSize: number\n scope: {\n organizationId: string\n tenantId: string\n userId?: string | null\n }\n}\n\nexport const metadata: WorkerMeta = {\n queue: DATA_SYNC_EXPORT_QUEUE,\n id: 'data-sync:export',\n concurrency: 5,\n lockDuration: DATA_SYNC_LOCK_DURATION_MS,\n maxStalledCount: DATA_SYNC_MAX_STALLED_COUNT,\n}\n\ntype HandlerContext = JobContext & {\n resolve: <T = unknown>(name: string) => T\n}\n\nexport default async function handle(job: QueuedJob<SyncJobPayload>, ctx: HandlerContext): Promise<void> {\n try {\n const engine = ctx.resolve<SyncEngine>('dataSyncEngine')\n await engine.runExport(job.payload.runId, job.payload.batchSize, job.payload.scope)\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Data sync export worker failed'\n const errorStack = error instanceof Error ? error.stack : undefined\n\n try {\n const syncRunService = ctx.resolve<SyncRunService>('dataSyncRunService')\n const progressService = ctx.resolve<ProgressService>('progressService')\n const run = await syncRunService.getRun(job.payload.runId, job.payload.scope)\n\n if (run && run.status !== 'completed' && run.status !== 'failed' && run.status !== 'cancelled') {\n await syncRunService.markStatus(run.id, 'failed', job.payload.scope, message)\n if (run.progressJobId) {\n await progressService.failJob(\n run.progressJobId,\n {\n errorMessage: message,\n errorStack,\n },\n job.payload.scope,\n )\n }\n }\n } catch (finalizeError) {\n logger.error('Failed to finalize crashed export worker job', { err: finalizeError })\n }\n\n throw error\n }\n}\n"],
5
+ "mappings": "AAIA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAE7B,MAAM,SAAS,aAAa,WAAW,EAAE,MAAM,EAAE,WAAW,cAAc,CAAC;AAYpE,MAAM,WAAuB;AAAA,EAClC,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,cAAc;AAAA,EACd,iBAAiB;AACnB;AAMA,eAAO,OAA8B,KAAgC,KAAoC;AACvG,MAAI;AACF,UAAM,SAAS,IAAI,QAAoB,gBAAgB;AACvD,UAAM,OAAO,UAAU,IAAI,QAAQ,OAAO,IAAI,QAAQ,WAAW,IAAI,QAAQ,KAAK;AAAA,EACpF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,UAAM,aAAa,iBAAiB,QAAQ,MAAM,QAAQ;AAE1D,QAAI;AACF,YAAM,iBAAiB,IAAI,QAAwB,oBAAoB;AACvE,YAAM,kBAAkB,IAAI,QAAyB,iBAAiB;AACtE,YAAM,MAAM,MAAM,eAAe,OAAO,IAAI,QAAQ,OAAO,IAAI,QAAQ,KAAK;AAE5E,UAAI,OAAO,IAAI,WAAW,eAAe,IAAI,WAAW,YAAY,IAAI,WAAW,aAAa;AAC9F,cAAM,eAAe,WAAW,IAAI,IAAI,UAAU,IAAI,QAAQ,OAAO,OAAO;AAC5E,YAAI,IAAI,eAAe;AACrB,gBAAM,gBAAgB;AAAA,YACpB,IAAI;AAAA,YACJ;AAAA,cACE,cAAc;AAAA,cACd;AAAA,YACF;AAAA,YACA,IAAI,QAAQ;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,eAAe;AACtB,aAAO,MAAM,gDAAgD,EAAE,KAAK,cAAc,CAAC;AAAA,IACrF;AAEA,UAAM;AAAA,EACR;AACF;",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,6 @@ import {
3
3
  DATA_SYNC_LOCK_DURATION_MS,
4
4
  DATA_SYNC_MAX_STALLED_COUNT
5
5
  } from "../lib/queue-policy.js";
6
- import { failAbandonedRun } from "../lib/abandoned-run.js";
7
6
  import { createLogger } from "@open-mercato/shared/lib/logger";
8
7
  const logger = createLogger("data_sync").child({ component: "sync-import" });
9
8
  const metadata = {
@@ -11,10 +10,7 @@ const metadata = {
11
10
  id: "data-sync:import",
12
11
  concurrency: 5,
13
12
  lockDuration: DATA_SYNC_LOCK_DURATION_MS,
14
- maxStalledCount: DATA_SYNC_MAX_STALLED_COUNT,
15
- // Declared on the worker, not on the enqueueing queue: the abandonment this reports is a worker
16
- // restart, and the process that restarts never constructs the producer's queue instance.
17
- onJobAbandoned: failAbandonedRun
13
+ maxStalledCount: DATA_SYNC_MAX_STALLED_COUNT
18
14
  };
19
15
  async function handle(job, ctx) {
20
16
  try {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/data_sync/workers/sync-import.ts"],
4
- "sourcesContent": ["import type { JobContext, QueuedJob, WorkerMeta } from '@open-mercato/queue'\nimport type { ProgressService } from '../../progress/lib/progressService'\nimport type { SyncEngine } from '../lib/sync-engine'\nimport type { SyncRunService } from '../lib/sync-run-service'\nimport {\n DATA_SYNC_IMPORT_QUEUE,\n DATA_SYNC_LOCK_DURATION_MS,\n DATA_SYNC_MAX_STALLED_COUNT,\n} from '../lib/queue-policy'\nimport { failAbandonedRun } from '../lib/abandoned-run'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('data_sync').child({ component: 'sync-import' })\n\ntype SyncJobPayload = {\n runId: string\n batchSize: number\n scope: {\n organizationId: string\n tenantId: string\n userId?: string | null\n }\n}\n\nexport const metadata: WorkerMeta = {\n queue: DATA_SYNC_IMPORT_QUEUE,\n id: 'data-sync:import',\n concurrency: 5,\n lockDuration: DATA_SYNC_LOCK_DURATION_MS,\n maxStalledCount: DATA_SYNC_MAX_STALLED_COUNT,\n // Declared on the worker, not on the enqueueing queue: the abandonment this reports is a worker\n // restart, and the process that restarts never constructs the producer's queue instance.\n onJobAbandoned: failAbandonedRun,\n}\n\ntype HandlerContext = JobContext & {\n resolve: <T = unknown>(name: string) => T\n}\n\nexport default async function handle(job: QueuedJob<SyncJobPayload>, ctx: HandlerContext): Promise<void> {\n try {\n const engine = ctx.resolve<SyncEngine>('dataSyncEngine')\n await engine.runImport(job.payload.runId, job.payload.batchSize, job.payload.scope)\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Data sync import worker failed'\n const errorStack = error instanceof Error ? error.stack : undefined\n\n try {\n const syncRunService = ctx.resolve<SyncRunService>('dataSyncRunService')\n const progressService = ctx.resolve<ProgressService>('progressService')\n const run = await syncRunService.getRun(job.payload.runId, job.payload.scope)\n\n if (run && run.status !== 'completed' && run.status !== 'failed' && run.status !== 'cancelled') {\n await syncRunService.markStatus(run.id, 'failed', job.payload.scope, message)\n if (run.progressJobId) {\n await progressService.failJob(\n run.progressJobId,\n {\n errorMessage: message,\n errorStack,\n },\n job.payload.scope,\n )\n }\n }\n } catch (finalizeError) {\n logger.error('Failed to finalize crashed import worker job', { err: finalizeError })\n }\n\n throw error\n }\n}\n"],
5
- "mappings": "AAIA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,wBAAwB;AACjC,SAAS,oBAAoB;AAE7B,MAAM,SAAS,aAAa,WAAW,EAAE,MAAM,EAAE,WAAW,cAAc,CAAC;AAYpE,MAAM,WAAuB;AAAA,EAClC,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,cAAc;AAAA,EACd,iBAAiB;AAAA;AAAA;AAAA,EAGjB,gBAAgB;AAClB;AAMA,eAAO,OAA8B,KAAgC,KAAoC;AACvG,MAAI;AACF,UAAM,SAAS,IAAI,QAAoB,gBAAgB;AACvD,UAAM,OAAO,UAAU,IAAI,QAAQ,OAAO,IAAI,QAAQ,WAAW,IAAI,QAAQ,KAAK;AAAA,EACpF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,UAAM,aAAa,iBAAiB,QAAQ,MAAM,QAAQ;AAE1D,QAAI;AACF,YAAM,iBAAiB,IAAI,QAAwB,oBAAoB;AACvE,YAAM,kBAAkB,IAAI,QAAyB,iBAAiB;AACtE,YAAM,MAAM,MAAM,eAAe,OAAO,IAAI,QAAQ,OAAO,IAAI,QAAQ,KAAK;AAE5E,UAAI,OAAO,IAAI,WAAW,eAAe,IAAI,WAAW,YAAY,IAAI,WAAW,aAAa;AAC9F,cAAM,eAAe,WAAW,IAAI,IAAI,UAAU,IAAI,QAAQ,OAAO,OAAO;AAC5E,YAAI,IAAI,eAAe;AACrB,gBAAM,gBAAgB;AAAA,YACpB,IAAI;AAAA,YACJ;AAAA,cACE,cAAc;AAAA,cACd;AAAA,YACF;AAAA,YACA,IAAI,QAAQ;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,eAAe;AACtB,aAAO,MAAM,gDAAgD,EAAE,KAAK,cAAc,CAAC;AAAA,IACrF;AAEA,UAAM;AAAA,EACR;AACF;",
4
+ "sourcesContent": ["import type { JobContext, QueuedJob, WorkerMeta } from '@open-mercato/queue'\nimport type { ProgressService } from '../../progress/lib/progressService'\nimport type { SyncEngine } from '../lib/sync-engine'\nimport type { SyncRunService } from '../lib/sync-run-service'\nimport {\n DATA_SYNC_IMPORT_QUEUE,\n DATA_SYNC_LOCK_DURATION_MS,\n DATA_SYNC_MAX_STALLED_COUNT,\n} from '../lib/queue-policy'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('data_sync').child({ component: 'sync-import' })\n\ntype SyncJobPayload = {\n runId: string\n batchSize: number\n scope: {\n organizationId: string\n tenantId: string\n userId?: string | null\n }\n}\n\nexport const metadata: WorkerMeta = {\n queue: DATA_SYNC_IMPORT_QUEUE,\n id: 'data-sync:import',\n concurrency: 5,\n lockDuration: DATA_SYNC_LOCK_DURATION_MS,\n maxStalledCount: DATA_SYNC_MAX_STALLED_COUNT,\n}\n\ntype HandlerContext = JobContext & {\n resolve: <T = unknown>(name: string) => T\n}\n\nexport default async function handle(job: QueuedJob<SyncJobPayload>, ctx: HandlerContext): Promise<void> {\n try {\n const engine = ctx.resolve<SyncEngine>('dataSyncEngine')\n await engine.runImport(job.payload.runId, job.payload.batchSize, job.payload.scope)\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Data sync import worker failed'\n const errorStack = error instanceof Error ? error.stack : undefined\n\n try {\n const syncRunService = ctx.resolve<SyncRunService>('dataSyncRunService')\n const progressService = ctx.resolve<ProgressService>('progressService')\n const run = await syncRunService.getRun(job.payload.runId, job.payload.scope)\n\n if (run && run.status !== 'completed' && run.status !== 'failed' && run.status !== 'cancelled') {\n await syncRunService.markStatus(run.id, 'failed', job.payload.scope, message)\n if (run.progressJobId) {\n await progressService.failJob(\n run.progressJobId,\n {\n errorMessage: message,\n errorStack,\n },\n job.payload.scope,\n )\n }\n }\n } catch (finalizeError) {\n logger.error('Failed to finalize crashed import worker job', { err: finalizeError })\n }\n\n throw error\n }\n}\n"],
5
+ "mappings": "AAIA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAE7B,MAAM,SAAS,aAAa,WAAW,EAAE,MAAM,EAAE,WAAW,cAAc,CAAC;AAYpE,MAAM,WAAuB;AAAA,EAClC,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,cAAc;AAAA,EACd,iBAAiB;AACnB;AAMA,eAAO,OAA8B,KAAgC,KAAoC;AACvG,MAAI;AACF,UAAM,SAAS,IAAI,QAAoB,gBAAgB;AACvD,UAAM,OAAO,UAAU,IAAI,QAAQ,OAAO,IAAI,QAAQ,WAAW,IAAI,QAAQ,KAAK;AAAA,EACpF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,UAAM,aAAa,iBAAiB,QAAQ,MAAM,QAAQ;AAE1D,QAAI;AACF,YAAM,iBAAiB,IAAI,QAAwB,oBAAoB;AACvE,YAAM,kBAAkB,IAAI,QAAyB,iBAAiB;AACtE,YAAM,MAAM,MAAM,eAAe,OAAO,IAAI,QAAQ,OAAO,IAAI,QAAQ,KAAK;AAE5E,UAAI,OAAO,IAAI,WAAW,eAAe,IAAI,WAAW,YAAY,IAAI,WAAW,aAAa;AAC9F,cAAM,eAAe,WAAW,IAAI,IAAI,UAAU,IAAI,QAAQ,OAAO,OAAO;AAC5E,YAAI,IAAI,eAAe;AACrB,gBAAM,gBAAgB;AAAA,YACpB,IAAI;AAAA,YACJ;AAAA,cACE,cAAc;AAAA,cACd;AAAA,YACF;AAAA,YACA,IAAI,QAAQ;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,eAAe;AACtB,aAAO,MAAM,gDAAgD,EAAE,KAAK,cAAc,CAAC;AAAA,IACrF;AAEA,UAAM;AAAA,EACR;AACF;",
6
6
  "names": []
7
7
  }
@@ -13,8 +13,6 @@ import { updateDeviceSchema } from "../../../../data/validators.js";
13
13
  import { isOrganizationReadAccessAllowed } from "@open-mercato/core/modules/directory/utils/organizationScopeGuard";
14
14
  import { resolveDeviceActorUserId } from "../../../auth.js";
15
15
  import { executeUpdate, executeDeactivate } from "../../../deviceOps.js";
16
- import { serializeDeviceDetail, deviceDetailItemSchema } from "../../../deviceSerialization.js";
17
- import { DEPRECATED_SNAKE_CASE_NOTICE } from "../../../openapi.js";
18
16
  const logger = createLogger("devices");
19
17
  const metadata = {
20
18
  GET: { requireAuth: true, requireFeatures: ["devices.admin"] },
@@ -26,6 +24,21 @@ async function loadDevice(container, id, tenantId) {
26
24
  const em = container.resolve("em");
27
25
  return findOneWithDecryption(em, UserDevice, { id, tenantId, deletedAt: null }, void 0, { tenantId });
28
26
  }
27
+ function serializeDevice(device) {
28
+ return {
29
+ id: device.id,
30
+ user_id: device.userId,
31
+ device_id: device.deviceId,
32
+ platform: device.platform,
33
+ client_app_version: device.clientAppVersion ?? null,
34
+ os_version: device.osVersion ?? null,
35
+ push_provider: device.pushProvider ?? null,
36
+ push_token_updated_at: device.pushTokenUpdatedAt ? device.pushTokenUpdatedAt.toISOString() : null,
37
+ last_seen_at: device.lastSeenAt ? device.lastSeenAt.toISOString() : null,
38
+ created_at: device.createdAt ? device.createdAt.toISOString() : null,
39
+ updated_at: device.updatedAt ? device.updatedAt.toISOString() : null
40
+ };
41
+ }
29
42
  async function GET(req, { params }) {
30
43
  const { translate } = await resolveTranslations();
31
44
  try {
@@ -47,7 +60,7 @@ async function GET(req, { params }) {
47
60
  if (!isOrganizationReadAccessAllowed({ scope, auth, organizationId: device.organizationId ?? null })) {
48
61
  return NextResponse.json({ error: translate("devices.errors.forbidden", "Access denied") }, { status: 403 });
49
62
  }
50
- return NextResponse.json({ item: serializeDeviceDetail(device) });
63
+ return NextResponse.json({ item: serializeDevice(device) });
51
64
  } catch (err) {
52
65
  if (isCrudHttpError(err)) {
53
66
  return NextResponse.json(err.body, { status: err.status });
@@ -141,14 +154,28 @@ async function DELETE(req, { params }) {
141
154
  }
142
155
  const okResponseSchema = z.object({ ok: z.literal(true), id: z.string().uuid().optional() });
143
156
  const errorResponseSchema = z.object({ error: z.string() });
144
- const detailResponseSchema = z.object({ item: deviceDetailItemSchema });
157
+ const detailResponseSchema = z.object({
158
+ item: z.object({
159
+ id: z.string().uuid(),
160
+ user_id: z.string().uuid(),
161
+ device_id: z.string(),
162
+ platform: z.enum(["ios", "android", "web"]),
163
+ client_app_version: z.string().nullable(),
164
+ os_version: z.string().nullable(),
165
+ push_provider: z.string().nullable(),
166
+ push_token_updated_at: z.string().nullable(),
167
+ last_seen_at: z.string().nullable(),
168
+ created_at: z.string().nullable(),
169
+ updated_at: z.string().nullable()
170
+ })
171
+ });
145
172
  const openApi = {
146
173
  tag: "Devices (admin)",
147
174
  summary: "Admin: read, update or deactivate any device in the tenant",
148
175
  methods: {
149
176
  GET: {
150
177
  summary: "Get any device",
151
- description: `Admin: fetch a single device by id (push_token is never returned). ${DEPRECATED_SNAKE_CASE_NOTICE}`,
178
+ description: "Admin: fetch a single device by id (push_token is never returned).",
152
179
  responses: [{ status: 200, description: "Device", schema: detailResponseSchema }],
153
180
  errors: [
154
181
  { status: 400, description: "Invalid id", schema: errorResponseSchema },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/devices/api/admin/devices/%5Bid%5D/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport { UserDevice } from '../../../../data/entities'\nimport { updateDeviceSchema } from '../../../../data/validators'\nimport { isOrganizationReadAccessAllowed } from '@open-mercato/core/modules/directory/utils/organizationScopeGuard'\nimport { resolveDeviceActorUserId } from '../../../auth'\nimport { executeUpdate, executeDeactivate, type DeviceMutationContext } from '../../../deviceOps'\nimport { serializeDeviceDetail, deviceDetailItemSchema } from '../../../deviceSerialization'\nimport { DEPRECATED_SNAKE_CASE_NOTICE } from '../../../openapi'\n\nconst logger = createLogger('devices')\n\n// Admin: read/update/deactivate ANY device in the tenant. Gated by devices.admin (no owner check).\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['devices.admin'] },\n PUT: { requireAuth: true, requireFeatures: ['devices.admin'] },\n DELETE: { requireAuth: true, requireFeatures: ['devices.admin'] },\n}\n\nconst paramsSchema = z.object({ id: z.string().uuid() })\n\nasync function loadDevice(\n container: Awaited<ReturnType<typeof createRequestContainer>>,\n id: string,\n tenantId: string,\n): Promise<UserDevice | null> {\n const em = container.resolve('em') as EntityManager\n // push_token is encrypted at rest; the org is not known until the row loads, so pass tenant only \u2014\n // the helper prefers each record's own tenant/org and treats this scope as a fallback.\n return findOneWithDecryption(em, UserDevice, { id, tenantId, deletedAt: null }, undefined, { tenantId })\n}\n\nexport async function GET(req: Request, { params }: { params: { id: string } }) {\n const { translate } = await resolveTranslations()\n try {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const actorUserId = resolveDeviceActorUserId(auth)\n if (!auth || !auth.tenantId || !actorUserId) {\n return NextResponse.json({ error: translate('devices.errors.unauthorized', 'Unauthorized') }, { status: 401 })\n }\n const parsedParams = paramsSchema.safeParse({ id: params.id })\n if (!parsedParams.success) {\n return NextResponse.json({ error: translate('devices.errors.invalid_id', 'Invalid device id') }, { status: 400 })\n }\n const device = await loadDevice(container, parsedParams.data.id, auth.tenantId)\n if (!device) {\n return NextResponse.json({ error: translate('devices.errors.not_found', 'Device not found') }, { status: 404 })\n }\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n if (!isOrganizationReadAccessAllowed({ scope, auth, organizationId: device.organizationId ?? null })) {\n return NextResponse.json({ error: translate('devices.errors.forbidden', 'Access denied') }, { status: 403 })\n }\n return NextResponse.json({ item: serializeDeviceDetail(device) })\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n logger.error('devices.admin.GET failed', { err })\n return NextResponse.json({ error: translate('devices.errors.load_failed', 'Failed to load device') }, { status: 500 })\n }\n}\n\nexport async function PUT(req: Request, { params }: { params: { id: string } }) {\n const { translate } = await resolveTranslations()\n try {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const actorUserId = resolveDeviceActorUserId(auth)\n if (!auth || !auth.tenantId || !actorUserId) {\n return NextResponse.json({ error: translate('devices.errors.unauthorized', 'Unauthorized') }, { status: 401 })\n }\n const parsedParams = paramsSchema.safeParse({ id: params.id })\n if (!parsedParams.success) {\n return NextResponse.json({ error: translate('devices.errors.invalid_id', 'Invalid device id') }, { status: 400 })\n }\n\n const body = updateDeviceSchema.parse(await readJsonSafe(req, {}))\n const device = await loadDevice(container, parsedParams.data.id, auth.tenantId)\n if (!device) {\n return NextResponse.json({ error: translate('devices.errors.not_found', 'Device not found') }, { status: 404 })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n if (!isOrganizationReadAccessAllowed({ scope, auth, organizationId: device.organizationId ?? null })) {\n return NextResponse.json({ error: translate('devices.errors.forbidden', 'Access denied') }, { status: 403 })\n }\n const mctx: DeviceMutationContext = {\n container,\n auth,\n scope,\n organizationId: device.organizationId ?? null,\n actorUserId,\n request: req,\n }\n return await executeUpdate(mctx, device, body)\n } catch (err) {\n if (err instanceof z.ZodError) {\n return NextResponse.json(\n { error: translate('devices.errors.invalid_payload', 'Invalid device payload'), details: err.flatten() },\n { status: 400 },\n )\n }\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n logger.error('devices.admin.PUT failed', { err })\n return NextResponse.json({ error: translate('devices.errors.update_failed', 'Failed to update device') }, { status: 500 })\n }\n}\n\nexport async function DELETE(req: Request, { params }: { params: { id: string } }) {\n const { translate } = await resolveTranslations()\n try {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const actorUserId = resolveDeviceActorUserId(auth)\n if (!auth || !auth.tenantId || !actorUserId) {\n return NextResponse.json({ error: translate('devices.errors.unauthorized', 'Unauthorized') }, { status: 401 })\n }\n const parsedParams = paramsSchema.safeParse({ id: params.id })\n if (!parsedParams.success) {\n return NextResponse.json({ error: translate('devices.errors.invalid_id', 'Invalid device id') }, { status: 400 })\n }\n\n const device = await loadDevice(container, parsedParams.data.id, auth.tenantId)\n if (!device) {\n return NextResponse.json({ error: translate('devices.errors.not_found', 'Device not found') }, { status: 404 })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n if (!isOrganizationReadAccessAllowed({ scope, auth, organizationId: device.organizationId ?? null })) {\n return NextResponse.json({ error: translate('devices.errors.forbidden', 'Access denied') }, { status: 403 })\n }\n const mctx: DeviceMutationContext = {\n container,\n auth,\n scope,\n organizationId: device.organizationId ?? null,\n actorUserId,\n request: req,\n }\n return await executeDeactivate(mctx, device)\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n logger.error('devices.admin.DELETE failed', { err })\n return NextResponse.json({ error: translate('devices.errors.delete_failed', 'Failed to delete device') }, { status: 500 })\n }\n}\n\nconst okResponseSchema = z.object({ ok: z.literal(true), id: z.string().uuid().optional() })\nconst errorResponseSchema = z.object({ error: z.string() })\nconst detailResponseSchema = z.object({ item: deviceDetailItemSchema })\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Devices (admin)',\n summary: 'Admin: read, update or deactivate any device in the tenant',\n methods: {\n GET: {\n summary: 'Get any device',\n description: `Admin: fetch a single device by id (push_token is never returned). ${DEPRECATED_SNAKE_CASE_NOTICE}`,\n responses: [{ status: 200, description: 'Device', schema: detailResponseSchema }],\n errors: [\n { status: 400, description: 'Invalid id', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n { status: 403, description: 'Missing devices.admin', schema: errorResponseSchema },\n { status: 404, description: 'Device not found', schema: errorResponseSchema },\n ],\n },\n PUT: {\n summary: 'Update any device',\n description: 'Admin: update last-seen, app/OS metadata, and push token for any device. Set pushToken to null to clear it.',\n requestBody: { schema: updateDeviceSchema },\n responses: [{ status: 200, description: 'Device updated', schema: okResponseSchema }],\n errors: [\n { status: 400, description: 'Invalid payload or id', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n { status: 403, description: 'Missing devices.admin', schema: errorResponseSchema },\n { status: 404, description: 'Device not found', schema: errorResponseSchema },\n ],\n },\n DELETE: {\n summary: 'Deactivate any device',\n description: 'Admin: soft-delete any device in the tenant.',\n responses: [{ status: 200, description: 'Device deactivated', schema: okResponseSchema }],\n errors: [\n { status: 400, description: 'Invalid id', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n { status: 403, description: 'Missing devices.admin', schema: errorResponseSchema },\n { status: 404, description: 'Device not found', schema: errorResponseSchema },\n ],\n },\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport { UserDevice } from '../../../../data/entities'\nimport { updateDeviceSchema } from '../../../../data/validators'\nimport { isOrganizationReadAccessAllowed } from '@open-mercato/core/modules/directory/utils/organizationScopeGuard'\nimport { resolveDeviceActorUserId } from '../../../auth'\nimport { executeUpdate, executeDeactivate, type DeviceMutationContext } from '../../../deviceOps'\n\nconst logger = createLogger('devices')\n\n// Admin: read/update/deactivate ANY device in the tenant. Gated by devices.admin (no owner check).\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['devices.admin'] },\n PUT: { requireAuth: true, requireFeatures: ['devices.admin'] },\n DELETE: { requireAuth: true, requireFeatures: ['devices.admin'] },\n}\n\nconst paramsSchema = z.object({ id: z.string().uuid() })\n\nasync function loadDevice(\n container: Awaited<ReturnType<typeof createRequestContainer>>,\n id: string,\n tenantId: string,\n): Promise<UserDevice | null> {\n const em = container.resolve('em') as EntityManager\n // push_token is encrypted at rest; the org is not known until the row loads, so pass tenant only \u2014\n // the helper prefers each record's own tenant/org and treats this scope as a fallback.\n return findOneWithDecryption(em, UserDevice, { id, tenantId, deletedAt: null }, undefined, { tenantId })\n}\n\n// push_token is a secret and is never returned.\nfunction serializeDevice(device: UserDevice) {\n return {\n id: device.id,\n user_id: device.userId,\n device_id: device.deviceId,\n platform: device.platform,\n client_app_version: device.clientAppVersion ?? null,\n os_version: device.osVersion ?? null,\n push_provider: device.pushProvider ?? null,\n push_token_updated_at: device.pushTokenUpdatedAt ? device.pushTokenUpdatedAt.toISOString() : null,\n last_seen_at: device.lastSeenAt ? device.lastSeenAt.toISOString() : null,\n created_at: device.createdAt ? device.createdAt.toISOString() : null,\n updated_at: device.updatedAt ? device.updatedAt.toISOString() : null,\n }\n}\n\nexport async function GET(req: Request, { params }: { params: { id: string } }) {\n const { translate } = await resolveTranslations()\n try {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const actorUserId = resolveDeviceActorUserId(auth)\n if (!auth || !auth.tenantId || !actorUserId) {\n return NextResponse.json({ error: translate('devices.errors.unauthorized', 'Unauthorized') }, { status: 401 })\n }\n const parsedParams = paramsSchema.safeParse({ id: params.id })\n if (!parsedParams.success) {\n return NextResponse.json({ error: translate('devices.errors.invalid_id', 'Invalid device id') }, { status: 400 })\n }\n const device = await loadDevice(container, parsedParams.data.id, auth.tenantId)\n if (!device) {\n return NextResponse.json({ error: translate('devices.errors.not_found', 'Device not found') }, { status: 404 })\n }\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n if (!isOrganizationReadAccessAllowed({ scope, auth, organizationId: device.organizationId ?? null })) {\n return NextResponse.json({ error: translate('devices.errors.forbidden', 'Access denied') }, { status: 403 })\n }\n return NextResponse.json({ item: serializeDevice(device) })\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n logger.error('devices.admin.GET failed', { err })\n return NextResponse.json({ error: translate('devices.errors.load_failed', 'Failed to load device') }, { status: 500 })\n }\n}\n\nexport async function PUT(req: Request, { params }: { params: { id: string } }) {\n const { translate } = await resolveTranslations()\n try {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const actorUserId = resolveDeviceActorUserId(auth)\n if (!auth || !auth.tenantId || !actorUserId) {\n return NextResponse.json({ error: translate('devices.errors.unauthorized', 'Unauthorized') }, { status: 401 })\n }\n const parsedParams = paramsSchema.safeParse({ id: params.id })\n if (!parsedParams.success) {\n return NextResponse.json({ error: translate('devices.errors.invalid_id', 'Invalid device id') }, { status: 400 })\n }\n\n const body = updateDeviceSchema.parse(await readJsonSafe(req, {}))\n const device = await loadDevice(container, parsedParams.data.id, auth.tenantId)\n if (!device) {\n return NextResponse.json({ error: translate('devices.errors.not_found', 'Device not found') }, { status: 404 })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n if (!isOrganizationReadAccessAllowed({ scope, auth, organizationId: device.organizationId ?? null })) {\n return NextResponse.json({ error: translate('devices.errors.forbidden', 'Access denied') }, { status: 403 })\n }\n const mctx: DeviceMutationContext = {\n container,\n auth,\n scope,\n organizationId: device.organizationId ?? null,\n actorUserId,\n request: req,\n }\n return await executeUpdate(mctx, device, body)\n } catch (err) {\n if (err instanceof z.ZodError) {\n return NextResponse.json(\n { error: translate('devices.errors.invalid_payload', 'Invalid device payload'), details: err.flatten() },\n { status: 400 },\n )\n }\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n logger.error('devices.admin.PUT failed', { err })\n return NextResponse.json({ error: translate('devices.errors.update_failed', 'Failed to update device') }, { status: 500 })\n }\n}\n\nexport async function DELETE(req: Request, { params }: { params: { id: string } }) {\n const { translate } = await resolveTranslations()\n try {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const actorUserId = resolveDeviceActorUserId(auth)\n if (!auth || !auth.tenantId || !actorUserId) {\n return NextResponse.json({ error: translate('devices.errors.unauthorized', 'Unauthorized') }, { status: 401 })\n }\n const parsedParams = paramsSchema.safeParse({ id: params.id })\n if (!parsedParams.success) {\n return NextResponse.json({ error: translate('devices.errors.invalid_id', 'Invalid device id') }, { status: 400 })\n }\n\n const device = await loadDevice(container, parsedParams.data.id, auth.tenantId)\n if (!device) {\n return NextResponse.json({ error: translate('devices.errors.not_found', 'Device not found') }, { status: 404 })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n if (!isOrganizationReadAccessAllowed({ scope, auth, organizationId: device.organizationId ?? null })) {\n return NextResponse.json({ error: translate('devices.errors.forbidden', 'Access denied') }, { status: 403 })\n }\n const mctx: DeviceMutationContext = {\n container,\n auth,\n scope,\n organizationId: device.organizationId ?? null,\n actorUserId,\n request: req,\n }\n return await executeDeactivate(mctx, device)\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n logger.error('devices.admin.DELETE failed', { err })\n return NextResponse.json({ error: translate('devices.errors.delete_failed', 'Failed to delete device') }, { status: 500 })\n }\n}\n\nconst okResponseSchema = z.object({ ok: z.literal(true), id: z.string().uuid().optional() })\nconst errorResponseSchema = z.object({ error: z.string() })\nconst detailResponseSchema = z.object({\n item: z.object({\n id: z.string().uuid(),\n user_id: z.string().uuid(),\n device_id: z.string(),\n platform: z.enum(['ios', 'android', 'web']),\n client_app_version: z.string().nullable(),\n os_version: z.string().nullable(),\n push_provider: z.string().nullable(),\n push_token_updated_at: z.string().nullable(),\n last_seen_at: z.string().nullable(),\n created_at: z.string().nullable(),\n updated_at: z.string().nullable(),\n }),\n})\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Devices (admin)',\n summary: 'Admin: read, update or deactivate any device in the tenant',\n methods: {\n GET: {\n summary: 'Get any device',\n description: 'Admin: fetch a single device by id (push_token is never returned).',\n responses: [{ status: 200, description: 'Device', schema: detailResponseSchema }],\n errors: [\n { status: 400, description: 'Invalid id', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n { status: 403, description: 'Missing devices.admin', schema: errorResponseSchema },\n { status: 404, description: 'Device not found', schema: errorResponseSchema },\n ],\n },\n PUT: {\n summary: 'Update any device',\n description: 'Admin: update last-seen, app/OS metadata, and push token for any device. Set pushToken to null to clear it.',\n requestBody: { schema: updateDeviceSchema },\n responses: [{ status: 200, description: 'Device updated', schema: okResponseSchema }],\n errors: [\n { status: 400, description: 'Invalid payload or id', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n { status: 403, description: 'Missing devices.admin', schema: errorResponseSchema },\n { status: 404, description: 'Device not found', schema: errorResponseSchema },\n ],\n },\n DELETE: {\n summary: 'Deactivate any device',\n description: 'Admin: soft-delete any device in the tenant.',\n responses: [{ status: 200, description: 'Device deactivated', schema: okResponseSchema }],\n errors: [\n { status: 400, description: 'Invalid id', schema: errorResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorResponseSchema },\n { status: 403, description: 'Missing devices.admin', schema: errorResponseSchema },\n { status: 404, description: 'Device not found', schema: errorResponseSchema },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,6 @@
1
1
  import { NextResponse } from "next/server";
2
2
  import { z } from "zod";
3
3
  import { makeCrudRoute } from "@open-mercato/shared/lib/crud/factory";
4
- import { toHeaderLabel } from "@open-mercato/shared/lib/crud/exporters";
5
4
  import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
6
5
  import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
7
6
  import { resolveOrganizationScopeForRequest } from "@open-mercato/core/modules/directory/utils/organizationScope";
@@ -19,14 +18,7 @@ import {
19
18
  } from "../../../data/validators.js";
20
19
  import { resolveDeviceActorUserId } from "../../auth.js";
21
20
  import { createDevicesCrudOpenApi, createPagedListResponseSchema } from "../../openapi.js";
22
- import {
23
- deviceListSchema,
24
- deviceListFields,
25
- deviceListSortFieldMap,
26
- deviceListItemSchema,
27
- deviceExportColumnFields,
28
- transformDeviceListItem
29
- } from "../../deviceList.js";
21
+ import { deviceListSchema, deviceListFields, deviceListSortFieldMap, deviceListItemSchema } from "../../deviceList.js";
30
22
  import { executeRegister } from "../../deviceOps.js";
31
23
  const logger = createLogger("devices");
32
24
  const routeMetadata = {
@@ -54,11 +46,6 @@ const crud = makeCrudRoute({
54
46
  entityId: E.devices.user_device,
55
47
  fields: deviceListFields,
56
48
  sortFieldMap: deviceListSortFieldMap,
57
- // The query engine projects raw column names; expose them in camelCase like every other module.
58
- transformItem: transformDeviceListItem,
59
- // Without an explicit column set the factory's default export spreads each item, so the deprecated
60
- // snake_case aliases would double every column in the CSV/JSON/XML export.
61
- export: { columns: deviceExportColumnFields.map((field) => ({ field, header: toHeaderLabel(field) })) },
62
49
  // Tenant + org scope is enforced by the factory (orm.tenantField + orm.orgField); only the optional
63
50
  // userId/platform narrowing is left to do here.
64
51
  buildFilters: async (query) => {