@open-mercato/core 0.6.7-develop.6863.1.61001cf9a8 → 0.6.7

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 (1458) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/AGENTS.md +3 -3
  3. package/agentic/standalone-guide.md +0 -13
  4. package/dist/bootstrap.js +1 -16
  5. package/dist/bootstrap.js.map +2 -2
  6. package/dist/generated/entities/customer_deal_person_link/index.js +0 -2
  7. package/dist/generated/entities/customer_deal_person_link/index.js.map +2 -2
  8. package/dist/generated/entities/customer_user_invitation/index.js +0 -2
  9. package/dist/generated/entities/customer_user_invitation/index.js.map +2 -2
  10. package/dist/generated/entities/gateway_payment_operation/index.js +0 -2
  11. package/dist/generated/entities/gateway_payment_operation/index.js.map +2 -2
  12. package/dist/generated/entities/gateway_transaction/index.js +0 -2
  13. package/dist/generated/entities/gateway_transaction/index.js.map +2 -2
  14. package/dist/generated/entities/organization/index.js +0 -2
  15. package/dist/generated/entities/organization/index.js.map +2 -2
  16. package/dist/generated/entities/resources_resource/index.js +0 -2
  17. package/dist/generated/entities/resources_resource/index.js.map +2 -2
  18. package/dist/generated/entities.ids.generated.js +1 -3
  19. package/dist/generated/entities.ids.generated.js.map +2 -2
  20. package/dist/generated/entity-fields-registry.js +0 -23
  21. package/dist/generated/entity-fields-registry.js.map +2 -2
  22. package/dist/helpers/integration/salesFixtures.js +2 -31
  23. package/dist/helpers/integration/salesFixtures.js.map +2 -2
  24. package/dist/helpers/integration/salesUi.js +0 -5
  25. package/dist/helpers/integration/salesUi.js.map +2 -2
  26. package/dist/modules/api_keys/backend/api-keys/page.js +1 -2
  27. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  28. package/dist/modules/attachments/api/route.js +10 -120
  29. package/dist/modules/attachments/api/route.js.map +2 -2
  30. package/dist/modules/attachments/data/entities.js +1 -67
  31. package/dist/modules/attachments/data/entities.js.map +2 -2
  32. package/dist/modules/attachments/di.js +1 -7
  33. package/dist/modules/attachments/di.js.map +2 -2
  34. package/dist/modules/attachments/fields/attachment.js +1 -1
  35. package/dist/modules/attachments/fields/attachment.js.map +2 -2
  36. package/dist/modules/attachments/lib/drivers/index.js.map +1 -1
  37. package/dist/modules/attachments/lib/drivers/localDriver.js +6 -19
  38. package/dist/modules/attachments/lib/drivers/localDriver.js.map +2 -2
  39. package/dist/modules/attachments/lib/upload-limits.js +0 -33
  40. package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
  41. package/dist/modules/audit_logs/api/audit-logs/access/route.js +1 -5
  42. package/dist/modules/audit_logs/api/audit-logs/access/route.js.map +2 -2
  43. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js +1 -5
  44. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js.map +2 -2
  45. package/dist/modules/audit_logs/api/audit-logs/actions/route.js +1 -5
  46. package/dist/modules/audit_logs/api/audit-logs/actions/route.js.map +2 -2
  47. package/dist/modules/audit_logs/components/AccessLogsTable.js +1 -2
  48. package/dist/modules/audit_logs/components/AccessLogsTable.js.map +2 -2
  49. package/dist/modules/audit_logs/components/AuditLogsActions.js +1 -2
  50. package/dist/modules/audit_logs/components/AuditLogsActions.js.map +2 -2
  51. package/dist/modules/auth/api/admin/nav.js +4 -17
  52. package/dist/modules/auth/api/admin/nav.js.map +2 -2
  53. package/dist/modules/auth/api/profile/route.js +2 -8
  54. package/dist/modules/auth/api/profile/route.js.map +2 -2
  55. package/dist/modules/auth/api/users/route.js +19 -8
  56. package/dist/modules/auth/api/users/route.js.map +2 -2
  57. package/dist/modules/auth/backend/auth/profile/page.js.map +2 -2
  58. package/dist/modules/auth/backend/profile/change-password/page.js.map +2 -2
  59. package/dist/modules/auth/backend/roles/page.js +1 -2
  60. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  61. package/dist/modules/auth/backend/settings/page.js +9 -14
  62. package/dist/modules/auth/backend/settings/page.js.map +2 -2
  63. package/dist/modules/auth/backend/users/page.js +1 -2
  64. package/dist/modules/auth/backend/users/page.js.map +2 -2
  65. package/dist/modules/auth/cli.js +1 -1
  66. package/dist/modules/auth/cli.js.map +2 -2
  67. package/dist/modules/auth/components/UserConsentsPanel.js +9 -9
  68. package/dist/modules/auth/components/UserConsentsPanel.js.map +2 -2
  69. package/dist/modules/auth/frontend/login.js +5 -6
  70. package/dist/modules/auth/frontend/login.js.map +2 -2
  71. package/dist/modules/auth/frontend/reset.js +2 -2
  72. package/dist/modules/auth/frontend/reset.js.map +2 -2
  73. package/dist/modules/auth/lib/backendChrome.js +29 -45
  74. package/dist/modules/auth/lib/backendChrome.js.map +2 -2
  75. package/dist/modules/auth/lib/setup-app.js +2 -17
  76. package/dist/modules/auth/lib/setup-app.js.map +2 -2
  77. package/dist/modules/auth/lib/tenantAccess.js +0 -7
  78. package/dist/modules/auth/lib/tenantAccess.js.map +2 -2
  79. package/dist/modules/auth/services/rbacService.js +44 -29
  80. package/dist/modules/auth/services/rbacService.js.map +2 -2
  81. package/dist/modules/business_rules/api/rules/route.js +4 -71
  82. package/dist/modules/business_rules/api/rules/route.js.map +2 -2
  83. package/dist/modules/business_rules/backend/rules/page.js +1 -2
  84. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  85. package/dist/modules/business_rules/components/ActionBuilder.js +4 -47
  86. package/dist/modules/business_rules/components/ActionBuilder.js.map +3 -3
  87. package/dist/modules/business_rules/components/ActionRow.js +16 -106
  88. package/dist/modules/business_rules/components/ActionRow.js.map +2 -2
  89. package/dist/modules/business_rules/components/ConditionRow.js +4 -8
  90. package/dist/modules/business_rules/components/ConditionRow.js.map +2 -2
  91. package/dist/modules/business_rules/components/utils/actionValidation.js +0 -6
  92. package/dist/modules/business_rules/components/utils/actionValidation.js.map +2 -2
  93. package/dist/modules/business_rules/lib/action-executor.js +0 -148
  94. package/dist/modules/business_rules/lib/action-executor.js.map +2 -2
  95. package/dist/modules/business_rules/lib/rule-engine.js +1 -5
  96. package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
  97. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +5 -6
  98. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  99. package/dist/modules/catalog/backend/catalog/products/create/page.js +6 -7
  100. package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
  101. package/dist/modules/catalog/components/PriceKindSettings.js +3 -3
  102. package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
  103. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +1 -2
  104. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  105. package/dist/modules/catalog/components/products/ProductCategorizeSection.js +3 -3
  106. package/dist/modules/catalog/components/products/ProductCategorizeSection.js.map +2 -2
  107. package/dist/modules/catalog/components/products/ProductMediaManager.js +1 -1
  108. package/dist/modules/catalog/components/products/ProductMediaManager.js.map +2 -2
  109. package/dist/modules/catalog/components/products/ProductsDataTable.js +2 -3
  110. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  111. package/dist/modules/catalog/components/products/VariantBuilder.js +5 -5
  112. package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
  113. package/dist/modules/catalog/events.js +0 -1
  114. package/dist/modules/catalog/events.js.map +2 -2
  115. package/dist/modules/catalog/widgets/injection/product-seo/widget.js +1 -1
  116. package/dist/modules/catalog/widgets/injection/product-seo/widget.js.map +2 -2
  117. package/dist/modules/communication_channels/api/post/test-seed/route.js +2 -52
  118. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  119. package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js +1 -11
  120. package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js.map +2 -2
  121. package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js +6 -11
  122. package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js.map +2 -2
  123. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +1 -2
  124. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
  125. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +3 -4
  126. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +2 -2
  127. package/dist/modules/communication_channels/data/enrichers.js +4 -4
  128. package/dist/modules/communication_channels/data/enrichers.js.map +2 -2
  129. package/dist/modules/communication_channels/lib/access-control.js +2 -2
  130. package/dist/modules/communication_channels/lib/access-control.js.map +2 -2
  131. package/dist/modules/configs/backend/config/system-status/page.js +1 -2
  132. package/dist/modules/configs/backend/config/system-status/page.js.map +2 -2
  133. package/dist/modules/configs/lib/upgrade-actions.js +0 -12
  134. package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
  135. package/dist/modules/currencies/backend/currencies/page.js +1 -2
  136. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  137. package/dist/modules/currencies/backend/exchange-rates/page.js +1 -2
  138. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  139. package/dist/modules/currencies/di.js +0 -4
  140. package/dist/modules/currencies/di.js.map +2 -2
  141. package/dist/modules/customer_accounts/api/admin/users/[id].js +1 -10
  142. package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
  143. package/dist/modules/customer_accounts/api/admin/users-invite.js +4 -63
  144. package/dist/modules/customer_accounts/api/admin/users-invite.js.map +2 -2
  145. package/dist/modules/customer_accounts/api/invitations/accept.js +2 -1
  146. package/dist/modules/customer_accounts/api/invitations/accept.js.map +2 -2
  147. package/dist/modules/customer_accounts/api/login.js +2 -4
  148. package/dist/modules/customer_accounts/api/login.js.map +2 -2
  149. package/dist/modules/customer_accounts/api/magic-link/verify.js +2 -4
  150. package/dist/modules/customer_accounts/api/magic-link/verify.js.map +2 -2
  151. package/dist/modules/customer_accounts/api/portal/feature-check.js +4 -5
  152. package/dist/modules/customer_accounts/api/portal/feature-check.js.map +2 -2
  153. package/dist/modules/customer_accounts/api/portal/nav.js +4 -6
  154. package/dist/modules/customer_accounts/api/portal/nav.js.map +2 -2
  155. package/dist/modules/customer_accounts/api/portal/profile.js +1 -5
  156. package/dist/modules/customer_accounts/api/portal/profile.js.map +2 -2
  157. package/dist/modules/customer_accounts/api/portal/sessions-refresh.js +3 -3
  158. package/dist/modules/customer_accounts/api/portal/sessions-refresh.js.map +2 -2
  159. package/dist/modules/customer_accounts/api/portal/users-invite.js +2 -22
  160. package/dist/modules/customer_accounts/api/portal/users-invite.js.map +2 -2
  161. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +1 -2
  162. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  163. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +1 -2
  164. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  165. package/dist/modules/customer_accounts/data/entities.js +0 -3
  166. package/dist/modules/customer_accounts/data/entities.js.map +2 -2
  167. package/dist/modules/customer_accounts/data/validators.js +0 -1
  168. package/dist/modules/customer_accounts/data/validators.js.map +2 -2
  169. package/dist/modules/customer_accounts/lib/customerAuth.js +2 -7
  170. package/dist/modules/customer_accounts/lib/customerAuth.js.map +2 -2
  171. package/dist/modules/customer_accounts/lib/customerAuthServer.js +1 -2
  172. package/dist/modules/customer_accounts/lib/customerAuthServer.js.map +2 -2
  173. package/dist/modules/customer_accounts/lib/customerEntityOwnership.js +3 -29
  174. package/dist/modules/customer_accounts/lib/customerEntityOwnership.js.map +2 -2
  175. package/dist/modules/customer_accounts/lib/customerUrl.js +10 -19
  176. package/dist/modules/customer_accounts/lib/customerUrl.js.map +2 -2
  177. package/dist/modules/customer_accounts/services/customerInvitationService.js +2 -32
  178. package/dist/modules/customer_accounts/services/customerInvitationService.js.map +2 -2
  179. package/dist/modules/customer_accounts/services/customerRbacService.js +3 -12
  180. package/dist/modules/customer_accounts/services/customerRbacService.js.map +2 -2
  181. package/dist/modules/customer_accounts/setup.js +0 -6
  182. package/dist/modules/customer_accounts/setup.js.map +2 -2
  183. package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js +7 -47
  184. package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js.map +2 -2
  185. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +2 -2
  186. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
  187. package/dist/modules/customer_accounts/widgets/injection/portal-ai-assistant-trigger/widget.client.js +1 -1
  188. package/dist/modules/customer_accounts/widgets/injection/portal-ai-assistant-trigger/widget.client.js.map +2 -2
  189. package/dist/modules/customer_accounts/widgets/injection-table.js +1 -1
  190. package/dist/modules/customer_accounts/widgets/injection-table.js.map +2 -2
  191. package/dist/modules/customers/analytics.js +1 -4
  192. package/dist/modules/customers/analytics.js.map +2 -2
  193. package/dist/modules/customers/api/companies/[id]/route.js +4 -3
  194. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  195. package/dist/modules/customers/api/deals/[id]/people/route.js +2 -4
  196. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  197. package/dist/modules/customers/api/deals/[id]/route.js +3 -7
  198. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  199. package/dist/modules/customers/api/deals/aggregate/route.js +4 -5
  200. package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
  201. package/dist/modules/customers/api/deals/summary/route.js +119 -14
  202. package/dist/modules/customers/api/deals/summary/route.js.map +2 -2
  203. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +2 -3
  204. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
  205. package/dist/modules/customers/api/utils.js +18 -12
  206. package/dist/modules/customers/api/utils.js.map +2 -2
  207. package/dist/modules/customers/backend/customers/companies/[id]/page.js +1 -2
  208. package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
  209. package/dist/modules/customers/backend/customers/companies/page.js +1 -2
  210. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  211. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +5 -16
  212. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  213. package/dist/modules/customers/backend/customers/deals/[id]/page.js +11 -18
  214. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  215. package/dist/modules/customers/backend/customers/deals/page.js +1 -2
  216. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  217. package/dist/modules/customers/backend/customers/deals/pipeline/components/QuickDealDialog.js +3 -17
  218. package/dist/modules/customers/backend/customers/deals/pipeline/components/QuickDealDialog.js.map +2 -2
  219. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +1 -7
  220. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  221. package/dist/modules/customers/backend/customers/people/[id]/page.js +1 -2
  222. package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
  223. package/dist/modules/customers/backend/customers/people/page.js +1 -2
  224. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  225. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +10 -26
  226. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  227. package/dist/modules/customers/cli.js +11 -28
  228. package/dist/modules/customers/cli.js.map +2 -2
  229. package/dist/modules/customers/commands/deals.js +10 -48
  230. package/dist/modules/customers/commands/deals.js.map +2 -2
  231. package/dist/modules/customers/commands/people.js +0 -2
  232. package/dist/modules/customers/commands/people.js.map +2 -2
  233. package/dist/modules/customers/components/CustomerTodosTable.js +1 -2
  234. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  235. package/dist/modules/customers/components/detail/ActiveDealCard.js +1 -2
  236. package/dist/modules/customers/components/detail/ActiveDealCard.js.map +2 -2
  237. package/dist/modules/customers/components/detail/ActivitiesDayStrip.js +3 -2
  238. package/dist/modules/customers/components/detail/ActivitiesDayStrip.js.map +2 -2
  239. package/dist/modules/customers/components/detail/CompanyDetailTabs.js +6 -26
  240. package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +2 -2
  241. package/dist/modules/customers/components/detail/CompanyKpiBar.js +5 -6
  242. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
  243. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +1 -1
  244. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +1 -1
  245. package/dist/modules/customers/components/detail/DealDetailTabs.js +8 -30
  246. package/dist/modules/customers/components/detail/DealDetailTabs.js.map +2 -2
  247. package/dist/modules/customers/components/detail/DealForm.js +1 -2
  248. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  249. package/dist/modules/customers/components/detail/DealsSection.js +1 -1
  250. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  251. package/dist/modules/customers/components/detail/PersonDetailTabs.js +8 -30
  252. package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
  253. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +216 -231
  254. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
  255. package/dist/modules/customers/components/detail/dashboard/helpers.js +3 -4
  256. package/dist/modules/customers/components/detail/dashboard/helpers.js.map +2 -2
  257. package/dist/modules/customers/components/formConfig.js +10 -14
  258. package/dist/modules/customers/components/formConfig.js.map +2 -2
  259. package/dist/modules/customers/data/entities.js +0 -8
  260. package/dist/modules/customers/data/entities.js.map +2 -2
  261. package/dist/modules/customers/data/validators.js +2 -5
  262. package/dist/modules/customers/data/validators.js.map +2 -2
  263. package/dist/modules/customers/lib/calendar/format.js +4 -8
  264. package/dist/modules/customers/lib/calendar/format.js.map +2 -2
  265. package/dist/modules/customers/lib/visibilityFilter.js +4 -6
  266. package/dist/modules/customers/lib/visibilityFilter.js.map +2 -2
  267. package/dist/modules/customers/search.js +29 -50
  268. package/dist/modules/customers/search.js.map +2 -2
  269. package/dist/modules/dashboards/api/layout/[itemId]/route.js +3 -6
  270. package/dist/modules/dashboards/api/layout/[itemId]/route.js.map +2 -2
  271. package/dist/modules/dashboards/api/layout/route.js +9 -22
  272. package/dist/modules/dashboards/api/layout/route.js.map +2 -2
  273. package/dist/modules/dashboards/api/roles/widgets/route.js +3 -9
  274. package/dist/modules/dashboards/api/roles/widgets/route.js.map +2 -2
  275. package/dist/modules/dashboards/api/users/widgets/route.js +3 -9
  276. package/dist/modules/dashboards/api/users/widgets/route.js.map +2 -2
  277. package/dist/modules/dashboards/api/widgets/catalog.js +3 -6
  278. package/dist/modules/dashboards/api/widgets/catalog.js.map +2 -2
  279. package/dist/modules/dashboards/api/widgets/data/batch/route.js +3 -12
  280. package/dist/modules/dashboards/api/widgets/data/batch/route.js.map +2 -2
  281. package/dist/modules/dashboards/api/widgets/data/route.js +3 -28
  282. package/dist/modules/dashboards/api/widgets/data/route.js.map +2 -2
  283. package/dist/modules/dashboards/api/widgets/data/schema.js +18 -28
  284. package/dist/modules/dashboards/api/widgets/data/schema.js.map +2 -2
  285. package/dist/modules/dashboards/lib/access.js +3 -5
  286. package/dist/modules/dashboards/lib/access.js.map +2 -2
  287. package/dist/modules/dashboards/lib/aggregations.js +46 -113
  288. package/dist/modules/dashboards/lib/aggregations.js.map +2 -2
  289. package/dist/modules/dashboards/lib/formatters.js +11 -84
  290. package/dist/modules/dashboards/lib/formatters.js.map +2 -2
  291. package/dist/modules/dashboards/services/widgetDataService.js +14 -316
  292. package/dist/modules/dashboards/services/widgetDataService.js.map +2 -2
  293. package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.js +3 -9
  294. package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.js.map +2 -2
  295. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/config.js +2 -52
  296. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/config.js.map +2 -2
  297. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.js +30 -52
  298. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.js.map +2 -2
  299. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js +2 -2
  300. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js.map +2 -2
  301. package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.js +3 -9
  302. package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.js.map +2 -2
  303. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js +3 -8
  304. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js.map +2 -2
  305. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js +18 -26
  306. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js.map +2 -2
  307. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js +14 -22
  308. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js.map +2 -2
  309. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js +4 -10
  310. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js.map +2 -2
  311. package/dist/modules/data_sync/api/mappings/[id]/route.js +9 -22
  312. package/dist/modules/data_sync/api/mappings/[id]/route.js.map +2 -2
  313. package/dist/modules/data_sync/api/mappings/route.js +4 -13
  314. package/dist/modules/data_sync/api/mappings/route.js.map +2 -2
  315. package/dist/modules/data_sync/api/options.js +2 -7
  316. package/dist/modules/data_sync/api/options.js.map +2 -2
  317. package/dist/modules/data_sync/api/run.js +2 -7
  318. package/dist/modules/data_sync/api/run.js.map +2 -2
  319. package/dist/modules/data_sync/api/runs/[id]/cancel.js +3 -8
  320. package/dist/modules/data_sync/api/runs/[id]/cancel.js.map +2 -2
  321. package/dist/modules/data_sync/api/runs/[id]/retry.js +2 -7
  322. package/dist/modules/data_sync/api/runs/[id]/retry.js.map +2 -2
  323. package/dist/modules/data_sync/api/runs/[id]/route.js +3 -8
  324. package/dist/modules/data_sync/api/runs/[id]/route.js.map +2 -2
  325. package/dist/modules/data_sync/api/runs.js +2 -7
  326. package/dist/modules/data_sync/api/runs.js.map +2 -2
  327. package/dist/modules/data_sync/api/schedules/[id]/route.js +6 -19
  328. package/dist/modules/data_sync/api/schedules/[id]/route.js.map +2 -2
  329. package/dist/modules/data_sync/api/schedules/route.js +4 -13
  330. package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
  331. package/dist/modules/data_sync/api/validate.js +4 -9
  332. package/dist/modules/data_sync/api/validate.js.map +2 -2
  333. package/dist/modules/data_sync/backend/data-sync/page.js +1 -2
  334. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  335. package/dist/modules/data_sync/lib/queue.js +1 -16
  336. package/dist/modules/data_sync/lib/queue.js.map +2 -2
  337. package/dist/modules/data_sync/lib/start-run.js +1 -2
  338. package/dist/modules/data_sync/lib/start-run.js.map +2 -2
  339. package/dist/modules/data_sync/lib/sync-engine.js +2 -35
  340. package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
  341. package/dist/modules/data_sync/lib/sync-run-service.js +2 -70
  342. package/dist/modules/data_sync/lib/sync-run-service.js.map +2 -2
  343. package/dist/modules/data_sync/workers/sync-export.js +2 -9
  344. package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
  345. package/dist/modules/data_sync/workers/sync-import.js +2 -9
  346. package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
  347. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +12 -34
  348. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
  349. package/dist/modules/dictionaries/api/openapi.js +2 -15
  350. package/dist/modules/dictionaries/api/openapi.js.map +2 -2
  351. package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +1 -1
  352. package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +2 -2
  353. package/dist/modules/dictionaries/components/hooks/useDictionaryEntries.js +29 -30
  354. package/dist/modules/dictionaries/components/hooks/useDictionaryEntries.js.map +2 -2
  355. package/dist/modules/dictionaries/data/validators.js +0 -7
  356. package/dist/modules/dictionaries/data/validators.js.map +2 -2
  357. package/dist/modules/dictionaries/lib/clientEntries.js +3 -4
  358. package/dist/modules/dictionaries/lib/clientEntries.js.map +2 -2
  359. package/dist/modules/directory/api/organization-branding/route.js +3 -10
  360. package/dist/modules/directory/api/organization-branding/route.js.map +2 -2
  361. package/dist/modules/directory/api/organization-switcher/route.js +20 -84
  362. package/dist/modules/directory/api/organization-switcher/route.js.map +2 -2
  363. package/dist/modules/directory/api/organizations/route.js +0 -7
  364. package/dist/modules/directory/api/organizations/route.js.map +3 -3
  365. package/dist/modules/directory/api/tenants/route.js +2 -8
  366. package/dist/modules/directory/api/tenants/route.js.map +2 -2
  367. package/dist/modules/directory/backend/directory/branding/page.js +8 -31
  368. package/dist/modules/directory/backend/directory/branding/page.js.map +2 -2
  369. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +16 -7
  370. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
  371. package/dist/modules/directory/backend/directory/organizations/page.js +1 -2
  372. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  373. package/dist/modules/directory/backend/directory/tenants/page.js +1 -2
  374. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  375. package/dist/modules/directory/commands/organizations.js +1 -8
  376. package/dist/modules/directory/commands/organizations.js.map +2 -2
  377. package/dist/modules/directory/commands/tenants.js +0 -6
  378. package/dist/modules/directory/commands/tenants.js.map +2 -2
  379. package/dist/modules/directory/data/entities.js +0 -4
  380. package/dist/modules/directory/data/entities.js.map +2 -2
  381. package/dist/modules/directory/data/validators.js +0 -2
  382. package/dist/modules/directory/data/validators.js.map +2 -2
  383. package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js +1 -5
  384. package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js.map +2 -2
  385. package/dist/modules/directory/utils/organizationScope.js +3 -11
  386. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  387. package/dist/modules/entities/api/definitions.js +3 -53
  388. package/dist/modules/entities/api/definitions.js.map +2 -2
  389. package/dist/modules/entities/api/entities.js +2 -21
  390. package/dist/modules/entities/api/entities.js.map +2 -2
  391. package/dist/modules/entities/api/entity-settings.js +9 -59
  392. package/dist/modules/entities/api/entity-settings.js.map +2 -2
  393. package/dist/modules/entities/api/records.js +24 -3
  394. package/dist/modules/entities/api/records.js.map +2 -2
  395. package/dist/modules/entities/api/relations/options.js +16 -11
  396. package/dist/modules/entities/api/relations/options.js.map +2 -2
  397. package/dist/modules/entities/api/sidebar-entities.js +12 -34
  398. package/dist/modules/entities/api/sidebar-entities.js.map +2 -2
  399. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +4 -23
  400. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  401. package/dist/modules/entities/backend/entities/user/create/page.js +7 -16
  402. package/dist/modules/entities/backend/entities/user/create/page.js.map +2 -2
  403. package/dist/modules/entities/cli.js +19 -193
  404. package/dist/modules/entities/cli.js.map +2 -2
  405. package/dist/modules/entities/components/SystemEntitiesTable.js +1 -2
  406. package/dist/modules/entities/components/SystemEntitiesTable.js.map +2 -2
  407. package/dist/modules/entities/components/UserEntitiesTable.js +1 -2
  408. package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
  409. package/dist/modules/entities/lib/entityAcl.js +9 -87
  410. package/dist/modules/entities/lib/entityAcl.js.map +3 -3
  411. package/dist/modules/feature_toggles/components/FeatureGuard.js +2 -3
  412. package/dist/modules/feature_toggles/components/FeatureGuard.js.map +2 -2
  413. package/dist/modules/feature_toggles/components/hooks/useFeatureFlagBoolean.js +2 -5
  414. package/dist/modules/feature_toggles/components/hooks/useFeatureFlagBoolean.js.map +2 -2
  415. package/dist/modules/feature_toggles/components/hooks/useFeatureFlagJson.js +2 -5
  416. package/dist/modules/feature_toggles/components/hooks/useFeatureFlagJson.js.map +2 -2
  417. package/dist/modules/feature_toggles/components/hooks/useFeatureFlagNumber.js +2 -5
  418. package/dist/modules/feature_toggles/components/hooks/useFeatureFlagNumber.js.map +2 -2
  419. package/dist/modules/feature_toggles/components/hooks/useFeatureFlagString.js +2 -5
  420. package/dist/modules/feature_toggles/components/hooks/useFeatureFlagString.js.map +2 -2
  421. package/dist/modules/inbox_ops/ai-tools.js +2 -5
  422. package/dist/modules/inbox_ops/ai-tools.js.map +2 -2
  423. package/dist/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.js +1 -14
  424. package/dist/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.js.map +2 -2
  425. package/dist/modules/inbox_ops/api/proposals/route.js +1 -16
  426. package/dist/modules/inbox_ops/api/proposals/route.js.map +2 -2
  427. package/dist/modules/inbox_ops/api/webhook/inbound.js +10 -14
  428. package/dist/modules/inbox_ops/api/webhook/inbound.js.map +2 -2
  429. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +6 -6
  430. package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
  431. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +20 -25
  432. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
  433. package/dist/modules/inbox_ops/search.js +4 -15
  434. package/dist/modules/inbox_ops/search.js.map +2 -2
  435. package/dist/modules/integrations/api/[id]/credentials/route.js +5 -11
  436. package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
  437. package/dist/modules/integrations/api/[id]/health/route.js +3 -6
  438. package/dist/modules/integrations/api/[id]/health/route.js.map +2 -2
  439. package/dist/modules/integrations/api/[id]/route.js +3 -6
  440. package/dist/modules/integrations/api/[id]/route.js.map +2 -2
  441. package/dist/modules/integrations/api/[id]/state/route.js +3 -6
  442. package/dist/modules/integrations/api/[id]/state/route.js.map +2 -2
  443. package/dist/modules/integrations/api/[id]/version/route.js +3 -6
  444. package/dist/modules/integrations/api/[id]/version/route.js.map +2 -2
  445. package/dist/modules/integrations/api/logs/route.js +3 -6
  446. package/dist/modules/integrations/api/logs/route.js.map +2 -2
  447. package/dist/modules/integrations/api/route.js +3 -6
  448. package/dist/modules/integrations/api/route.js.map +2 -2
  449. package/dist/modules/integrations/api/umes-read.js +2 -2
  450. package/dist/modules/integrations/api/umes-read.js.map +2 -2
  451. package/dist/modules/integrations/backend/integrations/[id]/page.js +4 -2
  452. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  453. package/dist/modules/integrations/lib/organization-scope.js +9 -2
  454. package/dist/modules/integrations/lib/organization-scope.js.map +2 -2
  455. package/dist/modules/integrations/widgets/injection/external-ids/widget.client.js +5 -0
  456. package/dist/modules/integrations/widgets/injection/external-ids/widget.client.js.map +2 -2
  457. package/dist/modules/messages/api/[id]/route.js +0 -15
  458. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  459. package/dist/modules/messages/api/route.js +8 -77
  460. package/dist/modules/messages/api/route.js.map +2 -2
  461. package/dist/modules/messages/components/ComposeMessagePageClient.js +1 -2
  462. package/dist/modules/messages/components/ComposeMessagePageClient.js.map +2 -2
  463. package/dist/modules/messages/components/MessageDetailPageClient.js +2 -3
  464. package/dist/modules/messages/components/MessageDetailPageClient.js.map +2 -2
  465. package/dist/modules/messages/components/MessagesInboxPageClient.js +1 -2
  466. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  467. package/dist/modules/messages/components/message-detail/panels/dialogs.js +1 -1
  468. package/dist/modules/messages/components/message-detail/panels/dialogs.js.map +1 -1
  469. package/dist/modules/messages/lib/routeHelpers.js +3 -1
  470. package/dist/modules/messages/lib/routeHelpers.js.map +2 -2
  471. package/dist/modules/messages/lib/searchLookup.js +16 -8
  472. package/dist/modules/messages/lib/searchLookup.js.map +2 -2
  473. package/dist/modules/messages/search.js +5 -10
  474. package/dist/modules/messages/search.js.map +2 -2
  475. package/dist/modules/notifications/api/route.js +4 -83
  476. package/dist/modules/notifications/api/route.js.map +2 -2
  477. package/dist/modules/notifications/api/unread-count/route.js +6 -25
  478. package/dist/modules/notifications/api/unread-count/route.js.map +2 -2
  479. package/dist/modules/notifications/di.js +1 -1
  480. package/dist/modules/notifications/di.js.map +2 -2
  481. package/dist/modules/notifications/events.js +2 -4
  482. package/dist/modules/notifications/events.js.map +2 -2
  483. package/dist/modules/notifications/lib/notificationRecipients.js +7 -6
  484. package/dist/modules/notifications/lib/notificationRecipients.js.map +2 -2
  485. package/dist/modules/notifications/lib/notificationService.js +4 -48
  486. package/dist/modules/notifications/lib/notificationService.js.map +2 -2
  487. package/dist/modules/notifications/lib/routeHelpers.js +2 -16
  488. package/dist/modules/notifications/lib/routeHelpers.js.map +2 -2
  489. package/dist/modules/payment_gateways/api/capture/route.js +1 -1
  490. package/dist/modules/payment_gateways/api/capture/route.js.map +2 -2
  491. package/dist/modules/payment_gateways/api/sessions/route.js +3 -6
  492. package/dist/modules/payment_gateways/api/sessions/route.js.map +2 -2
  493. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +1 -11
  494. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
  495. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +2 -3
  496. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  497. package/dist/modules/payment_gateways/data/entities.js +0 -11
  498. package/dist/modules/payment_gateways/data/entities.js.map +2 -2
  499. package/dist/modules/payment_gateways/di.js +1 -17
  500. package/dist/modules/payment_gateways/di.js.map +2 -2
  501. package/dist/modules/payment_gateways/lib/gateway-service.js +14 -93
  502. package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
  503. package/dist/modules/payment_gateways/lib/payment-operation-idempotency.js +0 -1
  504. package/dist/modules/payment_gateways/lib/payment-operation-idempotency.js.map +2 -2
  505. package/dist/modules/payment_gateways/lib/session-idempotency.js +0 -33
  506. package/dist/modules/payment_gateways/lib/session-idempotency.js.map +2 -2
  507. package/dist/modules/payment_gateways/setup.js +0 -47
  508. package/dist/modules/payment_gateways/setup.js.map +2 -2
  509. package/dist/modules/planner/components/AvailabilityRulesEditor.js +4 -4
  510. package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
  511. package/dist/modules/planner/components/unavailabilityReasons.js +3 -3
  512. package/dist/modules/planner/components/unavailabilityReasons.js.map +2 -2
  513. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js +3 -3
  514. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js.map +2 -2
  515. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +3 -3
  516. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
  517. package/dist/modules/portal/frontend/[orgSlug]/portal/page.js +3 -3
  518. package/dist/modules/portal/frontend/[orgSlug]/portal/page.js.map +2 -2
  519. package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js +3 -3
  520. package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js.map +2 -2
  521. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +3 -3
  522. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +2 -2
  523. package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js +3 -3
  524. package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js.map +2 -2
  525. package/dist/modules/progress/lib/progressService.js +0 -2
  526. package/dist/modules/progress/lib/progressService.js.map +2 -2
  527. package/dist/modules/progress/lib/progressServiceImpl.js +104 -322
  528. package/dist/modules/progress/lib/progressServiceImpl.js.map +2 -2
  529. package/dist/modules/query_index/api/openapi.js +1 -13
  530. package/dist/modules/query_index/api/openapi.js.map +2 -2
  531. package/dist/modules/query_index/api/reindex.js +0 -10
  532. package/dist/modules/query_index/api/reindex.js.map +2 -2
  533. package/dist/modules/query_index/api/status.js +105 -165
  534. package/dist/modules/query_index/api/status.js.map +2 -2
  535. package/dist/modules/query_index/cli.js +1 -125
  536. package/dist/modules/query_index/cli.js.map +2 -2
  537. package/dist/modules/query_index/components/QueryIndexesTable.js +42 -130
  538. package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
  539. package/dist/modules/query_index/data/entities.js +1 -2
  540. package/dist/modules/query_index/data/entities.js.map +2 -2
  541. package/dist/modules/query_index/di.js +0 -3
  542. package/dist/modules/query_index/di.js.map +2 -2
  543. package/dist/modules/query_index/lib/batch.js +4 -11
  544. package/dist/modules/query_index/lib/batch.js.map +2 -2
  545. package/dist/modules/query_index/lib/coverage.js +9 -21
  546. package/dist/modules/query_index/lib/coverage.js.map +2 -2
  547. package/dist/modules/query_index/lib/document.js +5 -12
  548. package/dist/modules/query_index/lib/document.js.map +2 -2
  549. package/dist/modules/query_index/lib/engine.js +48 -105
  550. package/dist/modules/query_index/lib/engine.js.map +2 -2
  551. package/dist/modules/query_index/lib/indexer.js +19 -95
  552. package/dist/modules/query_index/lib/indexer.js.map +2 -2
  553. package/dist/modules/query_index/lib/reindexer.js +37 -43
  554. package/dist/modules/query_index/lib/reindexer.js.map +2 -2
  555. package/dist/modules/query_index/lib/search-tokens.js +15 -34
  556. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  557. package/dist/modules/query_index/lib/subscriber-scope.js +3 -2
  558. package/dist/modules/query_index/lib/subscriber-scope.js.map +2 -2
  559. package/dist/modules/query_index/subscribers/coverage_refresh.js +0 -4
  560. package/dist/modules/query_index/subscribers/coverage_refresh.js.map +2 -2
  561. package/dist/modules/query_index/subscribers/delete_one.js +1 -53
  562. package/dist/modules/query_index/subscribers/delete_one.js.map +3 -3
  563. package/dist/modules/query_index/subscribers/upsert_one.js +0 -60
  564. package/dist/modules/query_index/subscribers/upsert_one.js.map +3 -3
  565. package/dist/modules/resources/api/resources.js +0 -2
  566. package/dist/modules/resources/api/resources.js.map +2 -2
  567. package/dist/modules/resources/backend/resources/resource-types/page.js +1 -2
  568. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  569. package/dist/modules/resources/backend/resources/resources/[id]/page.js +2 -3
  570. package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
  571. package/dist/modules/resources/backend/resources/resources/page.js +1 -2
  572. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  573. package/dist/modules/resources/commands/resources.js +0 -9
  574. package/dist/modules/resources/commands/resources.js.map +2 -2
  575. package/dist/modules/resources/components/detail/dictionaries.js +3 -3
  576. package/dist/modules/resources/components/detail/dictionaries.js.map +2 -2
  577. package/dist/modules/resources/data/entities.js +0 -3
  578. package/dist/modules/resources/data/entities.js.map +2 -2
  579. package/dist/modules/resources/data/validators.js +2 -6
  580. package/dist/modules/resources/data/validators.js.map +2 -2
  581. package/dist/modules/resources/lib/seeds.js +9 -16
  582. package/dist/modules/resources/lib/seeds.js.map +2 -2
  583. package/dist/modules/sales/analytics.js +3 -7
  584. package/dist/modules/sales/analytics.js.map +2 -2
  585. package/dist/modules/sales/api/document-history/route.js +1 -2
  586. package/dist/modules/sales/api/document-history/route.js.map +2 -2
  587. package/dist/modules/sales/api/documents/factory.js +3 -14
  588. package/dist/modules/sales/api/documents/factory.js.map +2 -2
  589. package/dist/modules/sales/backend/sales/documents/[id]/page.js +3 -11
  590. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  591. package/dist/modules/sales/backend/sales/documents/create/page.js +14 -11
  592. package/dist/modules/sales/backend/sales/documents/create/page.js.map +2 -2
  593. package/dist/modules/sales/commands/documents.js +23 -184
  594. package/dist/modules/sales/commands/documents.js.map +2 -2
  595. package/dist/modules/sales/components/documents/ItemsSection.js +10 -20
  596. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  597. package/dist/modules/sales/components/documents/LineItemDialog.js +5 -12
  598. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  599. package/dist/modules/sales/components/documents/SalesDocumentForm.js +2 -48
  600. package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
  601. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +1 -4
  602. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  603. package/dist/modules/sales/components/useSalesChannelsEnabled.js +35 -2
  604. package/dist/modules/sales/components/useSalesChannelsEnabled.js.map +2 -2
  605. package/dist/modules/sales/data/validators.js +5 -32
  606. package/dist/modules/sales/data/validators.js.map +2 -2
  607. package/dist/modules/sales/di.js +0 -7
  608. package/dist/modules/sales/di.js.map +2 -2
  609. package/dist/modules/sales/events.js +0 -1
  610. package/dist/modules/sales/events.js.map +2 -2
  611. package/dist/modules/sales/lib/historyHelpers.js +1 -69
  612. package/dist/modules/sales/lib/historyHelpers.js.map +2 -2
  613. package/dist/modules/sales/widgets/injection/document-history/widget.client.js +2 -51
  614. package/dist/modules/sales/widgets/injection/document-history/widget.client.js.map +2 -2
  615. package/dist/modules/sales/workflows.js +7 -10
  616. package/dist/modules/sales/workflows.js.map +2 -2
  617. package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js +1 -11
  618. package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js.map +2 -2
  619. package/dist/modules/shipping_carriers/lib/shipment-wizard/components/PackageEditor.js +1 -1
  620. package/dist/modules/shipping_carriers/lib/shipment-wizard/components/PackageEditor.js.map +1 -1
  621. package/dist/modules/staff/api/interceptors.js +3 -5
  622. package/dist/modules/staff/api/interceptors.js.map +2 -2
  623. package/dist/modules/staff/api/leave-requests.js +42 -45
  624. package/dist/modules/staff/api/leave-requests.js.map +2 -2
  625. package/dist/modules/staff/components/detail/dictionaries.js +3 -3
  626. package/dist/modules/staff/components/detail/dictionaries.js.map +2 -2
  627. package/dist/modules/sync_excel/api/upload/route.js +2 -15
  628. package/dist/modules/sync_excel/api/upload/route.js.map +2 -2
  629. package/dist/modules/wms/components/backend/ReleaseReservationDialog.js +1 -1
  630. package/dist/modules/wms/components/backend/ReleaseReservationDialog.js.map +1 -1
  631. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +4 -5
  632. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +2 -2
  633. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +3 -4
  634. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
  635. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +2 -3
  636. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  637. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +2 -3
  638. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  639. package/dist/modules/wms/components/backend/WmsLotsListPage.js +1 -2
  640. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
  641. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +2 -3
  642. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  643. package/dist/modules/workflows/backend/definitions/page.js +2 -3
  644. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  645. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +3 -6
  646. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  647. package/dist/modules/workflows/backend/instances/page.js +9 -10
  648. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  649. package/dist/modules/workflows/backend/tasks/page.js +7 -8
  650. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  651. package/dist/modules/workflows/components/ActivitiesEditor.js +13 -69
  652. package/dist/modules/workflows/components/ActivitiesEditor.js.map +2 -2
  653. package/dist/modules/workflows/components/BusinessRulesSelector.js +1 -1
  654. package/dist/modules/workflows/components/BusinessRulesSelector.js.map +2 -2
  655. package/dist/modules/workflows/components/DefinitionTriggersEditor.js +2 -2
  656. package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +2 -2
  657. package/dist/modules/workflows/components/EdgeEditDialogCrudForm.js +2 -1
  658. package/dist/modules/workflows/components/EdgeEditDialogCrudForm.js.map +2 -2
  659. package/dist/modules/workflows/components/NodeEditDialogCrudForm.js +2 -1
  660. package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +2 -2
  661. package/dist/modules/workflows/components/StepsEditor.js +2 -2
  662. package/dist/modules/workflows/components/StepsEditor.js.map +2 -2
  663. package/dist/modules/workflows/components/TransitionsEditor.js +165 -207
  664. package/dist/modules/workflows/components/TransitionsEditor.js.map +2 -2
  665. package/dist/modules/workflows/components/WorkflowLegend.js +1 -1
  666. package/dist/modules/workflows/components/WorkflowLegend.js.map +2 -2
  667. package/dist/modules/workflows/components/WorkflowSelector.js +1 -1
  668. package/dist/modules/workflows/components/WorkflowSelector.js.map +2 -2
  669. package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js +1 -1
  670. package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js.map +2 -2
  671. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +1 -1
  672. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +2 -2
  673. package/dist/modules/workflows/components/fields/MappingArrayEditor.js +1 -1
  674. package/dist/modules/workflows/components/fields/MappingArrayEditor.js.map +2 -2
  675. package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js +1 -1
  676. package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js.map +2 -2
  677. package/dist/modules/workflows/components/fields/WorkflowSelectorField.js +4 -4
  678. package/dist/modules/workflows/components/fields/WorkflowSelectorField.js.map +2 -2
  679. package/dist/modules/workflows/data/validators.js +1 -34
  680. package/dist/modules/workflows/data/validators.js.map +3 -3
  681. package/dist/modules/workflows/events.js +0 -1
  682. package/dist/modules/workflows/events.js.map +2 -2
  683. package/dist/modules/workflows/lib/activity-executor.js +14 -59
  684. package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
  685. package/dist/modules/workflows/lib/format-validation-error.js +1 -46
  686. package/dist/modules/workflows/lib/format-validation-error.js.map +2 -2
  687. package/dist/modules/workflows/widgets/injection/order-approval/widget.client.js +10 -21
  688. package/dist/modules/workflows/widgets/injection/order-approval/widget.client.js.map +2 -2
  689. package/generated/entities/customer_deal_person_link/index.ts +0 -1
  690. package/generated/entities/customer_user_invitation/index.ts +0 -1
  691. package/generated/entities/gateway_payment_operation/index.ts +0 -1
  692. package/generated/entities/gateway_transaction/index.ts +0 -1
  693. package/generated/entities/organization/index.ts +0 -1
  694. package/generated/entities/resources_resource/index.ts +0 -1
  695. package/generated/entities.ids.generated.ts +1 -3
  696. package/generated/entity-fields-registry.ts +0 -23
  697. package/package.json +18 -19
  698. package/src/bootstrap.ts +2 -17
  699. package/src/helpers/integration/salesFixtures.ts +2 -34
  700. package/src/helpers/integration/salesUi.ts +0 -8
  701. package/src/modules/api_keys/backend/api-keys/page.tsx +1 -2
  702. package/src/modules/attachments/api/route.ts +9 -130
  703. package/src/modules/attachments/data/entities.ts +0 -59
  704. package/src/modules/attachments/di.ts +1 -9
  705. package/src/modules/attachments/fields/attachment.tsx +1 -1
  706. package/src/modules/attachments/i18n/de.json +0 -15
  707. package/src/modules/attachments/i18n/en.json +0 -15
  708. package/src/modules/attachments/i18n/es.json +0 -15
  709. package/src/modules/attachments/i18n/pl.json +0 -15
  710. package/src/modules/attachments/lib/drivers/index.ts +1 -1
  711. package/src/modules/attachments/lib/drivers/localDriver.ts +8 -23
  712. package/src/modules/attachments/lib/drivers/types.ts +0 -5
  713. package/src/modules/attachments/lib/upload-limits.ts +0 -35
  714. package/src/modules/attachments/migrations/.snapshot-open-mercato.json +120 -648
  715. package/src/modules/audit_logs/api/audit-logs/access/route.ts +0 -5
  716. package/src/modules/audit_logs/api/audit-logs/actions/export/route.ts +0 -5
  717. package/src/modules/audit_logs/api/audit-logs/actions/route.ts +0 -5
  718. package/src/modules/audit_logs/components/AccessLogsTable.tsx +1 -2
  719. package/src/modules/audit_logs/components/AuditLogsActions.tsx +1 -2
  720. package/src/modules/auth/AGENTS.md +8 -12
  721. package/src/modules/auth/api/admin/nav.ts +4 -28
  722. package/src/modules/auth/api/profile/route.ts +2 -8
  723. package/src/modules/auth/api/users/route.ts +28 -8
  724. package/src/modules/auth/backend/auth/profile/page.tsx +0 -1
  725. package/src/modules/auth/backend/profile/change-password/page.tsx +0 -1
  726. package/src/modules/auth/backend/roles/page.tsx +1 -2
  727. package/src/modules/auth/backend/settings/page.tsx +8 -17
  728. package/src/modules/auth/backend/users/page.tsx +1 -2
  729. package/src/modules/auth/cli.ts +1 -1
  730. package/src/modules/auth/components/UserConsentsPanel.tsx +9 -9
  731. package/src/modules/auth/frontend/login.tsx +4 -5
  732. package/src/modules/auth/frontend/reset.tsx +2 -2
  733. package/src/modules/auth/i18n/de.json +0 -1
  734. package/src/modules/auth/i18n/en.json +0 -1
  735. package/src/modules/auth/i18n/es.json +0 -1
  736. package/src/modules/auth/i18n/pl.json +0 -1
  737. package/src/modules/auth/lib/backendChrome.tsx +33 -71
  738. package/src/modules/auth/lib/setup-app.ts +2 -21
  739. package/src/modules/auth/lib/tenantAccess.ts +0 -8
  740. package/src/modules/auth/services/rbacService.ts +46 -41
  741. package/src/modules/business_rules/api/rules/route.ts +4 -92
  742. package/src/modules/business_rules/backend/rules/page.tsx +1 -2
  743. package/src/modules/business_rules/components/ActionBuilder.tsx +5 -54
  744. package/src/modules/business_rules/components/ActionRow.tsx +18 -156
  745. package/src/modules/business_rules/components/ConditionRow.tsx +6 -9
  746. package/src/modules/business_rules/components/utils/actionValidation.ts +0 -6
  747. package/src/modules/business_rules/i18n/de.json +0 -12
  748. package/src/modules/business_rules/i18n/en.json +0 -12
  749. package/src/modules/business_rules/i18n/es.json +0 -12
  750. package/src/modules/business_rules/i18n/pl.json +0 -12
  751. package/src/modules/business_rules/lib/action-executor.ts +0 -198
  752. package/src/modules/business_rules/lib/rule-engine.ts +0 -4
  753. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +5 -6
  754. package/src/modules/catalog/backend/catalog/products/create/page.tsx +6 -7
  755. package/src/modules/catalog/components/PriceKindSettings.tsx +3 -3
  756. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +1 -2
  757. package/src/modules/catalog/components/products/ProductCategorizeSection.tsx +3 -3
  758. package/src/modules/catalog/components/products/ProductMediaManager.tsx +1 -1
  759. package/src/modules/catalog/components/products/ProductsDataTable.tsx +2 -3
  760. package/src/modules/catalog/components/products/VariantBuilder.tsx +5 -5
  761. package/src/modules/catalog/events.ts +0 -1
  762. package/src/modules/catalog/i18n/de.json +0 -18
  763. package/src/modules/catalog/i18n/en.json +0 -18
  764. package/src/modules/catalog/i18n/es.json +0 -18
  765. package/src/modules/catalog/i18n/pl.json +0 -18
  766. package/src/modules/catalog/widgets/injection/product-seo/widget.ts +1 -1
  767. package/src/modules/communication_channels/api/post/test-seed/route.ts +2 -69
  768. package/src/modules/communication_channels/api/post/webhook/[provider]/route.ts +1 -11
  769. package/src/modules/communication_channels/api/post/webhooks/gmail/route.ts +11 -17
  770. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +1 -2
  771. package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +3 -4
  772. package/src/modules/communication_channels/data/enrichers.ts +26 -6
  773. package/src/modules/communication_channels/lib/access-control.ts +3 -3
  774. package/src/modules/configs/backend/config/system-status/page.tsx +1 -2
  775. package/src/modules/configs/lib/upgrade-actions.ts +0 -14
  776. package/src/modules/currencies/backend/currencies/page.tsx +1 -2
  777. package/src/modules/currencies/backend/exchange-rates/page.tsx +1 -2
  778. package/src/modules/currencies/di.ts +1 -4
  779. package/src/modules/currencies/i18n/de.json +0 -1
  780. package/src/modules/currencies/i18n/en.json +0 -1
  781. package/src/modules/currencies/i18n/es.json +0 -1
  782. package/src/modules/currencies/i18n/pl.json +0 -1
  783. package/src/modules/customer_accounts/AGENTS.md +3 -3
  784. package/src/modules/customer_accounts/api/admin/users/[id].ts +1 -16
  785. package/src/modules/customer_accounts/api/admin/users-invite.ts +3 -81
  786. package/src/modules/customer_accounts/api/invitations/accept.ts +2 -1
  787. package/src/modules/customer_accounts/api/login.ts +2 -4
  788. package/src/modules/customer_accounts/api/magic-link/verify.ts +2 -4
  789. package/src/modules/customer_accounts/api/portal/feature-check.ts +7 -5
  790. package/src/modules/customer_accounts/api/portal/nav.ts +3 -5
  791. package/src/modules/customer_accounts/api/portal/profile.ts +1 -5
  792. package/src/modules/customer_accounts/api/portal/sessions-refresh.ts +3 -3
  793. package/src/modules/customer_accounts/api/portal/users-invite.ts +1 -25
  794. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +1 -2
  795. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +1 -2
  796. package/src/modules/customer_accounts/data/entities.ts +0 -3
  797. package/src/modules/customer_accounts/data/validators.ts +0 -1
  798. package/src/modules/customer_accounts/i18n/de.json +0 -6
  799. package/src/modules/customer_accounts/i18n/en.json +0 -6
  800. package/src/modules/customer_accounts/i18n/es.json +0 -6
  801. package/src/modules/customer_accounts/i18n/pl.json +0 -6
  802. package/src/modules/customer_accounts/lib/customerAuth.ts +2 -8
  803. package/src/modules/customer_accounts/lib/customerAuthServer.ts +0 -1
  804. package/src/modules/customer_accounts/lib/customerEntityOwnership.ts +2 -68
  805. package/src/modules/customer_accounts/lib/customerUrl.ts +11 -27
  806. package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +0 -16
  807. package/src/modules/customer_accounts/services/customerInvitationService.ts +3 -56
  808. package/src/modules/customer_accounts/services/customerRbacService.ts +3 -16
  809. package/src/modules/customer_accounts/setup.ts +0 -7
  810. package/src/modules/customer_accounts/subscribers/autoLinkCrm.ts +8 -75
  811. package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +2 -2
  812. package/src/modules/customer_accounts/widgets/injection/portal-ai-assistant-trigger/widget.client.tsx +3 -1
  813. package/src/modules/customer_accounts/widgets/injection-table.ts +1 -4
  814. package/src/modules/customers/analytics.ts +0 -3
  815. package/src/modules/customers/api/companies/[id]/route.ts +4 -3
  816. package/src/modules/customers/api/deals/[id]/people/route.ts +0 -3
  817. package/src/modules/customers/api/deals/[id]/route.ts +2 -10
  818. package/src/modules/customers/api/deals/aggregate/route.ts +4 -5
  819. package/src/modules/customers/api/deals/summary/route.ts +162 -15
  820. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +2 -3
  821. package/src/modules/customers/api/utils.ts +31 -12
  822. package/src/modules/customers/backend/customers/companies/[id]/page.tsx +1 -2
  823. package/src/modules/customers/backend/customers/companies/page.tsx +1 -2
  824. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +5 -17
  825. package/src/modules/customers/backend/customers/deals/[id]/hooks/types.ts +0 -1
  826. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +12 -19
  827. package/src/modules/customers/backend/customers/deals/page.tsx +1 -2
  828. package/src/modules/customers/backend/customers/deals/pipeline/components/QuickDealDialog.tsx +3 -35
  829. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +1 -10
  830. package/src/modules/customers/backend/customers/people/[id]/page.tsx +1 -2
  831. package/src/modules/customers/backend/customers/people/page.tsx +1 -2
  832. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +10 -29
  833. package/src/modules/customers/cli.ts +11 -28
  834. package/src/modules/customers/commands/deals.ts +9 -50
  835. package/src/modules/customers/commands/people.ts +0 -3
  836. package/src/modules/customers/components/CustomerTodosTable.tsx +1 -2
  837. package/src/modules/customers/components/detail/ActiveDealCard.tsx +1 -2
  838. package/src/modules/customers/components/detail/ActivitiesDayStrip.tsx +3 -2
  839. package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +7 -30
  840. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +5 -6
  841. package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +1 -1
  842. package/src/modules/customers/components/detail/DealDetailTabs.tsx +9 -34
  843. package/src/modules/customers/components/detail/DealForm.tsx +1 -5
  844. package/src/modules/customers/components/detail/DealsSection.tsx +1 -1
  845. package/src/modules/customers/components/detail/PersonDetailTabs.tsx +9 -34
  846. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +13 -28
  847. package/src/modules/customers/components/detail/dashboard/helpers.ts +3 -4
  848. package/src/modules/customers/components/formConfig.tsx +8 -12
  849. package/src/modules/customers/data/entities.ts +1 -9
  850. package/src/modules/customers/data/validators.ts +1 -6
  851. package/src/modules/customers/i18n/de.json +0 -72
  852. package/src/modules/customers/i18n/en.json +0 -72
  853. package/src/modules/customers/i18n/es.json +0 -72
  854. package/src/modules/customers/i18n/pl.json +0 -72
  855. package/src/modules/customers/lib/calendar/format.ts +4 -10
  856. package/src/modules/customers/lib/visibilityFilter.ts +5 -7
  857. package/src/modules/customers/migrations/.snapshot-open-mercato.json +1 -27
  858. package/src/modules/customers/search.ts +27 -59
  859. package/src/modules/dashboards/api/layout/[itemId]/route.ts +3 -6
  860. package/src/modules/dashboards/api/layout/route.ts +9 -22
  861. package/src/modules/dashboards/api/roles/widgets/route.ts +3 -9
  862. package/src/modules/dashboards/api/users/widgets/route.ts +3 -9
  863. package/src/modules/dashboards/api/widgets/catalog.ts +3 -6
  864. package/src/modules/dashboards/api/widgets/data/batch/route.ts +1 -12
  865. package/src/modules/dashboards/api/widgets/data/route.ts +1 -29
  866. package/src/modules/dashboards/api/widgets/data/schema.ts +19 -49
  867. package/src/modules/dashboards/i18n/de.json +0 -5
  868. package/src/modules/dashboards/i18n/en.json +0 -5
  869. package/src/modules/dashboards/i18n/es.json +0 -5
  870. package/src/modules/dashboards/i18n/pl.json +0 -5
  871. package/src/modules/dashboards/lib/access.ts +3 -5
  872. package/src/modules/dashboards/lib/aggregations.ts +48 -198
  873. package/src/modules/dashboards/lib/formatters.ts +12 -137
  874. package/src/modules/dashboards/services/widgetDataService.ts +12 -453
  875. package/src/modules/dashboards/widgets/dashboard/aov-kpi/widget.client.tsx +3 -9
  876. package/src/modules/dashboards/widgets/dashboard/pipeline-summary/config.ts +0 -86
  877. package/src/modules/dashboards/widgets/dashboard/pipeline-summary/widget.client.tsx +21 -42
  878. package/src/modules/dashboards/widgets/dashboard/pipeline-summary/widget.ts +2 -2
  879. package/src/modules/dashboards/widgets/dashboard/revenue-kpi/widget.client.tsx +3 -9
  880. package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.tsx +2 -7
  881. package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.tsx +15 -25
  882. package/src/modules/dashboards/widgets/dashboard/top-customers/widget.client.tsx +11 -21
  883. package/src/modules/dashboards/widgets/dashboard/top-products/widget.client.tsx +3 -9
  884. package/src/modules/data_sync/AGENTS.md +0 -1
  885. package/src/modules/data_sync/api/mappings/[id]/route.ts +9 -22
  886. package/src/modules/data_sync/api/mappings/route.ts +4 -13
  887. package/src/modules/data_sync/api/options.ts +2 -7
  888. package/src/modules/data_sync/api/run.ts +2 -7
  889. package/src/modules/data_sync/api/runs/[id]/cancel.ts +3 -8
  890. package/src/modules/data_sync/api/runs/[id]/retry.ts +2 -7
  891. package/src/modules/data_sync/api/runs/[id]/route.ts +3 -8
  892. package/src/modules/data_sync/api/runs.ts +2 -7
  893. package/src/modules/data_sync/api/schedules/[id]/route.ts +6 -19
  894. package/src/modules/data_sync/api/schedules/route.ts +4 -13
  895. package/src/modules/data_sync/api/validate.ts +4 -9
  896. package/src/modules/data_sync/backend/data-sync/page.tsx +1 -2
  897. package/src/modules/data_sync/lib/adapter.ts +0 -18
  898. package/src/modules/data_sync/lib/queue.ts +1 -19
  899. package/src/modules/data_sync/lib/start-run.ts +1 -2
  900. package/src/modules/data_sync/lib/sync-engine.ts +0 -46
  901. package/src/modules/data_sync/lib/sync-run-service.ts +1 -82
  902. package/src/modules/data_sync/workers/sync-export.ts +1 -8
  903. package/src/modules/data_sync/workers/sync-import.ts +1 -8
  904. package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +11 -39
  905. package/src/modules/dictionaries/api/openapi.ts +0 -19
  906. package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +1 -1
  907. package/src/modules/dictionaries/components/hooks/useDictionaryEntries.ts +36 -35
  908. package/src/modules/dictionaries/data/validators.ts +0 -14
  909. package/src/modules/dictionaries/lib/clientEntries.ts +3 -4
  910. package/src/modules/directory/api/organization-branding/route.ts +1 -12
  911. package/src/modules/directory/api/organization-switcher/route.ts +26 -97
  912. package/src/modules/directory/api/organizations/route.ts +0 -7
  913. package/src/modules/directory/api/tenants/route.ts +1 -9
  914. package/src/modules/directory/backend/directory/branding/page.tsx +9 -34
  915. package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +14 -10
  916. package/src/modules/directory/backend/directory/organizations/page.tsx +1 -2
  917. package/src/modules/directory/backend/directory/tenants/page.tsx +1 -2
  918. package/src/modules/directory/commands/organizations.ts +1 -9
  919. package/src/modules/directory/commands/tenants.ts +0 -6
  920. package/src/modules/directory/data/entities.ts +0 -3
  921. package/src/modules/directory/data/validators.ts +0 -2
  922. package/src/modules/directory/i18n/de.json +1 -4
  923. package/src/modules/directory/i18n/en.json +1 -4
  924. package/src/modules/directory/i18n/es.json +1 -4
  925. package/src/modules/directory/i18n/pl.json +1 -4
  926. package/src/modules/directory/migrations/.snapshot-open-mercato.json +1 -18
  927. package/src/modules/directory/subscribers/invalidateOrgScopeCache.ts +1 -4
  928. package/src/modules/directory/utils/organizationScope.ts +3 -9
  929. package/src/modules/entities/api/definitions.ts +3 -55
  930. package/src/modules/entities/api/entities.ts +2 -30
  931. package/src/modules/entities/api/entity-settings.ts +22 -66
  932. package/src/modules/entities/api/records.ts +27 -3
  933. package/src/modules/entities/api/relations/options.ts +25 -11
  934. package/src/modules/entities/api/sidebar-entities.ts +14 -43
  935. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +75 -96
  936. package/src/modules/entities/backend/entities/user/create/page.tsx +7 -16
  937. package/src/modules/entities/cli.ts +21 -238
  938. package/src/modules/entities/components/SystemEntitiesTable.tsx +1 -2
  939. package/src/modules/entities/components/UserEntitiesTable.tsx +1 -2
  940. package/src/modules/entities/i18n/de.json +0 -9
  941. package/src/modules/entities/i18n/en.json +0 -9
  942. package/src/modules/entities/i18n/es.json +0 -9
  943. package/src/modules/entities/i18n/pl.json +0 -9
  944. package/src/modules/entities/lib/entityAcl.ts +11 -98
  945. package/src/modules/feature_toggles/components/FeatureGuard.tsx +2 -9
  946. package/src/modules/feature_toggles/components/hooks/useFeatureFlagBoolean.ts +1 -13
  947. package/src/modules/feature_toggles/components/hooks/useFeatureFlagJson.ts +3 -12
  948. package/src/modules/feature_toggles/components/hooks/useFeatureFlagNumber.ts +1 -10
  949. package/src/modules/feature_toggles/components/hooks/useFeatureFlagString.ts +1 -10
  950. package/src/modules/inbox_ops/ai-tools.ts +3 -5
  951. package/src/modules/inbox_ops/api/proposals/[id]/actions/[actionId]/route.ts +1 -17
  952. package/src/modules/inbox_ops/api/proposals/route.ts +1 -20
  953. package/src/modules/inbox_ops/api/webhook/inbound.ts +12 -14
  954. package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +6 -6
  955. package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +19 -24
  956. package/src/modules/inbox_ops/components/proposals/types.ts +0 -1
  957. package/src/modules/inbox_ops/i18n/de.json +0 -3
  958. package/src/modules/inbox_ops/i18n/en.json +0 -3
  959. package/src/modules/inbox_ops/i18n/es.json +0 -3
  960. package/src/modules/inbox_ops/i18n/pl.json +0 -3
  961. package/src/modules/inbox_ops/search.ts +4 -20
  962. package/src/modules/integrations/api/[id]/credentials/route.ts +5 -11
  963. package/src/modules/integrations/api/[id]/health/route.ts +3 -6
  964. package/src/modules/integrations/api/[id]/route.ts +3 -6
  965. package/src/modules/integrations/api/[id]/state/route.ts +3 -6
  966. package/src/modules/integrations/api/[id]/version/route.ts +3 -6
  967. package/src/modules/integrations/api/logs/route.ts +3 -6
  968. package/src/modules/integrations/api/route.ts +3 -6
  969. package/src/modules/integrations/api/umes-read.ts +2 -2
  970. package/src/modules/integrations/backend/integrations/[id]/page.tsx +2 -2
  971. package/src/modules/integrations/lib/organization-scope.ts +25 -5
  972. package/src/modules/integrations/widgets/injection/external-ids/widget.client.tsx +5 -0
  973. package/src/modules/messages/api/[id]/route.ts +0 -21
  974. package/src/modules/messages/api/route.ts +9 -109
  975. package/src/modules/messages/components/ComposeMessagePageClient.tsx +1 -2
  976. package/src/modules/messages/components/MessageDetailPageClient.tsx +2 -3
  977. package/src/modules/messages/components/MessagesInboxPageClient.tsx +1 -2
  978. package/src/modules/messages/components/message-detail/panels/dialogs.tsx +1 -1
  979. package/src/modules/messages/i18n/de.json +0 -2
  980. package/src/modules/messages/i18n/en.json +0 -2
  981. package/src/modules/messages/i18n/es.json +0 -2
  982. package/src/modules/messages/i18n/pl.json +0 -2
  983. package/src/modules/messages/lib/routeHelpers.ts +6 -4
  984. package/src/modules/messages/lib/searchLookup.ts +34 -11
  985. package/src/modules/messages/search.ts +5 -11
  986. package/src/modules/notifications/api/route.ts +3 -123
  987. package/src/modules/notifications/api/unread-count/route.ts +5 -42
  988. package/src/modules/notifications/di.ts +1 -1
  989. package/src/modules/notifications/events.ts +0 -2
  990. package/src/modules/notifications/lib/notificationRecipients.ts +8 -6
  991. package/src/modules/notifications/lib/notificationService.ts +1 -63
  992. package/src/modules/notifications/lib/routeHelpers.ts +2 -19
  993. package/src/modules/payment_gateways/api/capture/route.ts +1 -1
  994. package/src/modules/payment_gateways/api/sessions/route.ts +3 -6
  995. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +1 -13
  996. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +2 -3
  997. package/src/modules/payment_gateways/data/entities.ts +2 -13
  998. package/src/modules/payment_gateways/di.ts +2 -28
  999. package/src/modules/payment_gateways/i18n/de.json +1 -8
  1000. package/src/modules/payment_gateways/i18n/en.json +1 -8
  1001. package/src/modules/payment_gateways/i18n/es.json +1 -8
  1002. package/src/modules/payment_gateways/i18n/pl.json +1 -8
  1003. package/src/modules/payment_gateways/lib/gateway-service.ts +18 -114
  1004. package/src/modules/payment_gateways/lib/payment-operation-idempotency.ts +0 -1
  1005. package/src/modules/payment_gateways/lib/session-idempotency.ts +0 -36
  1006. package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +1 -44
  1007. package/src/modules/payment_gateways/setup.ts +0 -62
  1008. package/src/modules/planner/components/AvailabilityRulesEditor.tsx +4 -4
  1009. package/src/modules/planner/components/unavailabilityReasons.ts +3 -3
  1010. package/src/modules/portal/frontend/[orgSlug]/portal/dashboard/page.tsx +3 -3
  1011. package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +3 -3
  1012. package/src/modules/portal/frontend/[orgSlug]/portal/page.tsx +3 -3
  1013. package/src/modules/portal/frontend/[orgSlug]/portal/profile/page.tsx +3 -3
  1014. package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +4 -4
  1015. package/src/modules/portal/frontend/[orgSlug]/portal/signup/page.tsx +3 -3
  1016. package/src/modules/portal/i18n/de.json +0 -18
  1017. package/src/modules/portal/i18n/en.json +0 -18
  1018. package/src/modules/portal/i18n/es.json +0 -18
  1019. package/src/modules/portal/i18n/pl.json +0 -18
  1020. package/src/modules/progress/AGENTS.md +1 -11
  1021. package/src/modules/progress/lib/progressService.ts +0 -1
  1022. package/src/modules/progress/lib/progressServiceImpl.ts +117 -385
  1023. package/src/modules/query_index/api/openapi.ts +0 -12
  1024. package/src/modules/query_index/api/reindex.ts +0 -15
  1025. package/src/modules/query_index/api/status.ts +136 -238
  1026. package/src/modules/query_index/cli.ts +1 -180
  1027. package/src/modules/query_index/components/QueryIndexesTable.tsx +47 -194
  1028. package/src/modules/query_index/data/entities.ts +0 -7
  1029. package/src/modules/query_index/di.ts +0 -6
  1030. package/src/modules/query_index/i18n/de.json +3 -5
  1031. package/src/modules/query_index/i18n/en.json +3 -5
  1032. package/src/modules/query_index/i18n/es.json +3 -5
  1033. package/src/modules/query_index/i18n/pl.json +3 -5
  1034. package/src/modules/query_index/lib/batch.ts +4 -11
  1035. package/src/modules/query_index/lib/coverage.ts +14 -47
  1036. package/src/modules/query_index/lib/document.ts +4 -35
  1037. package/src/modules/query_index/lib/engine.ts +59 -136
  1038. package/src/modules/query_index/lib/indexer.ts +21 -130
  1039. package/src/modules/query_index/lib/reindexer.ts +40 -62
  1040. package/src/modules/query_index/lib/search-tokens.ts +16 -48
  1041. package/src/modules/query_index/lib/subscriber-scope.ts +7 -2
  1042. package/src/modules/query_index/migrations/.snapshot-open-mercato.json +0 -12
  1043. package/src/modules/query_index/subscribers/coverage_refresh.ts +0 -4
  1044. package/src/modules/query_index/subscribers/delete_one.ts +1 -65
  1045. package/src/modules/query_index/subscribers/upsert_one.ts +1 -68
  1046. package/src/modules/resources/api/resources.ts +0 -2
  1047. package/src/modules/resources/backend/resources/resource-types/page.tsx +1 -2
  1048. package/src/modules/resources/backend/resources/resources/[id]/page.tsx +3 -9
  1049. package/src/modules/resources/backend/resources/resources/page.tsx +1 -2
  1050. package/src/modules/resources/commands/resources.ts +0 -10
  1051. package/src/modules/resources/components/detail/dictionaries.ts +3 -3
  1052. package/src/modules/resources/data/entities.ts +0 -3
  1053. package/src/modules/resources/data/validators.ts +0 -5
  1054. package/src/modules/resources/lib/seeds.ts +9 -16
  1055. package/src/modules/resources/migrations/.snapshot-open-mercato.json +1 -17
  1056. package/src/modules/sales/analytics.ts +0 -4
  1057. package/src/modules/sales/api/document-history/route.ts +0 -1
  1058. package/src/modules/sales/api/documents/factory.ts +3 -28
  1059. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +3 -11
  1060. package/src/modules/sales/backend/sales/documents/create/page.tsx +4 -2
  1061. package/src/modules/sales/commands/documents.ts +31 -298
  1062. package/src/modules/sales/components/documents/ItemsSection.tsx +11 -21
  1063. package/src/modules/sales/components/documents/LineItemDialog.tsx +5 -13
  1064. package/src/modules/sales/components/documents/SalesDocumentForm.tsx +6 -48
  1065. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +1 -6
  1066. package/src/modules/sales/components/useSalesChannelsEnabled.ts +48 -2
  1067. package/src/modules/sales/data/validators.ts +6 -59
  1068. package/src/modules/sales/di.ts +0 -9
  1069. package/src/modules/sales/events.ts +0 -1
  1070. package/src/modules/sales/i18n/de.json +0 -22
  1071. package/src/modules/sales/i18n/en.json +0 -22
  1072. package/src/modules/sales/i18n/es.json +0 -22
  1073. package/src/modules/sales/i18n/pl.json +0 -22
  1074. package/src/modules/sales/lib/historyHelpers.ts +1 -88
  1075. package/src/modules/sales/widgets/injection/document-history/widget.client.tsx +3 -64
  1076. package/src/modules/sales/workflows.ts +7 -10
  1077. package/src/modules/shipping_carriers/api/webhook/[provider]/route.ts +1 -11
  1078. package/src/modules/shipping_carriers/lib/shipment-wizard/components/PackageEditor.tsx +1 -1
  1079. package/src/modules/staff/api/interceptors.ts +4 -6
  1080. package/src/modules/staff/api/leave-requests.ts +47 -54
  1081. package/src/modules/staff/components/detail/dictionaries.ts +3 -3
  1082. package/src/modules/sync_excel/api/upload/route.ts +2 -15
  1083. package/src/modules/wms/components/backend/ReleaseReservationDialog.tsx +1 -1
  1084. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +4 -5
  1085. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +3 -4
  1086. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +2 -3
  1087. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +2 -3
  1088. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +1 -2
  1089. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +2 -3
  1090. package/src/modules/wms/i18n/de.json +0 -2
  1091. package/src/modules/wms/i18n/en.json +0 -2
  1092. package/src/modules/wms/i18n/es.json +0 -2
  1093. package/src/modules/wms/i18n/pl.json +0 -2
  1094. package/src/modules/workflows/backend/definitions/page.tsx +2 -3
  1095. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +4 -13
  1096. package/src/modules/workflows/backend/instances/page.tsx +9 -10
  1097. package/src/modules/workflows/backend/tasks/page.tsx +7 -8
  1098. package/src/modules/workflows/components/ActivitiesEditor.tsx +14 -98
  1099. package/src/modules/workflows/components/BusinessRulesSelector.tsx +1 -1
  1100. package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +2 -2
  1101. package/src/modules/workflows/components/EdgeEditDialogCrudForm.tsx +2 -1
  1102. package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +2 -1
  1103. package/src/modules/workflows/components/StepsEditor.tsx +2 -2
  1104. package/src/modules/workflows/components/TransitionsEditor.tsx +20 -78
  1105. package/src/modules/workflows/components/WorkflowLegend.tsx +1 -1
  1106. package/src/modules/workflows/components/WorkflowSelector.tsx +1 -1
  1107. package/src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx +1 -1
  1108. package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +1 -1
  1109. package/src/modules/workflows/components/fields/MappingArrayEditor.tsx +1 -1
  1110. package/src/modules/workflows/components/fields/StartPreConditionsEditor.tsx +1 -1
  1111. package/src/modules/workflows/components/fields/WorkflowSelectorField.tsx +4 -4
  1112. package/src/modules/workflows/data/validators.ts +1 -52
  1113. package/src/modules/workflows/events.ts +0 -1
  1114. package/src/modules/workflows/i18n/de.json +0 -3
  1115. package/src/modules/workflows/i18n/en.json +0 -3
  1116. package/src/modules/workflows/i18n/es.json +0 -3
  1117. package/src/modules/workflows/i18n/pl.json +0 -3
  1118. package/src/modules/workflows/lib/activity-executor.ts +20 -99
  1119. package/src/modules/workflows/lib/format-validation-error.ts +0 -60
  1120. package/src/modules/workflows/widgets/injection/order-approval/widget.client.tsx +11 -27
  1121. package/dist/generated/entities/attachment_quota_reservation/index.js +0 -33
  1122. package/dist/generated/entities/attachment_quota_reservation/index.js.map +0 -7
  1123. package/dist/modules/api_keys/extension-points.js +0 -16
  1124. package/dist/modules/api_keys/extension-points.js.map +0 -7
  1125. package/dist/modules/attachments/lib/quota-recovery-queue.js +0 -9
  1126. package/dist/modules/attachments/lib/quota-recovery-queue.js.map +0 -7
  1127. package/dist/modules/attachments/lib/quota-service.js +0 -224
  1128. package/dist/modules/attachments/lib/quota-service.js.map +0 -7
  1129. package/dist/modules/attachments/migrations/Migration20260709234741_attachments.js +0 -13
  1130. package/dist/modules/attachments/migrations/Migration20260709234741_attachments.js.map +0 -7
  1131. package/dist/modules/attachments/workers/quota-recovery.js +0 -45
  1132. package/dist/modules/attachments/workers/quota-recovery.js.map +0 -7
  1133. package/dist/modules/audit_logs/api/audit-logs/readScope.js +0 -12
  1134. package/dist/modules/audit_logs/api/audit-logs/readScope.js.map +0 -7
  1135. package/dist/modules/audit_logs/extension-points.js +0 -14
  1136. package/dist/modules/audit_logs/extension-points.js.map +0 -7
  1137. package/dist/modules/auth/extension-points.js +0 -21
  1138. package/dist/modules/auth/extension-points.js.map +0 -7
  1139. package/dist/modules/business_rules/api/openmercato-call-options/route.js +0 -85
  1140. package/dist/modules/business_rules/api/openmercato-call-options/route.js.map +0 -7
  1141. package/dist/modules/business_rules/events.js +0 -13
  1142. package/dist/modules/business_rules/events.js.map +0 -7
  1143. package/dist/modules/business_rules/extension-points.js +0 -13
  1144. package/dist/modules/business_rules/extension-points.js.map +0 -7
  1145. package/dist/modules/business_rules/lib/openmercato-call-options-types.js +0 -5
  1146. package/dist/modules/business_rules/lib/openmercato-call-options-types.js.map +0 -7
  1147. package/dist/modules/business_rules/lib/openmercato-call-options.js +0 -231
  1148. package/dist/modules/business_rules/lib/openmercato-call-options.js.map +0 -7
  1149. package/dist/modules/catalog/extension-points.js +0 -27
  1150. package/dist/modules/catalog/extension-points.js.map +0 -7
  1151. package/dist/modules/communication_channels/extension-points.js +0 -20
  1152. package/dist/modules/communication_channels/extension-points.js.map +0 -7
  1153. package/dist/modules/configs/extension-points.js +0 -18
  1154. package/dist/modules/configs/extension-points.js.map +0 -7
  1155. package/dist/modules/currencies/extension-points.js +0 -14
  1156. package/dist/modules/currencies/extension-points.js.map +0 -7
  1157. package/dist/modules/currencies/services/baseCurrencyService.js +0 -42
  1158. package/dist/modules/currencies/services/baseCurrencyService.js.map +0 -7
  1159. package/dist/modules/customer_accounts/emails/CustomerInvitationEmail.js +0 -26
  1160. package/dist/modules/customer_accounts/emails/CustomerInvitationEmail.js.map +0 -7
  1161. package/dist/modules/customer_accounts/extension-points.js +0 -14
  1162. package/dist/modules/customer_accounts/extension-points.js.map +0 -7
  1163. package/dist/modules/customer_accounts/lib/invitationEmail.js +0 -35
  1164. package/dist/modules/customer_accounts/lib/invitationEmail.js.map +0 -7
  1165. package/dist/modules/customer_accounts/migrations/Migration20260723120000_customer_accounts.js +0 -13
  1166. package/dist/modules/customer_accounts/migrations/Migration20260723120000_customer_accounts.js.map +0 -7
  1167. package/dist/modules/customers/extension-points.js +0 -42
  1168. package/dist/modules/customers/extension-points.js.map +0 -7
  1169. package/dist/modules/customers/lib/dealStatus.js +0 -38
  1170. package/dist/modules/customers/lib/dealStatus.js.map +0 -7
  1171. package/dist/modules/customers/lib/dealsSummaryQueries.js +0 -144
  1172. package/dist/modules/customers/lib/dealsSummaryQueries.js.map +0 -7
  1173. package/dist/modules/customers/lib/optionalBaseCurrency.js +0 -19
  1174. package/dist/modules/customers/lib/optionalBaseCurrency.js.map +0 -7
  1175. package/dist/modules/customers/migrations/Migration20260723210000_customers.js +0 -15
  1176. package/dist/modules/customers/migrations/Migration20260723210000_customers.js.map +0 -7
  1177. package/dist/modules/dashboards/components/UnlabelledAmountNotice.js +0 -33
  1178. package/dist/modules/dashboards/components/UnlabelledAmountNotice.js.map +0 -7
  1179. package/dist/modules/dashboards/lib/exactDecimal.js +0 -69
  1180. package/dist/modules/dashboards/lib/exactDecimal.js.map +0 -7
  1181. package/dist/modules/dashboards/lib/optionalBaseCurrency.js +0 -11
  1182. package/dist/modules/dashboards/lib/optionalBaseCurrency.js.map +0 -7
  1183. package/dist/modules/dashboards/subscribers/invalidateWidgetDataCache.js +0 -26
  1184. package/dist/modules/dashboards/subscribers/invalidateWidgetDataCache.js.map +0 -7
  1185. package/dist/modules/data_sync/extension-points.js +0 -13
  1186. package/dist/modules/data_sync/extension-points.js.map +0 -7
  1187. package/dist/modules/data_sync/lib/queue-policy.js +0 -15
  1188. package/dist/modules/data_sync/lib/queue-policy.js.map +0 -7
  1189. package/dist/modules/design_system/acl.js +0 -9
  1190. package/dist/modules/design_system/acl.js.map +0 -7
  1191. package/dist/modules/design_system/backend/design-system/page.js +0 -11
  1192. package/dist/modules/design_system/backend/design-system/page.js.map +0 -7
  1193. package/dist/modules/design_system/backend/design-system/page.meta.js +0 -15
  1194. package/dist/modules/design_system/backend/design-system/page.meta.js.map +0 -7
  1195. package/dist/modules/design_system/gallery/components/CodeSnippet.js +0 -52
  1196. package/dist/modules/design_system/gallery/components/CodeSnippet.js.map +0 -7
  1197. package/dist/modules/design_system/gallery/components/EntryCard.js +0 -63
  1198. package/dist/modules/design_system/gallery/components/EntryCard.js.map +0 -7
  1199. package/dist/modules/design_system/gallery/components/GalleryShell.js +0 -163
  1200. package/dist/modules/design_system/gallery/components/GalleryShell.js.map +0 -7
  1201. package/dist/modules/design_system/gallery/components/VariantPreview.js +0 -9
  1202. package/dist/modules/design_system/gallery/components/VariantPreview.js.map +0 -7
  1203. package/dist/modules/design_system/gallery/entries/banners.js +0 -186
  1204. package/dist/modules/design_system/gallery/entries/banners.js.map +0 -7
  1205. package/dist/modules/design_system/gallery/entries/buttons.js +0 -361
  1206. package/dist/modules/design_system/gallery/entries/buttons.js.map +0 -7
  1207. package/dist/modules/design_system/gallery/entries/charts.js +0 -457
  1208. package/dist/modules/design_system/gallery/entries/charts.js.map +0 -7
  1209. package/dist/modules/design_system/gallery/entries/dates.js +0 -306
  1210. package/dist/modules/design_system/gallery/entries/dates.js.map +0 -7
  1211. package/dist/modules/design_system/gallery/entries/detail.js +0 -358
  1212. package/dist/modules/design_system/gallery/entries/detail.js.map +0 -7
  1213. package/dist/modules/design_system/gallery/entries/display.js +0 -785
  1214. package/dist/modules/design_system/gallery/entries/display.js.map +0 -7
  1215. package/dist/modules/design_system/gallery/entries/feedback.js +0 -658
  1216. package/dist/modules/design_system/gallery/entries/feedback.js.map +0 -7
  1217. package/dist/modules/design_system/gallery/entries/filters.js +0 -505
  1218. package/dist/modules/design_system/gallery/entries/filters.js.map +0 -7
  1219. package/dist/modules/design_system/gallery/entries/foundations.js +0 -453
  1220. package/dist/modules/design_system/gallery/entries/foundations.js.map +0 -7
  1221. package/dist/modules/design_system/gallery/entries/icons.js +0 -140
  1222. package/dist/modules/design_system/gallery/entries/icons.js.map +0 -7
  1223. package/dist/modules/design_system/gallery/entries/inputs.js +0 -1217
  1224. package/dist/modules/design_system/gallery/entries/inputs.js.map +0 -7
  1225. package/dist/modules/design_system/gallery/entries/messages.js +0 -334
  1226. package/dist/modules/design_system/gallery/entries/messages.js.map +0 -7
  1227. package/dist/modules/design_system/gallery/entries/navigation.js +0 -475
  1228. package/dist/modules/design_system/gallery/entries/navigation.js.map +0 -7
  1229. package/dist/modules/design_system/gallery/entries/notifications.js +0 -257
  1230. package/dist/modules/design_system/gallery/entries/notifications.js.map +0 -7
  1231. package/dist/modules/design_system/gallery/entries/overlays.js +0 -576
  1232. package/dist/modules/design_system/gallery/entries/overlays.js.map +0 -7
  1233. package/dist/modules/design_system/gallery/entries/scaffolding.js +0 -378
  1234. package/dist/modules/design_system/gallery/entries/scaffolding.js.map +0 -7
  1235. package/dist/modules/design_system/gallery/entries/schedule.js +0 -297
  1236. package/dist/modules/design_system/gallery/entries/schedule.js.map +0 -7
  1237. package/dist/modules/design_system/gallery/registry.js +0 -139
  1238. package/dist/modules/design_system/gallery/registry.js.map +0 -7
  1239. package/dist/modules/design_system/gallery/types.js +0 -1
  1240. package/dist/modules/design_system/gallery/types.js.map +0 -7
  1241. package/dist/modules/design_system/index.js +0 -9
  1242. package/dist/modules/design_system/index.js.map +0 -7
  1243. package/dist/modules/design_system/setup.js +0 -14
  1244. package/dist/modules/design_system/setup.js.map +0 -7
  1245. package/dist/modules/dictionaries/lib/fetchAllEntries.js +0 -43
  1246. package/dist/modules/dictionaries/lib/fetchAllEntries.js.map +0 -7
  1247. package/dist/modules/directory/extension-points.js +0 -14
  1248. package/dist/modules/directory/extension-points.js.map +0 -7
  1249. package/dist/modules/directory/migrations/Migration20260626145500_directory_logo_preserve_aspect_ratio.js +0 -13
  1250. package/dist/modules/directory/migrations/Migration20260626145500_directory_logo_preserve_aspect_ratio.js.map +0 -7
  1251. package/dist/modules/entities/backend/config/settings/page.js +0 -10
  1252. package/dist/modules/entities/backend/config/settings/page.js.map +0 -7
  1253. package/dist/modules/entities/backend/config/settings/page.meta.js +0 -36
  1254. package/dist/modules/entities/backend/config/settings/page.meta.js.map +0 -7
  1255. package/dist/modules/entities/components/EntitySettingsManager.js +0 -136
  1256. package/dist/modules/entities/components/EntitySettingsManager.js.map +0 -7
  1257. package/dist/modules/entities/components/RecordListRelationCell.js +0 -63
  1258. package/dist/modules/entities/components/RecordListRelationCell.js.map +0 -7
  1259. package/dist/modules/entities/components/recordListRelationDisplays.js +0 -80
  1260. package/dist/modules/entities/components/recordListRelationDisplays.js.map +0 -7
  1261. package/dist/modules/entities/extension-points.js +0 -21
  1262. package/dist/modules/entities/extension-points.js.map +0 -7
  1263. package/dist/modules/feature_toggles/components/hooks/staleTime.js +0 -5
  1264. package/dist/modules/feature_toggles/components/hooks/staleTime.js.map +0 -7
  1265. package/dist/modules/inbox_ops/subscribers/search-reindex-proposal-created.js +0 -32
  1266. package/dist/modules/inbox_ops/subscribers/search-reindex-proposal-created.js.map +0 -7
  1267. package/dist/modules/integrations/extension-points.js +0 -30
  1268. package/dist/modules/integrations/extension-points.js.map +0 -7
  1269. package/dist/modules/integrations/widgets/injection/external-ids/widget.js +0 -14
  1270. package/dist/modules/integrations/widgets/injection/external-ids/widget.js.map +0 -7
  1271. package/dist/modules/messages/extension-points.js +0 -16
  1272. package/dist/modules/messages/extension-points.js.map +0 -7
  1273. package/dist/modules/messages/lib/participantScope.js +0 -15
  1274. package/dist/modules/messages/lib/participantScope.js.map +0 -7
  1275. package/dist/modules/notifications/lib/notificationScope.js +0 -26
  1276. package/dist/modules/notifications/lib/notificationScope.js.map +0 -7
  1277. package/dist/modules/payment_gateways/extension-points.js +0 -19
  1278. package/dist/modules/payment_gateways/extension-points.js.map +0 -7
  1279. package/dist/modules/payment_gateways/lib/capture-ledger.js +0 -183
  1280. package/dist/modules/payment_gateways/lib/capture-ledger.js.map +0 -7
  1281. package/dist/modules/payment_gateways/lib/order-amount-reconciliation.js +0 -58
  1282. package/dist/modules/payment_gateways/lib/order-amount-reconciliation.js.map +0 -7
  1283. package/dist/modules/payment_gateways/migrations/Migration20260725101500_payment_gateways.js +0 -16
  1284. package/dist/modules/payment_gateways/migrations/Migration20260725101500_payment_gateways.js.map +0 -7
  1285. package/dist/modules/payment_gateways/migrations/Migration20260803103035_payment_gateways.js +0 -18
  1286. package/dist/modules/payment_gateways/migrations/Migration20260803103035_payment_gateways.js.map +0 -7
  1287. package/dist/modules/payment_gateways/workers/session-initialization-prune.js +0 -50
  1288. package/dist/modules/payment_gateways/workers/session-initialization-prune.js.map +0 -7
  1289. package/dist/modules/portal/extension-points.js +0 -32
  1290. package/dist/modules/portal/extension-points.js.map +0 -7
  1291. package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.js +0 -134
  1292. package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.js.map +0 -7
  1293. package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.meta.js +0 -11
  1294. package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.meta.js.map +0 -7
  1295. package/dist/modules/portal/lib/navigation.js +0 -7
  1296. package/dist/modules/portal/lib/navigation.js.map +0 -7
  1297. package/dist/modules/query_index/events.js +0 -20
  1298. package/dist/modules/query_index/events.js.map +0 -7
  1299. package/dist/modules/query_index/extension-points.js +0 -13
  1300. package/dist/modules/query_index/extension-points.js.map +0 -7
  1301. package/dist/modules/query_index/migrations/Migration20260731105052_query_index.js +0 -17
  1302. package/dist/modules/query_index/migrations/Migration20260731105052_query_index.js.map +0 -7
  1303. package/dist/modules/resources/extension-points.js +0 -14
  1304. package/dist/modules/resources/extension-points.js.map +0 -7
  1305. package/dist/modules/resources/migrations/Migration20260608231000.js +0 -13
  1306. package/dist/modules/resources/migrations/Migration20260608231000.js.map +0 -7
  1307. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +0 -167
  1308. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +0 -7
  1309. package/dist/modules/sales/extension-points.js +0 -36
  1310. package/dist/modules/sales/extension-points.js.map +0 -7
  1311. package/dist/modules/sales/services/paymentOrderTotalResolver.js +0 -52
  1312. package/dist/modules/sales/services/paymentOrderTotalResolver.js.map +0 -7
  1313. package/dist/modules/wms/extension-points.js +0 -26
  1314. package/dist/modules/wms/extension-points.js.map +0 -7
  1315. package/dist/modules/workflows/extension-points.js +0 -15
  1316. package/dist/modules/workflows/extension-points.js.map +0 -7
  1317. package/dist/modules/workflows/widgets/injection/order-approval/context-keys.js +0 -10
  1318. package/dist/modules/workflows/widgets/injection/order-approval/context-keys.js.map +0 -7
  1319. package/generated/entities/attachment_quota_reservation/index.ts +0 -15
  1320. package/src/modules/api_keys/extension-points.ts +0 -13
  1321. package/src/modules/api_keys/i18n/ko.json +0 -42
  1322. package/src/modules/attachments/i18n/ko.json +0 -175
  1323. package/src/modules/attachments/lib/quota-recovery-queue.ts +0 -16
  1324. package/src/modules/attachments/lib/quota-service.ts +0 -442
  1325. package/src/modules/attachments/migrations/Migration20260709234741_attachments.ts +0 -12
  1326. package/src/modules/attachments/workers/quota-recovery.ts +0 -68
  1327. package/src/modules/audit_logs/api/audit-logs/readScope.ts +0 -28
  1328. package/src/modules/audit_logs/extension-points.ts +0 -11
  1329. package/src/modules/audit_logs/i18n/ko.json +0 -66
  1330. package/src/modules/auth/extension-points.ts +0 -18
  1331. package/src/modules/auth/i18n/ko.json +0 -255
  1332. package/src/modules/business_rules/api/openmercato-call-options/route.ts +0 -94
  1333. package/src/modules/business_rules/events.ts +0 -10
  1334. package/src/modules/business_rules/extension-points.ts +0 -10
  1335. package/src/modules/business_rules/i18n/ko.json +0 -396
  1336. package/src/modules/business_rules/lib/openmercato-call-options-types.ts +0 -31
  1337. package/src/modules/business_rules/lib/openmercato-call-options.ts +0 -297
  1338. package/src/modules/catalog/extension-points.ts +0 -24
  1339. package/src/modules/catalog/i18n/ko.json +0 -723
  1340. package/src/modules/communication_channels/extension-points.ts +0 -17
  1341. package/src/modules/communication_channels/i18n/ko.json +0 -138
  1342. package/src/modules/configs/extension-points.ts +0 -15
  1343. package/src/modules/configs/i18n/ko.json +0 -197
  1344. package/src/modules/currencies/extension-points.ts +0 -11
  1345. package/src/modules/currencies/i18n/ko.json +0 -160
  1346. package/src/modules/currencies/services/baseCurrencyService.ts +0 -59
  1347. package/src/modules/customer_accounts/emails/CustomerInvitationEmail.tsx +0 -45
  1348. package/src/modules/customer_accounts/extension-points.ts +0 -11
  1349. package/src/modules/customer_accounts/i18n/ko.json +0 -354
  1350. package/src/modules/customer_accounts/lib/invitationEmail.ts +0 -42
  1351. package/src/modules/customer_accounts/migrations/Migration20260723120000_customer_accounts.ts +0 -13
  1352. package/src/modules/customers/extension-points.ts +0 -40
  1353. package/src/modules/customers/i18n/ko.json +0 -2855
  1354. package/src/modules/customers/lib/dealStatus.ts +0 -48
  1355. package/src/modules/customers/lib/dealsSummaryQueries.ts +0 -211
  1356. package/src/modules/customers/lib/optionalBaseCurrency.ts +0 -34
  1357. package/src/modules/customers/migrations/Migration20260723210000_customers.ts +0 -15
  1358. package/src/modules/dashboards/components/UnlabelledAmountNotice.tsx +0 -43
  1359. package/src/modules/dashboards/i18n/ko.json +0 -118
  1360. package/src/modules/dashboards/lib/exactDecimal.ts +0 -96
  1361. package/src/modules/dashboards/lib/optionalBaseCurrency.ts +0 -22
  1362. package/src/modules/dashboards/subscribers/invalidateWidgetDataCache.ts +0 -32
  1363. package/src/modules/data_sync/extension-points.ts +0 -10
  1364. package/src/modules/data_sync/i18n/ko.json +0 -125
  1365. package/src/modules/data_sync/lib/queue-policy.ts +0 -30
  1366. package/src/modules/design_system/AGENTS.md +0 -34
  1367. package/src/modules/design_system/acl.ts +0 -5
  1368. package/src/modules/design_system/backend/design-system/page.meta.ts +0 -11
  1369. package/src/modules/design_system/backend/design-system/page.tsx +0 -14
  1370. package/src/modules/design_system/gallery/components/CodeSnippet.tsx +0 -55
  1371. package/src/modules/design_system/gallery/components/EntryCard.tsx +0 -95
  1372. package/src/modules/design_system/gallery/components/GalleryShell.tsx +0 -206
  1373. package/src/modules/design_system/gallery/components/VariantPreview.tsx +0 -15
  1374. package/src/modules/design_system/gallery/entries/banners.tsx +0 -226
  1375. package/src/modules/design_system/gallery/entries/buttons.tsx +0 -422
  1376. package/src/modules/design_system/gallery/entries/charts.tsx +0 -518
  1377. package/src/modules/design_system/gallery/entries/dates.tsx +0 -325
  1378. package/src/modules/design_system/gallery/entries/detail.tsx +0 -403
  1379. package/src/modules/design_system/gallery/entries/display.tsx +0 -893
  1380. package/src/modules/design_system/gallery/entries/feedback.tsx +0 -746
  1381. package/src/modules/design_system/gallery/entries/filters.tsx +0 -570
  1382. package/src/modules/design_system/gallery/entries/foundations.tsx +0 -529
  1383. package/src/modules/design_system/gallery/entries/icons.tsx +0 -168
  1384. package/src/modules/design_system/gallery/entries/inputs.tsx +0 -1516
  1385. package/src/modules/design_system/gallery/entries/messages.tsx +0 -339
  1386. package/src/modules/design_system/gallery/entries/navigation.tsx +0 -573
  1387. package/src/modules/design_system/gallery/entries/notifications.tsx +0 -285
  1388. package/src/modules/design_system/gallery/entries/overlays.tsx +0 -677
  1389. package/src/modules/design_system/gallery/entries/scaffolding.tsx +0 -430
  1390. package/src/modules/design_system/gallery/entries/schedule.tsx +0 -307
  1391. package/src/modules/design_system/gallery/registry.ts +0 -152
  1392. package/src/modules/design_system/gallery/types.ts +0 -32
  1393. package/src/modules/design_system/i18n/.hardcoded-allowlist.json +0 -71
  1394. package/src/modules/design_system/i18n/de.json +0 -58
  1395. package/src/modules/design_system/i18n/en.json +0 -58
  1396. package/src/modules/design_system/i18n/es.json +0 -58
  1397. package/src/modules/design_system/i18n/ko.json +0 -58
  1398. package/src/modules/design_system/i18n/pl.json +0 -58
  1399. package/src/modules/design_system/index.ts +0 -7
  1400. package/src/modules/design_system/setup.ts +0 -12
  1401. package/src/modules/dictionaries/i18n/ko.json +0 -130
  1402. package/src/modules/dictionaries/lib/fetchAllEntries.ts +0 -72
  1403. package/src/modules/directory/extension-points.ts +0 -11
  1404. package/src/modules/directory/i18n/ko.json +0 -105
  1405. package/src/modules/directory/migrations/Migration20260626145500_directory_logo_preserve_aspect_ratio.ts +0 -13
  1406. package/src/modules/entities/backend/config/settings/page.meta.ts +0 -34
  1407. package/src/modules/entities/backend/config/settings/page.tsx +0 -12
  1408. package/src/modules/entities/components/EntitySettingsManager.tsx +0 -160
  1409. package/src/modules/entities/components/RecordListRelationCell.tsx +0 -90
  1410. package/src/modules/entities/components/recordListRelationDisplays.ts +0 -109
  1411. package/src/modules/entities/extension-points.ts +0 -18
  1412. package/src/modules/entities/i18n/ko.json +0 -260
  1413. package/src/modules/feature_toggles/components/hooks/staleTime.ts +0 -5
  1414. package/src/modules/feature_toggles/i18n/ko.json +0 -96
  1415. package/src/modules/inbox_ops/i18n/ko.json +0 -196
  1416. package/src/modules/inbox_ops/subscribers/search-reindex-proposal-created.ts +0 -39
  1417. package/src/modules/integrations/extension-points.ts +0 -27
  1418. package/src/modules/integrations/i18n/ko.json +0 -129
  1419. package/src/modules/integrations/widgets/injection/external-ids/widget.ts +0 -13
  1420. package/src/modules/messages/extension-points.ts +0 -13
  1421. package/src/modules/messages/i18n/ko.json +0 -263
  1422. package/src/modules/messages/lib/participantScope.ts +0 -64
  1423. package/src/modules/notifications/i18n/ko.json +0 -55
  1424. package/src/modules/notifications/lib/notificationScope.ts +0 -40
  1425. package/src/modules/payment_gateways/extension-points.ts +0 -16
  1426. package/src/modules/payment_gateways/i18n/ko.json +0 -87
  1427. package/src/modules/payment_gateways/lib/capture-ledger.ts +0 -260
  1428. package/src/modules/payment_gateways/lib/order-amount-reconciliation.ts +0 -93
  1429. package/src/modules/payment_gateways/migrations/Migration20260725101500_payment_gateways.ts +0 -21
  1430. package/src/modules/payment_gateways/migrations/Migration20260803103035_payment_gateways.ts +0 -17
  1431. package/src/modules/payment_gateways/workers/session-initialization-prune.ts +0 -63
  1432. package/src/modules/planner/i18n/ko.json +0 -565
  1433. package/src/modules/portal/extension-points.ts +0 -30
  1434. package/src/modules/portal/frontend/[orgSlug]/portal/invite/page.meta.ts +0 -9
  1435. package/src/modules/portal/frontend/[orgSlug]/portal/invite/page.tsx +0 -164
  1436. package/src/modules/portal/i18n/ko.json +0 -143
  1437. package/src/modules/portal/lib/navigation.ts +0 -3
  1438. package/src/modules/progress/i18n/ko.json +0 -20
  1439. package/src/modules/query_index/events.ts +0 -17
  1440. package/src/modules/query_index/extension-points.ts +0 -10
  1441. package/src/modules/query_index/i18n/ko.json +0 -69
  1442. package/src/modules/query_index/migrations/Migration20260731105052_query_index.ts +0 -35
  1443. package/src/modules/resources/extension-points.ts +0 -11
  1444. package/src/modules/resources/i18n/ko.json +0 -770
  1445. package/src/modules/resources/migrations/Migration20260608231000.ts +0 -13
  1446. package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +0 -198
  1447. package/src/modules/sales/extension-points.ts +0 -33
  1448. package/src/modules/sales/i18n/ko.json +0 -1442
  1449. package/src/modules/sales/services/paymentOrderTotalResolver.ts +0 -67
  1450. package/src/modules/shipping_carriers/i18n/ko.json +0 -85
  1451. package/src/modules/staff/i18n/ko.json +0 -1162
  1452. package/src/modules/sync_excel/i18n/ko.json +0 -107
  1453. package/src/modules/translations/i18n/ko.json +0 -45
  1454. package/src/modules/wms/extension-points.ts +0 -23
  1455. package/src/modules/wms/i18n/ko.json +0 -1053
  1456. package/src/modules/workflows/extension-points.ts +0 -12
  1457. package/src/modules/workflows/i18n/ko.json +0 -1204
  1458. package/src/modules/workflows/widgets/injection/order-approval/context-keys.ts +0 -18
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customer_accounts/lib/customerAuthServer.ts"],
4
- "sourcesContent": ["/**\n * Server-side customer auth helpers for Next.js server components.\n *\n * Uses the `cookies()` API from `next/headers` to read the customer auth token\n * from cookies \u2014 analogous to `getAuthFromCookies()` for staff auth.\n */\n\nimport { cookies } from 'next/headers'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { verifyAudienceJwt } from '@open-mercato/shared/lib/auth/jwt'\nimport { CUSTOMER_JWT_AUDIENCE, CustomerSessionService } from '@open-mercato/core/modules/customer_accounts/services/customerSessionService'\nimport { DomainMappingService } from '@open-mercato/core/modules/customer_accounts/services/domainMappingService'\nimport { tryNormalizeHostname } from '@open-mercato/core/modules/customer_accounts/lib/hostname'\nimport { platformDomains } from '@open-mercato/core/modules/customer_accounts/lib/platformDomains'\nimport { validateUserState } from './customerAuth'\nimport type { CustomerAuthContext } from './customerAuth'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('customer_accounts').child({ component: 'customer-auth-server' })\n\nexport type { CustomerAuthContext }\n\nasync function assertSessionStillActive(sessionId: string): Promise<boolean> {\n try {\n const container = await createRequestContainer()\n const service = container.resolve('customerSessionService') as InstanceType<typeof CustomerSessionService>\n const session = await service.findActiveSessionById(sessionId)\n return session !== null\n } catch {\n return false\n }\n}\n\n/**\n * Read and verify customer auth from cookies in server components.\n *\n * Returns the customer auth context if a valid customer JWT is found,\n * or null if not authenticated.\n *\n * @example\n * ```tsx\n * // In a server component or catch-all route\n * import { getCustomerAuthFromCookies } from '@open-mercato/core/modules/customer_accounts/lib/customerAuthServer'\n *\n * const customerAuth = await getCustomerAuthFromCookies()\n * if (!customerAuth) redirect('/login')\n * ```\n */\nexport async function getCustomerAuthFromCookies(\n options?: { expectedTenantId?: string },\n): Promise<CustomerAuthContext | null> {\n const cookieStore = await cookies()\n const token = cookieStore.get('customer_auth_token')?.value\n if (!token) return null\n\n try {\n const payload = verifyAudienceJwt(CUSTOMER_JWT_AUDIENCE, token) as Record<string, unknown> | null\n if (!payload) return null\n if (payload.type !== 'customer') return null\n const sid = typeof payload.sid === 'string' ? payload.sid : ''\n if (!sid) return null\n const tenantId = String(payload.tenantId)\n if (options?.expectedTenantId && options.expectedTenantId !== tenantId) {\n // Cross-host JWT replay defense. See spec rev 5 Customer Authentication\n // section: the host-resolved tenant is the authoritative scope; mismatched\n // JWTs are rejected as if unauthenticated.\n return null\n }\n const stillActive = await assertSessionStillActive(sid)\n if (!stillActive) return null\n\n const userState = await validateUserState(\n String(payload.sub),\n tenantId,\n String(payload.orgId),\n payload.iat,\n )\n if (!userState.valid) return null\n\n return {\n sub: String(payload.sub),\n sid,\n type: 'customer',\n tenantId,\n orgId: String(payload.orgId),\n email: String(payload.email || ''),\n displayName: String(payload.displayName || ''),\n customerEntityId: payload.customerEntityId ? String(payload.customerEntityId) : null,\n personEntityId: payload.personEntityId ? String(payload.personEntityId) : null,\n resolvedFeatures: userState.resolvedFeatures,\n isPortalAdmin: userState.isPortalAdmin,\n }\n } catch {\n // Invalid or expired JWT \u2014 treat as unauthenticated\n return null\n }\n}\n\n/**\n * Convenience wrapper for custom-domain pages: resolves the host, calls\n * getCustomerAuthFromCookies with the host-resolved tenant as expectedTenantId.\n *\n * Use from server components rendered under custom domains.\n */\nexport async function getCustomerAuthForHost(\n host: string | null | undefined,\n): Promise<CustomerAuthContext | null> {\n if (!host) return getCustomerAuthFromCookies()\n\n try {\n const hostname = tryNormalizeHostname(host)\n if (!hostname) return getCustomerAuthFromCookies()\n if (platformDomains().includes(hostname)) return getCustomerAuthFromCookies()\n\n const container = await createRequestContainer()\n const service = container.resolve('domainMappingService') as InstanceType<typeof DomainMappingService>\n const resolved = await service.resolveByHostname(hostname)\n if (!resolved || resolved.status !== 'active') return null\n return getCustomerAuthFromCookies({ expectedTenantId: resolved.tenantId })\n } catch (err) {\n logger.warn('Domain resolve failed; falling back to platform cookie', { err })\n return getCustomerAuthFromCookies()\n }\n}\n"],
5
- "mappings": "AAOA,SAAS,eAAe;AACxB,SAAS,8BAA8B;AACvC,SAAS,yBAAyB;AAClC,SAAS,6BAAqD;AAE9D,SAAS,4BAA4B;AACrC,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAElC,SAAS,oBAAoB;AAE7B,MAAM,SAAS,aAAa,mBAAmB,EAAE,MAAM,EAAE,WAAW,uBAAuB,CAAC;AAI5F,eAAe,yBAAyB,WAAqC;AAC3E,MAAI;AACF,UAAM,YAAY,MAAM,uBAAuB;AAC/C,UAAM,UAAU,UAAU,QAAQ,wBAAwB;AAC1D,UAAM,UAAU,MAAM,QAAQ,sBAAsB,SAAS;AAC7D,WAAO,YAAY;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAiBA,eAAsB,2BACpB,SACqC;AACrC,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,QAAQ,YAAY,IAAI,qBAAqB,GAAG;AACtD,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI;AACF,UAAM,UAAU,kBAAkB,uBAAuB,KAAK;AAC9D,QAAI,CAAC,QAAS,QAAO;AACrB,QAAI,QAAQ,SAAS,WAAY,QAAO;AACxC,UAAM,MAAM,OAAO,QAAQ,QAAQ,WAAW,QAAQ,MAAM;AAC5D,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,WAAW,OAAO,QAAQ,QAAQ;AACxC,QAAI,SAAS,oBAAoB,QAAQ,qBAAqB,UAAU;AAItE,aAAO;AAAA,IACT;AACA,UAAM,cAAc,MAAM,yBAAyB,GAAG;AACtD,QAAI,CAAC,YAAa,QAAO;AAEzB,UAAM,YAAY,MAAM;AAAA,MACtB,OAAO,QAAQ,GAAG;AAAA,MAClB;AAAA,MACA,OAAO,QAAQ,KAAK;AAAA,MACpB,QAAQ;AAAA,IACV;AACA,QAAI,CAAC,UAAU,MAAO,QAAO;AAE7B,WAAO;AAAA,MACL,KAAK,OAAO,QAAQ,GAAG;AAAA,MACvB;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA,OAAO,OAAO,QAAQ,KAAK;AAAA,MAC3B,OAAO,OAAO,QAAQ,SAAS,EAAE;AAAA,MACjC,aAAa,OAAO,QAAQ,eAAe,EAAE;AAAA,MAC7C,kBAAkB,QAAQ,mBAAmB,OAAO,QAAQ,gBAAgB,IAAI;AAAA,MAChF,gBAAgB,QAAQ,iBAAiB,OAAO,QAAQ,cAAc,IAAI;AAAA,MAC1E,kBAAkB,UAAU;AAAA,MAC5B,eAAe,UAAU;AAAA,IAC3B;AAAA,EACF,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,uBACpB,MACqC;AACrC,MAAI,CAAC,KAAM,QAAO,2BAA2B;AAE7C,MAAI;AACF,UAAM,WAAW,qBAAqB,IAAI;AAC1C,QAAI,CAAC,SAAU,QAAO,2BAA2B;AACjD,QAAI,gBAAgB,EAAE,SAAS,QAAQ,EAAG,QAAO,2BAA2B;AAE5E,UAAM,YAAY,MAAM,uBAAuB;AAC/C,UAAM,UAAU,UAAU,QAAQ,sBAAsB;AACxD,UAAM,WAAW,MAAM,QAAQ,kBAAkB,QAAQ;AACzD,QAAI,CAAC,YAAY,SAAS,WAAW,SAAU,QAAO;AACtD,WAAO,2BAA2B,EAAE,kBAAkB,SAAS,SAAS,CAAC;AAAA,EAC3E,SAAS,KAAK;AACZ,WAAO,KAAK,0DAA0D,EAAE,IAAI,CAAC;AAC7E,WAAO,2BAA2B;AAAA,EACpC;AACF;",
4
+ "sourcesContent": ["/**\n * Server-side customer auth helpers for Next.js server components.\n *\n * Uses the `cookies()` API from `next/headers` to read the customer auth token\n * from cookies \u2014 analogous to `getAuthFromCookies()` for staff auth.\n */\n\nimport { cookies } from 'next/headers'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { verifyAudienceJwt } from '@open-mercato/shared/lib/auth/jwt'\nimport { CUSTOMER_JWT_AUDIENCE, CustomerSessionService } from '@open-mercato/core/modules/customer_accounts/services/customerSessionService'\nimport { DomainMappingService } from '@open-mercato/core/modules/customer_accounts/services/domainMappingService'\nimport { tryNormalizeHostname } from '@open-mercato/core/modules/customer_accounts/lib/hostname'\nimport { platformDomains } from '@open-mercato/core/modules/customer_accounts/lib/platformDomains'\nimport { validateUserState } from './customerAuth'\nimport type { CustomerAuthContext } from './customerAuth'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('customer_accounts').child({ component: 'customer-auth-server' })\n\nexport type { CustomerAuthContext }\n\nasync function assertSessionStillActive(sessionId: string): Promise<boolean> {\n try {\n const container = await createRequestContainer()\n const service = container.resolve('customerSessionService') as InstanceType<typeof CustomerSessionService>\n const session = await service.findActiveSessionById(sessionId)\n return session !== null\n } catch {\n return false\n }\n}\n\n/**\n * Read and verify customer auth from cookies in server components.\n *\n * Returns the customer auth context if a valid customer JWT is found,\n * or null if not authenticated.\n *\n * @example\n * ```tsx\n * // In a server component or catch-all route\n * import { getCustomerAuthFromCookies } from '@open-mercato/core/modules/customer_accounts/lib/customerAuthServer'\n *\n * const customerAuth = await getCustomerAuthFromCookies()\n * if (!customerAuth) redirect('/login')\n * ```\n */\nexport async function getCustomerAuthFromCookies(\n options?: { expectedTenantId?: string },\n): Promise<CustomerAuthContext | null> {\n const cookieStore = await cookies()\n const token = cookieStore.get('customer_auth_token')?.value\n if (!token) return null\n\n try {\n const payload = verifyAudienceJwt(CUSTOMER_JWT_AUDIENCE, token) as Record<string, unknown> | null\n if (!payload) return null\n if (payload.type !== 'customer') return null\n const sid = typeof payload.sid === 'string' ? payload.sid : ''\n if (!sid) return null\n const tenantId = String(payload.tenantId)\n if (options?.expectedTenantId && options.expectedTenantId !== tenantId) {\n // Cross-host JWT replay defense. See spec rev 5 Customer Authentication\n // section: the host-resolved tenant is the authoritative scope; mismatched\n // JWTs are rejected as if unauthenticated.\n return null\n }\n const stillActive = await assertSessionStillActive(sid)\n if (!stillActive) return null\n\n const userState = await validateUserState(\n String(payload.sub),\n tenantId,\n String(payload.orgId),\n payload.iat,\n )\n if (!userState.valid) return null\n\n return {\n sub: String(payload.sub),\n sid,\n type: 'customer',\n tenantId,\n orgId: String(payload.orgId),\n email: String(payload.email || ''),\n displayName: String(payload.displayName || ''),\n customerEntityId: payload.customerEntityId ? String(payload.customerEntityId) : null,\n personEntityId: payload.personEntityId ? String(payload.personEntityId) : null,\n resolvedFeatures: userState.resolvedFeatures,\n }\n } catch {\n // Invalid or expired JWT \u2014 treat as unauthenticated\n return null\n }\n}\n\n/**\n * Convenience wrapper for custom-domain pages: resolves the host, calls\n * getCustomerAuthFromCookies with the host-resolved tenant as expectedTenantId.\n *\n * Use from server components rendered under custom domains.\n */\nexport async function getCustomerAuthForHost(\n host: string | null | undefined,\n): Promise<CustomerAuthContext | null> {\n if (!host) return getCustomerAuthFromCookies()\n\n try {\n const hostname = tryNormalizeHostname(host)\n if (!hostname) return getCustomerAuthFromCookies()\n if (platformDomains().includes(hostname)) return getCustomerAuthFromCookies()\n\n const container = await createRequestContainer()\n const service = container.resolve('domainMappingService') as InstanceType<typeof DomainMappingService>\n const resolved = await service.resolveByHostname(hostname)\n if (!resolved || resolved.status !== 'active') return null\n return getCustomerAuthFromCookies({ expectedTenantId: resolved.tenantId })\n } catch (err) {\n logger.warn('Domain resolve failed; falling back to platform cookie', { err })\n return getCustomerAuthFromCookies()\n }\n}\n"],
5
+ "mappings": "AAOA,SAAS,eAAe;AACxB,SAAS,8BAA8B;AACvC,SAAS,yBAAyB;AAClC,SAAS,6BAAqD;AAE9D,SAAS,4BAA4B;AACrC,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAElC,SAAS,oBAAoB;AAE7B,MAAM,SAAS,aAAa,mBAAmB,EAAE,MAAM,EAAE,WAAW,uBAAuB,CAAC;AAI5F,eAAe,yBAAyB,WAAqC;AAC3E,MAAI;AACF,UAAM,YAAY,MAAM,uBAAuB;AAC/C,UAAM,UAAU,UAAU,QAAQ,wBAAwB;AAC1D,UAAM,UAAU,MAAM,QAAQ,sBAAsB,SAAS;AAC7D,WAAO,YAAY;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAiBA,eAAsB,2BACpB,SACqC;AACrC,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,QAAQ,YAAY,IAAI,qBAAqB,GAAG;AACtD,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI;AACF,UAAM,UAAU,kBAAkB,uBAAuB,KAAK;AAC9D,QAAI,CAAC,QAAS,QAAO;AACrB,QAAI,QAAQ,SAAS,WAAY,QAAO;AACxC,UAAM,MAAM,OAAO,QAAQ,QAAQ,WAAW,QAAQ,MAAM;AAC5D,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,WAAW,OAAO,QAAQ,QAAQ;AACxC,QAAI,SAAS,oBAAoB,QAAQ,qBAAqB,UAAU;AAItE,aAAO;AAAA,IACT;AACA,UAAM,cAAc,MAAM,yBAAyB,GAAG;AACtD,QAAI,CAAC,YAAa,QAAO;AAEzB,UAAM,YAAY,MAAM;AAAA,MACtB,OAAO,QAAQ,GAAG;AAAA,MAClB;AAAA,MACA,OAAO,QAAQ,KAAK;AAAA,MACpB,QAAQ;AAAA,IACV;AACA,QAAI,CAAC,UAAU,MAAO,QAAO;AAE7B,WAAO;AAAA,MACL,KAAK,OAAO,QAAQ,GAAG;AAAA,MACvB;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA,OAAO,OAAO,QAAQ,KAAK;AAAA,MAC3B,OAAO,OAAO,QAAQ,SAAS,EAAE;AAAA,MACjC,aAAa,OAAO,QAAQ,eAAe,EAAE;AAAA,MAC7C,kBAAkB,QAAQ,mBAAmB,OAAO,QAAQ,gBAAgB,IAAI;AAAA,MAChF,gBAAgB,QAAQ,iBAAiB,OAAO,QAAQ,cAAc,IAAI;AAAA,MAC1E,kBAAkB,UAAU;AAAA,IAC9B;AAAA,EACF,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,uBACpB,MACqC;AACrC,MAAI,CAAC,KAAM,QAAO,2BAA2B;AAE7C,MAAI;AACF,UAAM,WAAW,qBAAqB,IAAI;AAC1C,QAAI,CAAC,SAAU,QAAO,2BAA2B;AACjD,QAAI,gBAAgB,EAAE,SAAS,QAAQ,EAAG,QAAO,2BAA2B;AAE5E,UAAM,YAAY,MAAM,uBAAuB;AAC/C,UAAM,UAAU,UAAU,QAAQ,sBAAsB;AACxD,UAAM,WAAW,MAAM,QAAQ,kBAAkB,QAAQ;AACzD,QAAI,CAAC,YAAY,SAAS,WAAW,SAAU,QAAO;AACtD,WAAO,2BAA2B,EAAE,kBAAkB,SAAS,SAAS,CAAC;AAAA,EAC3E,SAAS,KAAK;AACZ,WAAO,KAAK,0DAA0D,EAAE,IAAI,CAAC;AAC7E,WAAO,2BAA2B;AAAA,EACpC;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,38 +1,14 @@
1
1
  import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
2
2
  async function isOwnedCompanyEntity(em, customerEntityId, scope) {
3
- return isOwnedEntityOfKind(em, customerEntityId, "company", scope);
4
- }
5
- async function isOwnedPersonEntity(em, personEntityId, scope) {
6
- return isOwnedEntityOfKind(em, personEntityId, "person", scope);
7
- }
8
- async function resolveOwnedCompanyForPerson(em, personEntityId, scope) {
9
- const { CustomerPersonProfile } = await import("@open-mercato/core/modules/customers/data/entities");
10
- const profile = await em.findOne(CustomerPersonProfile, {
11
- entity: personEntityId,
12
- tenantId: scope.tenantId,
13
- organizationId: scope.organizationId
14
- });
15
- const candidate = readCompanyEntityId(profile);
16
- if (!candidate) return null;
17
- return await isOwnedCompanyEntity(em, candidate, scope) ? candidate : null;
18
- }
19
- function readCompanyEntityId(profile) {
20
- const company = profile?.company;
21
- if (!company) return null;
22
- if (typeof company === "string") return company;
23
- const id = company.id;
24
- return typeof id === "string" ? id : null;
25
- }
26
- async function isOwnedEntityOfKind(em, entityId, kind, scope) {
27
3
  const { CustomerEntity } = await import("@open-mercato/core/modules/customers/data/entities");
28
4
  const entity = await findOneWithDecryption(
29
5
  em,
30
6
  CustomerEntity,
31
7
  {
32
- id: entityId,
8
+ id: customerEntityId,
33
9
  tenantId: scope.tenantId,
34
10
  organizationId: scope.organizationId,
35
- kind,
11
+ kind: "company",
36
12
  deletedAt: null
37
13
  },
38
14
  void 0,
@@ -41,8 +17,6 @@ async function isOwnedEntityOfKind(em, entityId, kind, scope) {
41
17
  return !!entity;
42
18
  }
43
19
  export {
44
- isOwnedCompanyEntity,
45
- isOwnedPersonEntity,
46
- resolveOwnedCompanyForPerson
20
+ isOwnedCompanyEntity
47
21
  };
48
22
  //# sourceMappingURL=customerEntityOwnership.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customer_accounts/lib/customerEntityOwnership.ts"],
4
- "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nexport type CustomerEntityScope = {\n tenantId: string | null | undefined\n organizationId: string | null | undefined\n}\n\n/**\n * Confirms that a caller-supplied `customerEntityId` (the CRM company FK linked\n * onto a customer user) exists, is a company, is not soft-deleted, and belongs\n * to the caller's tenant and organization.\n *\n * Without this check an admin in org A could pass a company UUID from org B in\n * the same tenant and cross-link a customer user into another org's portal\n * context (#2693). The lookup is org-scoped to match how `CustomerEntity` rows\n * are created and listed.\n */\nexport async function isOwnedCompanyEntity(\n em: EntityManager,\n customerEntityId: string,\n scope: CustomerEntityScope,\n): Promise<boolean> {\n return isOwnedEntityOfKind(em, customerEntityId, 'company', scope)\n}\n\n/**\n * Confirms that a caller-supplied `personEntityId` (the CRM person FK linked\n * onto a customer user) exists, is a person, is not soft-deleted, and belongs\n * to the caller's tenant and organization.\n *\n * This is the symmetric guard to {@link isOwnedCompanyEntity}: the person FK is\n * copied onto the customer user on accept and short-circuits CRM auto-linking,\n * so an unvalidated id would permanently cross-link a portal user to another\n * org's person (the #4362/#2693 class of bug, on the person side).\n */\nexport async function isOwnedPersonEntity(\n em: EntityManager,\n personEntityId: string,\n scope: CustomerEntityScope,\n): Promise<boolean> {\n return isOwnedEntityOfKind(em, personEntityId, 'person', scope)\n}\n\n/**\n * Resolves the CRM company a person belongs to, but only when both the profile\n * lookup and the company itself stay inside the given tenant/organization scope.\n * Returns null when the person has no company or that company is out of scope.\n *\n * Both the invite route and the CRM auto-link subscriber need this answer, and\n * both write the result into `customerEntityId` \u2014 the portal company scope key \u2014\n * so they must agree on what counts as an in-scope company.\n */\nexport async function resolveOwnedCompanyForPerson(\n em: EntityManager,\n personEntityId: string,\n scope: CustomerEntityScope,\n): Promise<string | null> {\n const { CustomerPersonProfile } = await import('@open-mercato/core/modules/customers/data/entities')\n const profile = await em.findOne(CustomerPersonProfile as any, {\n entity: personEntityId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n } as any)\n const candidate = readCompanyEntityId(profile)\n if (!candidate) return null\n return (await isOwnedCompanyEntity(em, candidate, scope)) ? candidate : null\n}\n\n/**\n * `CustomerPersonProfile.company` is a relation on `company_entity_id`, not a\n * scalar \u2014 MikroORM hands back either the raw id or an entity reference, never a\n * `companyEntityId` property. Reading the wrong one silently yields undefined and\n * turns every company recovery into a clear.\n */\nfunction readCompanyEntityId(profile: unknown): string | null {\n const company = (profile as { company?: unknown } | null | undefined)?.company\n if (!company) return null\n if (typeof company === 'string') return company\n const id = (company as { id?: unknown }).id\n return typeof id === 'string' ? id : null\n}\n\nasync function isOwnedEntityOfKind(\n em: EntityManager,\n entityId: string,\n kind: 'company' | 'person',\n scope: CustomerEntityScope,\n): Promise<boolean> {\n const { CustomerEntity } = await import('@open-mercato/core/modules/customers/data/entities')\n const entity = await findOneWithDecryption(\n em,\n CustomerEntity,\n {\n id: entityId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n kind,\n deletedAt: null,\n } as any,\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n return !!entity\n}\n"],
5
- "mappings": "AACA,SAAS,6BAA6B;AAiBtC,eAAsB,qBACpB,IACA,kBACA,OACkB;AAClB,SAAO,oBAAoB,IAAI,kBAAkB,WAAW,KAAK;AACnE;AAYA,eAAsB,oBACpB,IACA,gBACA,OACkB;AAClB,SAAO,oBAAoB,IAAI,gBAAgB,UAAU,KAAK;AAChE;AAWA,eAAsB,6BACpB,IACA,gBACA,OACwB;AACxB,QAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,oDAAoD;AACnG,QAAM,UAAU,MAAM,GAAG,QAAQ,uBAA8B;AAAA,IAC7D,QAAQ;AAAA,IACR,UAAU,MAAM;AAAA,IAChB,gBAAgB,MAAM;AAAA,EACxB,CAAQ;AACR,QAAM,YAAY,oBAAoB,OAAO;AAC7C,MAAI,CAAC,UAAW,QAAO;AACvB,SAAQ,MAAM,qBAAqB,IAAI,WAAW,KAAK,IAAK,YAAY;AAC1E;AAQA,SAAS,oBAAoB,SAAiC;AAC5D,QAAM,UAAW,SAAsD;AACvE,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,QAAM,KAAM,QAA6B;AACzC,SAAO,OAAO,OAAO,WAAW,KAAK;AACvC;AAEA,eAAe,oBACb,IACA,UACA,MACA,OACkB;AAClB,QAAM,EAAE,eAAe,IAAI,MAAM,OAAO,oDAAoD;AAC5F,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB;AAAA,MACA,WAAW;AAAA,IACb;AAAA,IACA;AAAA,IACA,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,EACnE;AACA,SAAO,CAAC,CAAC;AACX;",
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nexport type CustomerEntityScope = {\n tenantId: string | null | undefined\n organizationId: string | null | undefined\n}\n\n/**\n * Confirms that a caller-supplied `customerEntityId` (the CRM company FK linked\n * onto a customer user) exists, is a company, is not soft-deleted, and belongs\n * to the caller's tenant and organization.\n *\n * Without this check an admin in org A could pass a company UUID from org B in\n * the same tenant and cross-link a customer user into another org's portal\n * context (#2693). The lookup is org-scoped to match how `CustomerEntity` rows\n * are created and listed.\n */\nexport async function isOwnedCompanyEntity(\n em: EntityManager,\n customerEntityId: string,\n scope: CustomerEntityScope,\n): Promise<boolean> {\n const { CustomerEntity } = await import('@open-mercato/core/modules/customers/data/entities')\n const entity = await findOneWithDecryption(\n em,\n CustomerEntity,\n {\n id: customerEntityId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n kind: 'company',\n deletedAt: null,\n } as any,\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n return !!entity\n}\n"],
5
+ "mappings": "AACA,SAAS,6BAA6B;AAiBtC,eAAsB,qBACpB,IACA,kBACA,OACkB;AAClB,QAAM,EAAE,eAAe,IAAI,MAAM,OAAO,oDAAoD;AAC5F,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAAA,IACA;AAAA,IACA,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,EACnE;AACA,SAAO,CAAC,CAAC;AACX;",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,4 @@
1
1
  import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
2
- import { Organization } from "@open-mercato/core/modules/directory/data/entities";
3
2
  function platformBaseUrl() {
4
3
  const fromEnv = process.env.PLATFORM_PORTAL_BASE_URL?.trim();
5
4
  if (fromEnv && fromEnv.length > 0) return fromEnv.replace(/\/+$/, "");
@@ -14,23 +13,6 @@ function resolveContainer(container) {
14
13
  if (container) return Promise.resolve(container);
15
14
  return createRequestContainer();
16
15
  }
17
- async function resolveOrgSlug(container, orgId) {
18
- try {
19
- const orgService = container.resolve("orgService");
20
- if (orgService && typeof orgService.findById === "function") {
21
- const org = await orgService.findById(orgId);
22
- return org?.slug ?? null;
23
- }
24
- } catch {
25
- }
26
- try {
27
- const em = container.resolve("em");
28
- const org = await em.findOne(Organization, { id: orgId, deletedAt: null });
29
- return org?.slug ?? null;
30
- } catch {
31
- return null;
32
- }
33
- }
34
16
  async function urlForCustomerOrg(orgId, path, options) {
35
17
  const safePath = path.startsWith("/") ? path : `/${path}`;
36
18
  const container = await resolveContainer(options?.container);
@@ -46,7 +28,16 @@ async function urlForCustomerOrg(orgId, path, options) {
46
28
  if (active && active.hostname) {
47
29
  return `https://${active.hostname}${safePath}`;
48
30
  }
49
- const orgSlug = await resolveOrgSlug(container, orgId);
31
+ let orgSlug = null;
32
+ try {
33
+ const orgService = container.resolve("orgService");
34
+ if (orgService && typeof orgService.findById === "function") {
35
+ const org = await orgService.findById(orgId);
36
+ orgSlug = org?.slug ?? null;
37
+ }
38
+ } catch {
39
+ orgSlug = null;
40
+ }
50
41
  const base = platformBaseUrl();
51
42
  if (orgSlug) return `${base}/${orgSlug}/portal${safePath}`;
52
43
  return `${base}${safePath}`;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customer_accounts/lib/customerUrl.ts"],
4
- "sourcesContent": ["// Build customer-portal URLs that honor the active custom domain when present.\n// All customer-facing email senders (signup welcome, magic link, password reset,\n// notification digests) MUST construct links via this helper instead of\n// hard-coding PLATFORM_PORTAL_BASE_URL \u2014 see customer_accounts/AGENTS.md.\n\nimport type { AppContainer } from '@open-mercato/shared/lib/di/container'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport type { EntityManager } from '@mikro-orm/postgresql'\n\ntype DomainMappingService = {\n resolveActiveByOrg(orgId: string): Promise<{ hostname: string } | null>\n}\n\ntype OrgService = {\n findById(orgId: string): Promise<{ id: string; slug: string | null } | null>\n}\n\ntype EntityManagerResolver = {\n resolve(name: 'em'): EntityManager\n}\n\nfunction platformBaseUrl(): string {\n const fromEnv = process.env.PLATFORM_PORTAL_BASE_URL?.trim()\n if (fromEnv && fromEnv.length > 0) return fromEnv.replace(/\\/+$/, '')\n // Outbound emails (welcome, magic link, password reset) embed this URL \u2014\n // localhost in production silently sends broken links to real customers.\n if (process.env.NODE_ENV === 'production') {\n throw new Error(\n 'PLATFORM_PORTAL_BASE_URL is required in production. Configure it before sending customer-portal emails.',\n )\n }\n return 'http://localhost:3000'\n}\n\nfunction resolveContainer(container?: AppContainer): Promise<AppContainer> {\n if (container) return Promise.resolve(container)\n return createRequestContainer()\n}\n\nasync function resolveOrgSlug(container: AppContainer, orgId: string): Promise<string | null> {\n try {\n const orgService = container.resolve('orgService') as OrgService | undefined\n if (orgService && typeof orgService.findById === 'function') {\n const org = await orgService.findById(orgId)\n return org?.slug ?? null\n }\n } catch {\n // orgService is optional in standalone/runtime contexts \u2014 fall through to EntityManager.\n }\n\n try {\n const em = (container as AppContainer & EntityManagerResolver).resolve('em')\n const org = await em.findOne(Organization, { id: orgId, deletedAt: null })\n return org?.slug ?? null\n } catch {\n return null\n }\n}\n\nexport async function urlForCustomerOrg(\n orgId: string,\n path: string,\n options?: { container?: AppContainer },\n): Promise<string> {\n const safePath = path.startsWith('/') ? path : `/${path}`\n const container = await resolveContainer(options?.container)\n\n let active: { hostname: string } | null = null\n try {\n const service = container.resolve('domainMappingService') as DomainMappingService\n if (service && typeof service.resolveActiveByOrg === 'function') {\n active = await service.resolveActiveByOrg(orgId)\n }\n } catch {\n // domainMappingService not registered yet (fresh installs, tests) \u2014 fall through to platform URL.\n active = null\n }\n\n if (active && active.hostname) {\n return `https://${active.hostname}${safePath}`\n }\n\n const orgSlug = await resolveOrgSlug(container, orgId)\n const base = platformBaseUrl()\n if (orgSlug) return `${base}/${orgSlug}/portal${safePath}`\n return `${base}${safePath}`\n}\n"],
5
- "mappings": "AAMA,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAe7B,SAAS,kBAA0B;AACjC,QAAM,UAAU,QAAQ,IAAI,0BAA0B,KAAK;AAC3D,MAAI,WAAW,QAAQ,SAAS,EAAG,QAAO,QAAQ,QAAQ,QAAQ,EAAE;AAGpE,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,WAAiD;AACzE,MAAI,UAAW,QAAO,QAAQ,QAAQ,SAAS;AAC/C,SAAO,uBAAuB;AAChC;AAEA,eAAe,eAAe,WAAyB,OAAuC;AAC5F,MAAI;AACF,UAAM,aAAa,UAAU,QAAQ,YAAY;AACjD,QAAI,cAAc,OAAO,WAAW,aAAa,YAAY;AAC3D,YAAM,MAAM,MAAM,WAAW,SAAS,KAAK;AAC3C,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,MAAI;AACF,UAAM,KAAM,UAAmD,QAAQ,IAAI;AAC3E,UAAM,MAAM,MAAM,GAAG,QAAQ,cAAc,EAAE,IAAI,OAAO,WAAW,KAAK,CAAC;AACzE,WAAO,KAAK,QAAQ;AAAA,EACtB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBACpB,OACA,MACA,SACiB;AACjB,QAAM,WAAW,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AACvD,QAAM,YAAY,MAAM,iBAAiB,SAAS,SAAS;AAE3D,MAAI,SAAsC;AAC1C,MAAI;AACF,UAAM,UAAU,UAAU,QAAQ,sBAAsB;AACxD,QAAI,WAAW,OAAO,QAAQ,uBAAuB,YAAY;AAC/D,eAAS,MAAM,QAAQ,mBAAmB,KAAK;AAAA,IACjD;AAAA,EACF,QAAQ;AAEN,aAAS;AAAA,EACX;AAEA,MAAI,UAAU,OAAO,UAAU;AAC7B,WAAO,WAAW,OAAO,QAAQ,GAAG,QAAQ;AAAA,EAC9C;AAEA,QAAM,UAAU,MAAM,eAAe,WAAW,KAAK;AACrD,QAAM,OAAO,gBAAgB;AAC7B,MAAI,QAAS,QAAO,GAAG,IAAI,IAAI,OAAO,UAAU,QAAQ;AACxD,SAAO,GAAG,IAAI,GAAG,QAAQ;AAC3B;",
4
+ "sourcesContent": ["// Build customer-portal URLs that honor the active custom domain when present.\n// All customer-facing email senders (signup welcome, magic link, password reset,\n// notification digests) MUST construct links via this helper instead of\n// hard-coding PLATFORM_PORTAL_BASE_URL \u2014 see customer_accounts/AGENTS.md.\n\nimport type { AppContainer } from '@open-mercato/shared/lib/di/container'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\n\ntype DomainMappingService = {\n resolveActiveByOrg(orgId: string): Promise<{ hostname: string } | null>\n}\n\ntype OrgService = {\n findById(orgId: string): Promise<{ id: string; slug: string | null } | null>\n}\n\nfunction platformBaseUrl(): string {\n const fromEnv = process.env.PLATFORM_PORTAL_BASE_URL?.trim()\n if (fromEnv && fromEnv.length > 0) return fromEnv.replace(/\\/+$/, '')\n // Outbound emails (welcome, magic link, password reset) embed this URL \u2014\n // localhost in production silently sends broken links to real customers.\n if (process.env.NODE_ENV === 'production') {\n throw new Error(\n 'PLATFORM_PORTAL_BASE_URL is required in production. Configure it before sending customer-portal emails.',\n )\n }\n return 'http://localhost:3000'\n}\n\nfunction resolveContainer(container?: AppContainer): Promise<AppContainer> {\n if (container) return Promise.resolve(container)\n return createRequestContainer()\n}\n\nexport async function urlForCustomerOrg(\n orgId: string,\n path: string,\n options?: { container?: AppContainer },\n): Promise<string> {\n const safePath = path.startsWith('/') ? path : `/${path}`\n const container = await resolveContainer(options?.container)\n\n let active: { hostname: string } | null = null\n try {\n const service = container.resolve('domainMappingService') as DomainMappingService\n if (service && typeof service.resolveActiveByOrg === 'function') {\n active = await service.resolveActiveByOrg(orgId)\n }\n } catch {\n // domainMappingService not registered yet (fresh installs, tests) \u2014 fall through to platform URL.\n active = null\n }\n\n if (active && active.hostname) {\n return `https://${active.hostname}${safePath}`\n }\n\n let orgSlug: string | null = null\n try {\n const orgService = container.resolve('orgService') as OrgService | undefined\n if (orgService && typeof orgService.findById === 'function') {\n const org = await orgService.findById(orgId)\n orgSlug = org?.slug ?? null\n }\n } catch {\n orgSlug = null\n }\n\n const base = platformBaseUrl()\n if (orgSlug) return `${base}/${orgSlug}/portal${safePath}`\n return `${base}${safePath}`\n}\n"],
5
+ "mappings": "AAMA,SAAS,8BAA8B;AAUvC,SAAS,kBAA0B;AACjC,QAAM,UAAU,QAAQ,IAAI,0BAA0B,KAAK;AAC3D,MAAI,WAAW,QAAQ,SAAS,EAAG,QAAO,QAAQ,QAAQ,QAAQ,EAAE;AAGpE,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,WAAiD;AACzE,MAAI,UAAW,QAAO,QAAQ,QAAQ,SAAS;AAC/C,SAAO,uBAAuB;AAChC;AAEA,eAAsB,kBACpB,OACA,MACA,SACiB;AACjB,QAAM,WAAW,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AACvD,QAAM,YAAY,MAAM,iBAAiB,SAAS,SAAS;AAE3D,MAAI,SAAsC;AAC1C,MAAI;AACF,UAAM,UAAU,UAAU,QAAQ,sBAAsB;AACxD,QAAI,WAAW,OAAO,QAAQ,uBAAuB,YAAY;AAC/D,eAAS,MAAM,QAAQ,mBAAmB,KAAK;AAAA,IACjD;AAAA,EACF,QAAQ;AAEN,aAAS;AAAA,EACX;AAEA,MAAI,UAAU,OAAO,UAAU;AAC7B,WAAO,WAAW,OAAO,QAAQ,GAAG,QAAQ;AAAA,EAC9C;AAEA,MAAI,UAAyB;AAC7B,MAAI;AACF,UAAM,aAAa,UAAU,QAAQ,YAAY;AACjD,QAAI,cAAc,OAAO,WAAW,aAAa,YAAY;AAC3D,YAAM,MAAM,MAAM,WAAW,SAAS,KAAK;AAC3C,gBAAU,KAAK,QAAQ;AAAA,IACzB;AAAA,EACF,QAAQ;AACN,cAAU;AAAA,EACZ;AAEA,QAAM,OAAO,gBAAgB;AAC7B,MAAI,QAAS,QAAO,GAAG,IAAI,IAAI,OAAO,UAAU,QAAQ;AACxD,SAAO,GAAG,IAAI,GAAG,QAAQ;AAC3B;",
6
6
  "names": []
7
7
  }
@@ -35,28 +35,16 @@ class CustomerInvitationService {
35
35
  { tenantId: scope.tenantId, organizationId: scope.organizationId }
36
36
  );
37
37
  if (existing) {
38
- const rollbackState = {
39
- email: existing.email,
40
- token: existing.token,
41
- customerEntityId: existing.customerEntityId ?? null,
42
- personEntityId: existing.personEntityId ?? null,
43
- roleIdsJson: [...existing.roleIdsJson ?? []],
44
- invitedByUserId: existing.invitedByUserId ?? null,
45
- invitedByCustomerUserId: existing.invitedByCustomerUserId ?? null,
46
- displayName: existing.displayName ?? null,
47
- expiresAt: new Date(existing.expiresAt)
48
- };
49
38
  existing.email = normalizedEmail;
50
39
  existing.token = tokenHashed;
51
40
  existing.customerEntityId = options.customerEntityId || null;
52
- existing.personEntityId = options.personEntityId || null;
53
41
  existing.roleIdsJson = options.roleIds;
54
42
  existing.invitedByUserId = options.invitedByUserId || null;
55
43
  existing.invitedByCustomerUserId = options.invitedByCustomerUserId || null;
56
44
  existing.displayName = options.displayName || null;
57
45
  existing.expiresAt = expiresAt;
58
46
  await this.em.flush();
59
- return { invitation: existing, rawToken: token, reused: true, rollbackState };
47
+ return { invitation: existing, rawToken: token };
60
48
  }
61
49
  const invitation = this.em.create(CustomerUserInvitation, {
62
50
  tenantId: scope.tenantId,
@@ -65,7 +53,6 @@ class CustomerInvitationService {
65
53
  emailHash,
66
54
  token: tokenHashed,
67
55
  customerEntityId: options.customerEntityId || null,
68
- personEntityId: options.personEntityId || null,
69
56
  roleIdsJson: options.roleIds,
70
57
  invitedByUserId: options.invitedByUserId || null,
71
58
  invitedByCustomerUserId: options.invitedByCustomerUserId || null,
@@ -74,23 +61,7 @@ class CustomerInvitationService {
74
61
  createdAt: /* @__PURE__ */ new Date()
75
62
  });
76
63
  await this.em.persist(invitation).flush();
77
- return { invitation, rawToken: token, reused: false, rollbackState: null };
78
- }
79
- async rollbackInvitation(invitation, rollbackState) {
80
- if (!rollbackState) {
81
- await this.em.remove(invitation).flush();
82
- return;
83
- }
84
- invitation.email = rollbackState.email;
85
- invitation.token = rollbackState.token;
86
- invitation.customerEntityId = rollbackState.customerEntityId;
87
- invitation.personEntityId = rollbackState.personEntityId;
88
- invitation.roleIdsJson = [...rollbackState.roleIdsJson];
89
- invitation.invitedByUserId = rollbackState.invitedByUserId;
90
- invitation.invitedByCustomerUserId = rollbackState.invitedByCustomerUserId;
91
- invitation.displayName = rollbackState.displayName;
92
- invitation.expiresAt = new Date(rollbackState.expiresAt);
93
- await this.em.flush();
64
+ return { invitation, rawToken: token };
94
65
  }
95
66
  async findByToken(token) {
96
67
  const tokenHashed = hashToken(token);
@@ -118,7 +89,6 @@ class CustomerInvitationService {
118
89
  tenantId: invitation.tenantId,
119
90
  organizationId: invitation.organizationId,
120
91
  customerEntityId: invitation.customerEntityId || null,
121
- personEntityId: invitation.personEntityId || null,
122
92
  isActive: true,
123
93
  emailVerifiedAt: /* @__PURE__ */ new Date(),
124
94
  // Invitation implicitly verifies email
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customer_accounts/services/customerInvitationService.ts"],
4
- "sourcesContent": ["import { EntityManager } from '@mikro-orm/postgresql'\nimport { hash } from 'bcryptjs'\nimport {\n CustomerUser,\n CustomerUserInvitation,\n CustomerUserRole,\n CustomerRole,\n} from '@open-mercato/core/modules/customer_accounts/data/entities'\nimport { generateSecureToken, hashToken } from '@open-mercato/core/modules/customer_accounts/lib/tokenGenerator'\nimport { hashForLookup } from '@open-mercato/shared/lib/encryption/aes'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nconst BCRYPT_COST = 10\nconst INVITATION_TTL_MS = 72 * 60 * 60 * 1000 // 72 hours\n\nexport type CustomerInvitationRollbackState = {\n email: string\n token: string\n customerEntityId: string | null\n personEntityId: string | null\n roleIdsJson: string[]\n invitedByUserId: string | null\n invitedByCustomerUserId: string | null\n displayName: string | null\n expiresAt: Date\n}\n\nexport class CustomerInvitationService {\n constructor(private em: EntityManager) {}\n\n async createInvitation(\n email: string,\n scope: { tenantId: string; organizationId: string },\n options: {\n customerEntityId?: string | null\n personEntityId?: string | null\n roleIds: string[]\n invitedByUserId?: string | null\n invitedByCustomerUserId?: string | null\n displayName?: string | null\n },\n ): Promise<{\n invitation: CustomerUserInvitation\n rawToken: string\n reused: boolean\n rollbackState: CustomerInvitationRollbackState | null\n }> {\n const token = generateSecureToken()\n const emailHash = hashForLookup(email)\n const normalizedEmail = email.toLowerCase().trim()\n const expiresAt = new Date(Date.now() + INVITATION_TTL_MS)\n const tokenHashed = hashToken(token)\n\n // Dedupe: reuse an existing pending (not accepted, not cancelled, unexpired)\n // invitation for the same recipient instead of inserting a new row. This caps\n // row/token growth and keeps a single live token per concurrently-pending\n // (tenant, organization, email) tuple.\n const existing = await findOneWithDecryption(\n this.em,\n CustomerUserInvitation,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n emailHash,\n acceptedAt: null,\n cancelledAt: null,\n expiresAt: { $gt: new Date() },\n } as any,\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n\n if (existing) {\n const rollbackState: CustomerInvitationRollbackState = {\n email: existing.email,\n token: existing.token,\n customerEntityId: existing.customerEntityId ?? null,\n personEntityId: existing.personEntityId ?? null,\n roleIdsJson: [...(existing.roleIdsJson ?? [])],\n invitedByUserId: existing.invitedByUserId ?? null,\n invitedByCustomerUserId: existing.invitedByCustomerUserId ?? null,\n displayName: existing.displayName ?? null,\n expiresAt: new Date(existing.expiresAt),\n }\n existing.email = normalizedEmail\n existing.token = tokenHashed\n existing.customerEntityId = options.customerEntityId || null\n existing.personEntityId = options.personEntityId || null\n existing.roleIdsJson = options.roleIds\n existing.invitedByUserId = options.invitedByUserId || null\n existing.invitedByCustomerUserId = options.invitedByCustomerUserId || null\n existing.displayName = options.displayName || null\n existing.expiresAt = expiresAt\n await this.em.flush()\n return { invitation: existing, rawToken: token, reused: true, rollbackState }\n }\n\n const invitation = this.em.create(CustomerUserInvitation, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n email: normalizedEmail,\n emailHash,\n token: tokenHashed,\n customerEntityId: options.customerEntityId || null,\n personEntityId: options.personEntityId || null,\n roleIdsJson: options.roleIds,\n invitedByUserId: options.invitedByUserId || null,\n invitedByCustomerUserId: options.invitedByCustomerUserId || null,\n displayName: options.displayName || null,\n expiresAt,\n createdAt: new Date(),\n } as any) as CustomerUserInvitation\n await this.em.persist(invitation).flush()\n return { invitation, rawToken: token, reused: false, rollbackState: null }\n }\n\n async rollbackInvitation(\n invitation: CustomerUserInvitation,\n rollbackState: CustomerInvitationRollbackState | null,\n ): Promise<void> {\n if (!rollbackState) {\n await this.em.remove(invitation).flush()\n return\n }\n\n invitation.email = rollbackState.email\n invitation.token = rollbackState.token\n invitation.customerEntityId = rollbackState.customerEntityId\n invitation.personEntityId = rollbackState.personEntityId\n invitation.roleIdsJson = [...rollbackState.roleIdsJson]\n invitation.invitedByUserId = rollbackState.invitedByUserId\n invitation.invitedByCustomerUserId = rollbackState.invitedByCustomerUserId\n invitation.displayName = rollbackState.displayName\n invitation.expiresAt = new Date(rollbackState.expiresAt)\n await this.em.flush()\n }\n\n async findByToken(token: string): Promise<CustomerUserInvitation | null> {\n const tokenHashed = hashToken(token)\n const invitation = await findOneWithDecryption(\n this.em,\n CustomerUserInvitation,\n { token: tokenHashed } as any,\n )\n if (!invitation) return null\n if (invitation.acceptedAt) return null\n if (invitation.cancelledAt) return null\n if (invitation.expiresAt.getTime() < Date.now()) return null\n return invitation\n }\n\n async acceptInvitation(\n token: string,\n password: string,\n displayName: string,\n ): Promise<{ user: CustomerUser; invitation: CustomerUserInvitation } | null> {\n const invitation = await this.findByToken(token)\n if (!invitation) return null\n\n const passwordHash = await hash(password, BCRYPT_COST)\n const emailHash = hashForLookup(invitation.email)\n\n // Create user\n const user = this.em.create(CustomerUser, {\n email: invitation.email,\n emailHash,\n passwordHash,\n displayName: displayName || invitation.displayName || invitation.email,\n tenantId: invitation.tenantId,\n organizationId: invitation.organizationId,\n customerEntityId: invitation.customerEntityId || null,\n personEntityId: invitation.personEntityId || null,\n isActive: true,\n emailVerifiedAt: new Date(), // Invitation implicitly verifies email\n failedLoginAttempts: 0,\n createdAt: new Date(),\n } as any) as CustomerUser\n this.em.persist(user)\n\n // Assign roles\n const roleIds = Array.isArray(invitation.roleIdsJson) ? invitation.roleIdsJson : []\n const roles = roleIds.length > 0\n ? await findWithDecryption(\n this.em,\n CustomerRole,\n {\n id: { $in: roleIds } as any,\n tenantId: invitation.tenantId,\n organizationId: invitation.organizationId,\n deletedAt: null,\n } as any,\n undefined,\n { tenantId: invitation.tenantId, organizationId: invitation.organizationId },\n )\n : []\n for (const role of roles) {\n const userRole = this.em.create(CustomerUserRole, {\n user,\n role,\n createdAt: new Date(),\n } as any)\n this.em.persist(userRole)\n }\n\n // Mark invitation as accepted\n invitation.acceptedAt = new Date()\n\n await this.em.flush()\n return { user, invitation }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { EntityManager } from '@mikro-orm/postgresql'\nimport { hash } from 'bcryptjs'\nimport {\n CustomerUser,\n CustomerUserInvitation,\n CustomerUserRole,\n CustomerRole,\n} from '@open-mercato/core/modules/customer_accounts/data/entities'\nimport { generateSecureToken, hashToken } from '@open-mercato/core/modules/customer_accounts/lib/tokenGenerator'\nimport { hashForLookup } from '@open-mercato/shared/lib/encryption/aes'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nconst BCRYPT_COST = 10\nconst INVITATION_TTL_MS = 72 * 60 * 60 * 1000 // 72 hours\n\nexport class CustomerInvitationService {\n constructor(private em: EntityManager) {}\n\n async createInvitation(\n email: string,\n scope: { tenantId: string; organizationId: string },\n options: {\n customerEntityId?: string | null\n roleIds: string[]\n invitedByUserId?: string | null\n invitedByCustomerUserId?: string | null\n displayName?: string | null\n },\n ): Promise<{ invitation: CustomerUserInvitation; rawToken: string }> {\n const token = generateSecureToken()\n const emailHash = hashForLookup(email)\n const normalizedEmail = email.toLowerCase().trim()\n const expiresAt = new Date(Date.now() + INVITATION_TTL_MS)\n const tokenHashed = hashToken(token)\n\n // Dedupe: reuse an existing pending (not accepted, not cancelled, unexpired)\n // invitation for the same recipient instead of inserting a new row. This caps\n // row/token growth and keeps a single live token per concurrently-pending\n // (tenant, organization, email) tuple.\n const existing = await findOneWithDecryption(\n this.em,\n CustomerUserInvitation,\n {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n emailHash,\n acceptedAt: null,\n cancelledAt: null,\n expiresAt: { $gt: new Date() },\n } as any,\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n\n if (existing) {\n existing.email = normalizedEmail\n existing.token = tokenHashed\n existing.customerEntityId = options.customerEntityId || null\n existing.roleIdsJson = options.roleIds\n existing.invitedByUserId = options.invitedByUserId || null\n existing.invitedByCustomerUserId = options.invitedByCustomerUserId || null\n existing.displayName = options.displayName || null\n existing.expiresAt = expiresAt\n await this.em.flush()\n return { invitation: existing, rawToken: token }\n }\n\n const invitation = this.em.create(CustomerUserInvitation, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n email: normalizedEmail,\n emailHash,\n token: tokenHashed,\n customerEntityId: options.customerEntityId || null,\n roleIdsJson: options.roleIds,\n invitedByUserId: options.invitedByUserId || null,\n invitedByCustomerUserId: options.invitedByCustomerUserId || null,\n displayName: options.displayName || null,\n expiresAt,\n createdAt: new Date(),\n } as any) as CustomerUserInvitation\n await this.em.persist(invitation).flush()\n return { invitation, rawToken: token }\n }\n\n async findByToken(token: string): Promise<CustomerUserInvitation | null> {\n const tokenHashed = hashToken(token)\n const invitation = await findOneWithDecryption(\n this.em,\n CustomerUserInvitation,\n { token: tokenHashed } as any,\n )\n if (!invitation) return null\n if (invitation.acceptedAt) return null\n if (invitation.cancelledAt) return null\n if (invitation.expiresAt.getTime() < Date.now()) return null\n return invitation\n }\n\n async acceptInvitation(\n token: string,\n password: string,\n displayName: string,\n ): Promise<{ user: CustomerUser; invitation: CustomerUserInvitation } | null> {\n const invitation = await this.findByToken(token)\n if (!invitation) return null\n\n const passwordHash = await hash(password, BCRYPT_COST)\n const emailHash = hashForLookup(invitation.email)\n\n // Create user\n const user = this.em.create(CustomerUser, {\n email: invitation.email,\n emailHash,\n passwordHash,\n displayName: displayName || invitation.displayName || invitation.email,\n tenantId: invitation.tenantId,\n organizationId: invitation.organizationId,\n customerEntityId: invitation.customerEntityId || null,\n isActive: true,\n emailVerifiedAt: new Date(), // Invitation implicitly verifies email\n failedLoginAttempts: 0,\n createdAt: new Date(),\n } as any) as CustomerUser\n this.em.persist(user)\n\n // Assign roles\n const roleIds = Array.isArray(invitation.roleIdsJson) ? invitation.roleIdsJson : []\n const roles = roleIds.length > 0\n ? await findWithDecryption(\n this.em,\n CustomerRole,\n {\n id: { $in: roleIds } as any,\n tenantId: invitation.tenantId,\n organizationId: invitation.organizationId,\n deletedAt: null,\n } as any,\n undefined,\n { tenantId: invitation.tenantId, organizationId: invitation.organizationId },\n )\n : []\n for (const role of roles) {\n const userRole = this.em.create(CustomerUserRole, {\n user,\n role,\n createdAt: new Date(),\n } as any)\n this.em.persist(userRole)\n }\n\n // Mark invitation as accepted\n invitation.acceptedAt = new Date()\n\n await this.em.flush()\n return { user, invitation }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,10 +3,7 @@ import {
3
3
  CustomerRoleAcl,
4
4
  CustomerUserRole
5
5
  } from "@open-mercato/core/modules/customer_accounts/data/entities";
6
- import {
7
- authorizeFeatures,
8
- resolveEffectiveFeatures
9
- } from "@open-mercato/shared/security/featurePolicy";
6
+ import { hasAllFeatures } from "@open-mercato/shared/lib/auth/featureMatch";
10
7
  function isCustomerAclData(value) {
11
8
  if (typeof value !== "object" || value === null) return false;
12
9
  const record = value;
@@ -95,14 +92,8 @@ class CustomerRbacService {
95
92
  async userHasAllFeatures(userId, required, scope) {
96
93
  if (!required.length) return true;
97
94
  const acl = await this.loadAcl(userId, scope);
98
- return authorizeFeatures(required, {
99
- grantedFeatures: acl.features,
100
- unrestricted: acl.isPortalAdmin
101
- });
102
- }
103
- async getEffectiveFeatures(userId, scope) {
104
- const acl = await this.loadAcl(userId, scope);
105
- return resolveEffectiveFeatures(acl.isPortalAdmin ? ["portal.*"] : acl.features);
95
+ if (acl.isPortalAdmin) return true;
96
+ return hasAllFeatures(required, acl.features);
106
97
  }
107
98
  async invalidateUserCache(userId) {
108
99
  if (!this.cache) return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customer_accounts/services/customerRbacService.ts"],
4
- "sourcesContent": ["import { EntityManager } from '@mikro-orm/postgresql'\nimport type { CacheStrategy } from '@open-mercato/cache'\nimport {\n CustomerUserAcl,\n CustomerRoleAcl,\n CustomerUserRole,\n} from '@open-mercato/core/modules/customer_accounts/data/entities'\nimport {\n authorizeFeatures,\n resolveEffectiveFeatures,\n} from '@open-mercato/shared/security/featurePolicy'\n\ninterface CustomerAclData {\n isPortalAdmin: boolean\n features: string[]\n}\n\nfunction isCustomerAclData(value: unknown): value is CustomerAclData {\n if (typeof value !== 'object' || value === null) return false\n const record = value as Partial<CustomerAclData>\n if (typeof record.isPortalAdmin !== 'boolean') return false\n if (!Array.isArray(record.features) || record.features.some((f) => typeof f !== 'string')) return false\n return true\n}\n\nexport class CustomerRbacService {\n private cacheTtlMs: number = 5 * 60 * 1000\n private cache: CacheStrategy | null = null\n\n constructor(private em: EntityManager, cache?: CacheStrategy) {\n this.cache = cache || null\n }\n\n private getCacheKey(userId: string, scope: { tenantId: string; organizationId: string }): string {\n // Keep the authorization query versioned in the key so cache entries created\n // before scope hardening cannot preserve grants that are no longer valid.\n return `customer_rbac:v2:${userId}:${scope.tenantId}:${scope.organizationId}`\n }\n\n private getUserTag(userId: string): string {\n return `customer_rbac:user:${userId}`\n }\n\n private getTenantTag(tenantId: string): string {\n return `customer_rbac:tenant:${tenantId}`\n }\n\n private async getFromCache(cacheKey: string): Promise<CustomerAclData | null> {\n if (!this.cache) return null\n const cached = await this.cache.get(cacheKey)\n if (!cached) return null\n return isCustomerAclData(cached) ? cached : null\n }\n\n private async setCache(\n cacheKey: string,\n data: CustomerAclData,\n userId: string,\n scope: { tenantId: string; organizationId: string },\n ): Promise<void> {\n if (!this.cache) return\n const tags = [\n this.getUserTag(userId),\n this.getTenantTag(scope.tenantId),\n 'customer_rbac:all',\n ]\n await this.cache.set(cacheKey, data, { ttl: this.cacheTtlMs, tags })\n }\n\n async loadAcl(\n userId: string,\n scope: { tenantId: string; organizationId: string },\n ): Promise<CustomerAclData> {\n const cacheKey = this.getCacheKey(userId, scope)\n const cached = await this.getFromCache(cacheKey)\n if (cached) return cached\n\n const em = this.em.fork()\n\n // Per-user ACL first\n const userAcl = await em.findOne(CustomerUserAcl, {\n user: userId as any,\n tenantId: scope.tenantId,\n })\n if (userAcl) {\n const result: CustomerAclData = {\n isPortalAdmin: !!userAcl.isPortalAdmin,\n features: Array.isArray(userAcl.featuresJson) ? userAcl.featuresJson : [],\n }\n await this.setCache(cacheKey, result, userId, scope)\n return result\n }\n\n // Aggregate role ACLs\n const links = await em.find(CustomerUserRole, {\n user: userId as any,\n role: {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n deletedAt: null,\n },\n deletedAt: null,\n } as any, { populate: ['role'] })\n const roleIds = links.map((l) => (l.role as any)?.id).filter(Boolean)\n\n let isPortalAdmin = false\n const features: string[] = []\n if (roleIds.length) {\n const roleAcls = await em.find(CustomerRoleAcl, {\n tenantId: scope.tenantId,\n role: { $in: roleIds as any },\n } as any)\n for (const acl of roleAcls) {\n isPortalAdmin = isPortalAdmin || !!acl.isPortalAdmin\n if (Array.isArray(acl.featuresJson)) {\n for (const f of acl.featuresJson) {\n if (!features.includes(f)) features.push(f)\n }\n }\n }\n }\n\n const result: CustomerAclData = { isPortalAdmin, features }\n await this.setCache(cacheKey, result, userId, scope)\n return result\n }\n\n async userHasAllFeatures(\n userId: string,\n required: string[],\n scope: { tenantId: string; organizationId: string },\n ): Promise<boolean> {\n if (!required.length) return true\n const acl = await this.loadAcl(userId, scope)\n return authorizeFeatures(required, {\n grantedFeatures: acl.features,\n unrestricted: acl.isPortalAdmin,\n })\n }\n\n async getEffectiveFeatures(\n userId: string,\n scope: { tenantId: string; organizationId: string },\n ): Promise<string[]> {\n const acl = await this.loadAcl(userId, scope)\n return resolveEffectiveFeatures(acl.isPortalAdmin ? ['portal.*'] : acl.features)\n }\n\n async invalidateUserCache(userId: string): Promise<void> {\n if (!this.cache) return\n await this.cache.deleteByTags([this.getUserTag(userId)])\n }\n\n async invalidateRoleCache(roleId: string): Promise<void> {\n if (!this.cache) return\n // When a role changes, invalidate all customer RBAC caches since we don't track role\u2192user mappings\n await this.cache.deleteByTags(['customer_rbac:all'])\n }\n\n async invalidateTenantCache(tenantId: string): Promise<void> {\n if (!this.cache) return\n await this.cache.deleteByTags([this.getTenantTag(tenantId)])\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { EntityManager } from '@mikro-orm/postgresql'\nimport type { CacheStrategy } from '@open-mercato/cache'\nimport {\n CustomerUserAcl,\n CustomerRoleAcl,\n CustomerUserRole,\n} from '@open-mercato/core/modules/customer_accounts/data/entities'\nimport { hasAllFeatures } from '@open-mercato/shared/lib/auth/featureMatch'\n\ninterface CustomerAclData {\n isPortalAdmin: boolean\n features: string[]\n}\n\nfunction isCustomerAclData(value: unknown): value is CustomerAclData {\n if (typeof value !== 'object' || value === null) return false\n const record = value as Partial<CustomerAclData>\n if (typeof record.isPortalAdmin !== 'boolean') return false\n if (!Array.isArray(record.features) || record.features.some((f) => typeof f !== 'string')) return false\n return true\n}\n\nexport class CustomerRbacService {\n private cacheTtlMs: number = 5 * 60 * 1000\n private cache: CacheStrategy | null = null\n\n constructor(private em: EntityManager, cache?: CacheStrategy) {\n this.cache = cache || null\n }\n\n private getCacheKey(userId: string, scope: { tenantId: string; organizationId: string }): string {\n // Keep the authorization query versioned in the key so cache entries created\n // before scope hardening cannot preserve grants that are no longer valid.\n return `customer_rbac:v2:${userId}:${scope.tenantId}:${scope.organizationId}`\n }\n\n private getUserTag(userId: string): string {\n return `customer_rbac:user:${userId}`\n }\n\n private getTenantTag(tenantId: string): string {\n return `customer_rbac:tenant:${tenantId}`\n }\n\n private async getFromCache(cacheKey: string): Promise<CustomerAclData | null> {\n if (!this.cache) return null\n const cached = await this.cache.get(cacheKey)\n if (!cached) return null\n return isCustomerAclData(cached) ? cached : null\n }\n\n private async setCache(\n cacheKey: string,\n data: CustomerAclData,\n userId: string,\n scope: { tenantId: string; organizationId: string },\n ): Promise<void> {\n if (!this.cache) return\n const tags = [\n this.getUserTag(userId),\n this.getTenantTag(scope.tenantId),\n 'customer_rbac:all',\n ]\n await this.cache.set(cacheKey, data, { ttl: this.cacheTtlMs, tags })\n }\n\n async loadAcl(\n userId: string,\n scope: { tenantId: string; organizationId: string },\n ): Promise<CustomerAclData> {\n const cacheKey = this.getCacheKey(userId, scope)\n const cached = await this.getFromCache(cacheKey)\n if (cached) return cached\n\n const em = this.em.fork()\n\n // Per-user ACL first\n const userAcl = await em.findOne(CustomerUserAcl, {\n user: userId as any,\n tenantId: scope.tenantId,\n })\n if (userAcl) {\n const result: CustomerAclData = {\n isPortalAdmin: !!userAcl.isPortalAdmin,\n features: Array.isArray(userAcl.featuresJson) ? userAcl.featuresJson : [],\n }\n await this.setCache(cacheKey, result, userId, scope)\n return result\n }\n\n // Aggregate role ACLs\n const links = await em.find(CustomerUserRole, {\n user: userId as any,\n role: {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n deletedAt: null,\n },\n deletedAt: null,\n } as any, { populate: ['role'] })\n const roleIds = links.map((l) => (l.role as any)?.id).filter(Boolean)\n\n let isPortalAdmin = false\n const features: string[] = []\n if (roleIds.length) {\n const roleAcls = await em.find(CustomerRoleAcl, {\n tenantId: scope.tenantId,\n role: { $in: roleIds as any },\n } as any)\n for (const acl of roleAcls) {\n isPortalAdmin = isPortalAdmin || !!acl.isPortalAdmin\n if (Array.isArray(acl.featuresJson)) {\n for (const f of acl.featuresJson) {\n if (!features.includes(f)) features.push(f)\n }\n }\n }\n }\n\n const result: CustomerAclData = { isPortalAdmin, features }\n await this.setCache(cacheKey, result, userId, scope)\n return result\n }\n\n async userHasAllFeatures(\n userId: string,\n required: string[],\n scope: { tenantId: string; organizationId: string },\n ): Promise<boolean> {\n if (!required.length) return true\n const acl = await this.loadAcl(userId, scope)\n if (acl.isPortalAdmin) return true\n return hasAllFeatures(required, acl.features)\n }\n\n async invalidateUserCache(userId: string): Promise<void> {\n if (!this.cache) return\n await this.cache.deleteByTags([this.getUserTag(userId)])\n }\n\n async invalidateRoleCache(roleId: string): Promise<void> {\n if (!this.cache) return\n // When a role changes, invalidate all customer RBAC caches since we don't track role\u2192user mappings\n await this.cache.deleteByTags(['customer_rbac:all'])\n }\n\n async invalidateTenantCache(tenantId: string): Promise<void> {\n if (!this.cache) return\n await this.cache.deleteByTags([this.getTenantTag(tenantId)])\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["result"]
7
7
  }
@@ -98,9 +98,6 @@ const DEFAULT_ROLES = [
98
98
  }
99
99
  }
100
100
  ];
101
- const DEFAULT_CUSTOMER_ROLE_FEATURES = Object.fromEntries(
102
- DEFAULT_ROLES.map((role) => [role.slug, [...role.acl.features]])
103
- );
104
101
  async function ensureDefaultCustomerRoleAcls(em, tenantId, modules) {
105
102
  const featuresByRole = {};
106
103
  for (const mod of modules) {
@@ -165,9 +162,6 @@ const setup = {
165
162
  superadmin: ["customer_accounts.*"],
166
163
  admin: ["customer_accounts.*"]
167
164
  },
168
- // Keep the portal feature catalog declarative so the shared feature policy
169
- // can project portal.* into concrete capabilities without importing core.
170
- defaultCustomerRoleFeatures: DEFAULT_CUSTOMER_ROLE_FEATURES,
171
165
  async onTenantCreated({ em, tenantId, organizationId }) {
172
166
  await seedDefaultRoles(em, { tenantId, organizationId });
173
167
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/customer_accounts/setup.ts"],
4
- "sourcesContent": ["import type { ModuleSetupConfig, DefaultCustomerRoleFeatures } from '@open-mercato/shared/modules/setup'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { Module } from '@open-mercato/shared/modules/registry'\nimport { hash } from 'bcryptjs'\nimport { hashForLookup } from '@open-mercato/shared/lib/encryption/aes'\nimport {\n CustomerRole,\n CustomerRoleAcl,\n CustomerUser,\n CustomerUserRole,\n} from '@open-mercato/core/modules/customer_accounts/data/entities'\n\ninterface SeedScope {\n tenantId: string\n organizationId: string\n}\n\ntype SchedulerServiceLike = {\n register: (registration: {\n id: string\n name: string\n description?: string\n scopeType: 'system'\n scheduleType: 'interval'\n scheduleValue: string\n timezone?: string\n targetType: 'queue'\n targetQueue: string\n targetPayload?: Record<string, unknown>\n sourceType: 'module'\n sourceModule: string\n isEnabled?: boolean\n }) => Promise<void>\n}\n\n// Stable, deterministic UUIDs for the two domain-routing system schedules so\n// re-running setup re-upserts the same rows instead of creating duplicates.\nconst DOMAIN_VERIFICATION_SCHEDULE_ID = '5e9ef5fc-1f4d-5b3d-8b58-8e1a5a4d1001'\nconst DOMAIN_TLS_RETRY_SCHEDULE_ID = '5e9ef5fc-1f4d-5b3d-8b58-8e1a5a4d1002'\n\nfunction intervalSecondsFromEnv(envName: string, fallbackSeconds: number): string {\n const parsed = Number.parseInt(process.env[envName] ?? '', 10)\n const seconds = Number.isFinite(parsed) && parsed > 0 ? parsed : fallbackSeconds\n return `${seconds}s`\n}\n\nasync function registerDomainSchedules(\n container: { hasRegistration?: (name: string) => boolean; resolve: (name: string) => unknown },\n): Promise<void> {\n if (typeof container.hasRegistration !== 'function' || !container.hasRegistration('schedulerService')) {\n return\n }\n const schedulerService = container.resolve('schedulerService') as SchedulerServiceLike\n\n await schedulerService.register({\n id: DOMAIN_VERIFICATION_SCHEDULE_ID,\n name: 'Custom domain \u2014 DNS auto-verification',\n description:\n 'Re-runs DNS verification for custom-domain mappings stuck in pending or dns_failed, and triggers TLS health checks on success.',\n scopeType: 'system',\n scheduleType: 'interval',\n scheduleValue: intervalSecondsFromEnv('DOMAIN_AUTO_VERIFY_INTERVAL_SECONDS', 300),\n timezone: 'UTC',\n targetType: 'queue',\n targetQueue: 'domain-verification',\n sourceType: 'module',\n sourceModule: 'customer_accounts',\n isEnabled: true,\n })\n\n await schedulerService.register({\n id: DOMAIN_TLS_RETRY_SCHEDULE_ID,\n name: 'Custom domain \u2014 TLS retry',\n description:\n 'Retries TLS certificate provisioning for verified or tls_failed custom-domain mappings, with batch cap and adaptive backoff on Let\\'s Encrypt rate limits.',\n scopeType: 'system',\n scheduleType: 'interval',\n scheduleValue: intervalSecondsFromEnv('DOMAIN_TLS_RETRY_INTERVAL_SECONDS', 1800),\n timezone: 'UTC',\n targetType: 'queue',\n targetQueue: 'domain-tls-retry',\n sourceType: 'module',\n sourceModule: 'customer_accounts',\n isEnabled: true,\n })\n}\n\nconst DEFAULT_ROLES = [\n {\n name: 'Portal Admin',\n slug: 'portal_admin',\n description: 'Full portal administration access',\n isSystem: true,\n customerAssignable: false,\n isDefault: false,\n acl: {\n isPortalAdmin: true,\n features: ['portal.*'],\n },\n },\n {\n name: 'Buyer',\n slug: 'buyer',\n description: 'Standard buyer access with ordering capabilities',\n isSystem: true,\n customerAssignable: true,\n isDefault: true,\n acl: {\n isPortalAdmin: false,\n features: [\n 'portal.account.manage',\n 'portal.orders.view',\n 'portal.orders.create',\n 'portal.quotes.view',\n 'portal.quotes.request',\n 'portal.invoices.view',\n 'portal.catalog.view',\n ],\n },\n },\n {\n name: 'Viewer',\n slug: 'viewer',\n description: 'Read-only portal access',\n isSystem: true,\n customerAssignable: true,\n isDefault: false,\n acl: {\n isPortalAdmin: false,\n features: [\n 'portal.account.manage',\n 'portal.orders.view',\n 'portal.invoices.view',\n 'portal.catalog.view',\n ],\n },\n },\n]\n\nconst DEFAULT_CUSTOMER_ROLE_FEATURES = Object.fromEntries(\n DEFAULT_ROLES.map((role) => [role.slug, [...role.acl.features]]),\n)\n\n/**\n * Collect defaultCustomerRoleFeatures from all enabled modules and merge\n * them into the corresponding CustomerRoleAcl records.\n */\nasync function ensureDefaultCustomerRoleAcls(\n em: EntityManager,\n tenantId: string,\n modules: Module[],\n): Promise<void> {\n const featuresByRole: Record<string, string[]> = {}\n\n for (const mod of modules) {\n const customerRoleFeatures = mod.setup?.defaultCustomerRoleFeatures\n if (!customerRoleFeatures) continue\n for (const [roleSlug, features] of Object.entries(customerRoleFeatures)) {\n if (!features || !features.length) continue\n if (!featuresByRole[roleSlug]) featuresByRole[roleSlug] = []\n featuresByRole[roleSlug].push(...features)\n }\n }\n\n const roleSlugs = Object.keys(featuresByRole)\n if (!roleSlugs.length) return\n\n for (const roleSlug of roleSlugs) {\n const role = await em.findOne(CustomerRole, { tenantId, slug: roleSlug, deletedAt: null })\n if (!role) continue\n\n const acl = await em.findOne(CustomerRoleAcl, { role: role.id as any, tenantId })\n if (!acl) continue\n\n const currentFeatures = Array.isArray(acl.featuresJson) ? acl.featuresJson : []\n const merged = Array.from(new Set([...currentFeatures, ...featuresByRole[roleSlug]]))\n const changed =\n merged.length !== currentFeatures.length ||\n merged.some((value, index) => value !== currentFeatures[index])\n if (changed) {\n acl.featuresJson = merged\n em.persist(acl)\n }\n }\n await em.flush()\n}\n\nasync function seedDefaultRoles(em: EntityManager, scope: SeedScope): Promise<void> {\n for (const roleDef of DEFAULT_ROLES) {\n const existing = await em.findOne(CustomerRole, {\n tenantId: scope.tenantId,\n slug: roleDef.slug,\n deletedAt: null,\n })\n if (existing) continue\n\n const role = em.create(CustomerRole, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n name: roleDef.name,\n slug: roleDef.slug,\n description: roleDef.description,\n isSystem: roleDef.isSystem,\n customerAssignable: roleDef.customerAssignable,\n isDefault: roleDef.isDefault,\n createdAt: new Date(),\n } as any)\n em.persist(role)\n\n const acl = em.create(CustomerRoleAcl, {\n role,\n tenantId: scope.tenantId,\n featuresJson: roleDef.acl.features,\n isPortalAdmin: roleDef.acl.isPortalAdmin,\n createdAt: new Date(),\n } as any)\n em.persist(acl)\n }\n await em.flush()\n}\n\nexport const setup: ModuleSetupConfig = {\n defaultRoleFeatures: {\n superadmin: ['customer_accounts.*'],\n admin: ['customer_accounts.*'],\n },\n // Keep the portal feature catalog declarative so the shared feature policy\n // can project portal.* into concrete capabilities without importing core.\n defaultCustomerRoleFeatures: DEFAULT_CUSTOMER_ROLE_FEATURES,\n\n async onTenantCreated({ em, tenantId, organizationId }) {\n await seedDefaultRoles(em, { tenantId, organizationId })\n },\n\n async seedDefaults({ em, tenantId, organizationId, container }) {\n await seedDefaultRoles(em, { tenantId, organizationId })\n // Merge defaultCustomerRoleFeatures from all enabled modules\n try {\n const { getModules } = await import('@open-mercato/shared/lib/modules/registry')\n const allModules = getModules()\n await ensureDefaultCustomerRoleAcls(em, tenantId, allModules)\n } catch {\n // Modules may not be registered yet during initial setup\n }\n\n // System-scoped schedules: register is idempotent, so re-running setup\n // (or running it for additional tenants) just upserts the same two rows.\n try {\n await registerDomainSchedules(\n container as { hasRegistration?: (name: string) => boolean; resolve: (name: string) => unknown },\n )\n } catch {\n // Scheduler may not be installed in this deployment; ignore.\n }\n },\n\n async seedExamples({ em, tenantId, organizationId }) {\n const BCRYPT_COST = 10\n const exampleUsers = [\n { email: 'alice.johnson@example.com', displayName: 'Alice Johnson', password: 'Password123!', roleSlug: 'portal_admin' },\n { email: 'bob.smith@example.com', displayName: 'Bob Smith', password: 'Password123!', roleSlug: 'buyer' },\n { email: 'carol.white@example.com', displayName: 'Carol White', password: 'Password123!', roleSlug: 'viewer' },\n ]\n\n for (const entry of exampleUsers) {\n const emailHash = hashForLookup(entry.email)\n const existing = await em.findOne(CustomerUser, { emailHash, tenantId, deletedAt: null })\n if (existing) continue\n\n const passwordHash = await hash(entry.password, BCRYPT_COST)\n const user = em.create(CustomerUser, {\n email: entry.email,\n emailHash,\n passwordHash,\n displayName: entry.displayName,\n tenantId,\n organizationId,\n isActive: true,\n failedLoginAttempts: 0,\n emailVerifiedAt: new Date(),\n createdAt: new Date(),\n } as any)\n em.persist(user)\n\n const role = await em.findOne(CustomerRole, { tenantId, slug: entry.roleSlug, deletedAt: null })\n if (role) {\n const userRole = em.create(CustomerUserRole, {\n user,\n role,\n createdAt: new Date(),\n } as any)\n em.persist(userRole)\n }\n }\n await em.flush()\n },\n}\n\nexport default setup\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { ModuleSetupConfig, DefaultCustomerRoleFeatures } from '@open-mercato/shared/modules/setup'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { Module } from '@open-mercato/shared/modules/registry'\nimport { hash } from 'bcryptjs'\nimport { hashForLookup } from '@open-mercato/shared/lib/encryption/aes'\nimport {\n CustomerRole,\n CustomerRoleAcl,\n CustomerUser,\n CustomerUserRole,\n} from '@open-mercato/core/modules/customer_accounts/data/entities'\n\ninterface SeedScope {\n tenantId: string\n organizationId: string\n}\n\ntype SchedulerServiceLike = {\n register: (registration: {\n id: string\n name: string\n description?: string\n scopeType: 'system'\n scheduleType: 'interval'\n scheduleValue: string\n timezone?: string\n targetType: 'queue'\n targetQueue: string\n targetPayload?: Record<string, unknown>\n sourceType: 'module'\n sourceModule: string\n isEnabled?: boolean\n }) => Promise<void>\n}\n\n// Stable, deterministic UUIDs for the two domain-routing system schedules so\n// re-running setup re-upserts the same rows instead of creating duplicates.\nconst DOMAIN_VERIFICATION_SCHEDULE_ID = '5e9ef5fc-1f4d-5b3d-8b58-8e1a5a4d1001'\nconst DOMAIN_TLS_RETRY_SCHEDULE_ID = '5e9ef5fc-1f4d-5b3d-8b58-8e1a5a4d1002'\n\nfunction intervalSecondsFromEnv(envName: string, fallbackSeconds: number): string {\n const parsed = Number.parseInt(process.env[envName] ?? '', 10)\n const seconds = Number.isFinite(parsed) && parsed > 0 ? parsed : fallbackSeconds\n return `${seconds}s`\n}\n\nasync function registerDomainSchedules(\n container: { hasRegistration?: (name: string) => boolean; resolve: (name: string) => unknown },\n): Promise<void> {\n if (typeof container.hasRegistration !== 'function' || !container.hasRegistration('schedulerService')) {\n return\n }\n const schedulerService = container.resolve('schedulerService') as SchedulerServiceLike\n\n await schedulerService.register({\n id: DOMAIN_VERIFICATION_SCHEDULE_ID,\n name: 'Custom domain \u2014 DNS auto-verification',\n description:\n 'Re-runs DNS verification for custom-domain mappings stuck in pending or dns_failed, and triggers TLS health checks on success.',\n scopeType: 'system',\n scheduleType: 'interval',\n scheduleValue: intervalSecondsFromEnv('DOMAIN_AUTO_VERIFY_INTERVAL_SECONDS', 300),\n timezone: 'UTC',\n targetType: 'queue',\n targetQueue: 'domain-verification',\n sourceType: 'module',\n sourceModule: 'customer_accounts',\n isEnabled: true,\n })\n\n await schedulerService.register({\n id: DOMAIN_TLS_RETRY_SCHEDULE_ID,\n name: 'Custom domain \u2014 TLS retry',\n description:\n 'Retries TLS certificate provisioning for verified or tls_failed custom-domain mappings, with batch cap and adaptive backoff on Let\\'s Encrypt rate limits.',\n scopeType: 'system',\n scheduleType: 'interval',\n scheduleValue: intervalSecondsFromEnv('DOMAIN_TLS_RETRY_INTERVAL_SECONDS', 1800),\n timezone: 'UTC',\n targetType: 'queue',\n targetQueue: 'domain-tls-retry',\n sourceType: 'module',\n sourceModule: 'customer_accounts',\n isEnabled: true,\n })\n}\n\nconst DEFAULT_ROLES = [\n {\n name: 'Portal Admin',\n slug: 'portal_admin',\n description: 'Full portal administration access',\n isSystem: true,\n customerAssignable: false,\n isDefault: false,\n acl: {\n isPortalAdmin: true,\n features: ['portal.*'],\n },\n },\n {\n name: 'Buyer',\n slug: 'buyer',\n description: 'Standard buyer access with ordering capabilities',\n isSystem: true,\n customerAssignable: true,\n isDefault: true,\n acl: {\n isPortalAdmin: false,\n features: [\n 'portal.account.manage',\n 'portal.orders.view',\n 'portal.orders.create',\n 'portal.quotes.view',\n 'portal.quotes.request',\n 'portal.invoices.view',\n 'portal.catalog.view',\n ],\n },\n },\n {\n name: 'Viewer',\n slug: 'viewer',\n description: 'Read-only portal access',\n isSystem: true,\n customerAssignable: true,\n isDefault: false,\n acl: {\n isPortalAdmin: false,\n features: [\n 'portal.account.manage',\n 'portal.orders.view',\n 'portal.invoices.view',\n 'portal.catalog.view',\n ],\n },\n },\n]\n\n/**\n * Collect defaultCustomerRoleFeatures from all enabled modules and merge\n * them into the corresponding CustomerRoleAcl records.\n */\nasync function ensureDefaultCustomerRoleAcls(\n em: EntityManager,\n tenantId: string,\n modules: Module[],\n): Promise<void> {\n const featuresByRole: Record<string, string[]> = {}\n\n for (const mod of modules) {\n const customerRoleFeatures = mod.setup?.defaultCustomerRoleFeatures\n if (!customerRoleFeatures) continue\n for (const [roleSlug, features] of Object.entries(customerRoleFeatures)) {\n if (!features || !features.length) continue\n if (!featuresByRole[roleSlug]) featuresByRole[roleSlug] = []\n featuresByRole[roleSlug].push(...features)\n }\n }\n\n const roleSlugs = Object.keys(featuresByRole)\n if (!roleSlugs.length) return\n\n for (const roleSlug of roleSlugs) {\n const role = await em.findOne(CustomerRole, { tenantId, slug: roleSlug, deletedAt: null })\n if (!role) continue\n\n const acl = await em.findOne(CustomerRoleAcl, { role: role.id as any, tenantId })\n if (!acl) continue\n\n const currentFeatures = Array.isArray(acl.featuresJson) ? acl.featuresJson : []\n const merged = Array.from(new Set([...currentFeatures, ...featuresByRole[roleSlug]]))\n const changed =\n merged.length !== currentFeatures.length ||\n merged.some((value, index) => value !== currentFeatures[index])\n if (changed) {\n acl.featuresJson = merged\n em.persist(acl)\n }\n }\n await em.flush()\n}\n\nasync function seedDefaultRoles(em: EntityManager, scope: SeedScope): Promise<void> {\n for (const roleDef of DEFAULT_ROLES) {\n const existing = await em.findOne(CustomerRole, {\n tenantId: scope.tenantId,\n slug: roleDef.slug,\n deletedAt: null,\n })\n if (existing) continue\n\n const role = em.create(CustomerRole, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n name: roleDef.name,\n slug: roleDef.slug,\n description: roleDef.description,\n isSystem: roleDef.isSystem,\n customerAssignable: roleDef.customerAssignable,\n isDefault: roleDef.isDefault,\n createdAt: new Date(),\n } as any)\n em.persist(role)\n\n const acl = em.create(CustomerRoleAcl, {\n role,\n tenantId: scope.tenantId,\n featuresJson: roleDef.acl.features,\n isPortalAdmin: roleDef.acl.isPortalAdmin,\n createdAt: new Date(),\n } as any)\n em.persist(acl)\n }\n await em.flush()\n}\n\nexport const setup: ModuleSetupConfig = {\n defaultRoleFeatures: {\n superadmin: ['customer_accounts.*'],\n admin: ['customer_accounts.*'],\n },\n\n async onTenantCreated({ em, tenantId, organizationId }) {\n await seedDefaultRoles(em, { tenantId, organizationId })\n },\n\n async seedDefaults({ em, tenantId, organizationId, container }) {\n await seedDefaultRoles(em, { tenantId, organizationId })\n // Merge defaultCustomerRoleFeatures from all enabled modules\n try {\n const { getModules } = await import('@open-mercato/shared/lib/modules/registry')\n const allModules = getModules()\n await ensureDefaultCustomerRoleAcls(em, tenantId, allModules)\n } catch {\n // Modules may not be registered yet during initial setup\n }\n\n // System-scoped schedules: register is idempotent, so re-running setup\n // (or running it for additional tenants) just upserts the same two rows.\n try {\n await registerDomainSchedules(\n container as { hasRegistration?: (name: string) => boolean; resolve: (name: string) => unknown },\n )\n } catch {\n // Scheduler may not be installed in this deployment; ignore.\n }\n },\n\n async seedExamples({ em, tenantId, organizationId }) {\n const BCRYPT_COST = 10\n const exampleUsers = [\n { email: 'alice.johnson@example.com', displayName: 'Alice Johnson', password: 'Password123!', roleSlug: 'portal_admin' },\n { email: 'bob.smith@example.com', displayName: 'Bob Smith', password: 'Password123!', roleSlug: 'buyer' },\n { email: 'carol.white@example.com', displayName: 'Carol White', password: 'Password123!', roleSlug: 'viewer' },\n ]\n\n for (const entry of exampleUsers) {\n const emailHash = hashForLookup(entry.email)\n const existing = await em.findOne(CustomerUser, { emailHash, tenantId, deletedAt: null })\n if (existing) continue\n\n const passwordHash = await hash(entry.password, BCRYPT_COST)\n const user = em.create(CustomerUser, {\n email: entry.email,\n emailHash,\n passwordHash,\n displayName: entry.displayName,\n tenantId,\n organizationId,\n isActive: true,\n failedLoginAttempts: 0,\n emailVerifiedAt: new Date(),\n createdAt: new Date(),\n } as any)\n em.persist(user)\n\n const role = await em.findOne(CustomerRole, { tenantId, slug: entry.roleSlug, deletedAt: null })\n if (role) {\n const userRole = em.create(CustomerUserRole, {\n user,\n role,\n createdAt: new Date(),\n } as any)\n em.persist(userRole)\n }\n }\n await em.flush()\n },\n}\n\nexport default setup\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,5 @@
1
1
  import { CustomerUser } from "@open-mercato/core/modules/customer_accounts/data/entities";
2
2
  import { findWithDecryption, findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
3
- import { resolveOwnedCompanyForPerson } from "@open-mercato/core/modules/customer_accounts/lib/customerEntityOwnership";
4
3
  import { createLogger } from "@open-mercato/shared/lib/logger";
5
4
  const logger = createLogger("customer_accounts").child({ component: "auto-link-crm" });
6
5
  const metadata = {
@@ -18,51 +17,14 @@ async function handle(payload, ctx) {
18
17
  try {
19
18
  const user = await findOneWithDecryption(em, CustomerUser, { id: userId, tenantId, deletedAt: null }, void 0, { tenantId, organizationId });
20
19
  if (!user) return;
21
- const { CustomerEntity } = await import("@open-mercato/core/modules/customers/data/entities");
22
- const ownScope = { tenantId, organizationId: user.organizationId };
23
- if (user.customerEntityId) {
24
- const linked = await findOneWithDecryption(
25
- em,
26
- CustomerEntity,
27
- { id: user.customerEntityId, tenantId, organizationId: user.organizationId, deletedAt: null },
28
- void 0,
29
- { tenantId, organizationId }
30
- );
31
- if (!linked) {
32
- await em.nativeUpdate(
33
- CustomerUser,
34
- { id: userId, tenantId, organizationId: user.organizationId },
35
- { customerEntityId: null }
36
- );
37
- user.customerEntityId = null;
38
- } else if (linked.kind === "person") {
39
- const replacement = await resolveOwnedCompanyForPerson(em, user.customerEntityId, ownScope);
40
- await em.nativeUpdate(
41
- CustomerUser,
42
- { id: userId, tenantId, organizationId: user.organizationId },
43
- { customerEntityId: replacement }
44
- );
45
- user.customerEntityId = replacement;
46
- }
47
- }
48
- if (user.personEntityId) {
49
- if (user.customerEntityId) return;
50
- const recovered = await resolveOwnedCompanyForPerson(em, user.personEntityId, ownScope);
51
- if (recovered) {
52
- await em.nativeUpdate(
53
- CustomerUser,
54
- { id: userId, tenantId, organizationId: user.organizationId },
55
- { customerEntityId: recovered }
56
- );
57
- }
58
- return;
59
- }
20
+ if (user.personEntityId) return;
60
21
  const email = (data?.email ? data.email : user.email)?.toLowerCase().trim();
61
22
  if (!email) return;
23
+ const { CustomerEntity } = await import("@open-mercato/core/modules/customers/data/entities");
62
24
  const personEntities = await findWithDecryption(
63
25
  em,
64
26
  CustomerEntity,
65
- { tenantId, organizationId: user.organizationId, kind: "person", deletedAt: null },
27
+ { tenantId, kind: "person", deletedAt: null },
66
28
  { limit: 500 },
67
29
  { tenantId, organizationId }
68
30
  );
@@ -70,16 +32,14 @@ async function handle(payload, ctx) {
70
32
  (e) => e.primaryEmail && e.primaryEmail.toLowerCase().trim() === email
71
33
  );
72
34
  if (!matchingEntity) return;
73
- const companyEntityId = await resolveOwnedCompanyForPerson(em, matchingEntity.id, ownScope);
35
+ const { CustomerPersonProfile } = await import("@open-mercato/core/modules/customers/data/entities");
36
+ const profile = await em.findOne(CustomerPersonProfile, { entity: matchingEntity.id });
37
+ const companyEntityId = profile?.companyEntityId;
74
38
  const updates = { personEntityId: matchingEntity.id };
75
39
  if (companyEntityId) {
76
40
  updates.customerEntityId = companyEntityId;
77
41
  }
78
- await em.nativeUpdate(
79
- CustomerUser,
80
- { id: userId, tenantId, organizationId: user.organizationId },
81
- updates
82
- );
42
+ await em.nativeUpdate(CustomerUser, { id: userId }, updates);
83
43
  } catch (err) {
84
44
  logger.error("Failed to link customer user to CRM person", { err });
85
45
  }