@open-mercato/core 0.4.2-canary-f075c3eb92 → 0.4.2-canary-8a04af8836

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 (507) hide show
  1. package/dist/generated/entities/notification/index.js +57 -0
  2. package/dist/generated/entities/notification/index.js.map +7 -0
  3. package/dist/generated/entities.ids.generated.js +5 -1
  4. package/dist/generated/entities.ids.generated.js.map +2 -2
  5. package/dist/generated/entity-fields-registry.js +2 -0
  6. package/dist/generated/entity-fields-registry.js.map +2 -2
  7. package/dist/modules/api_docs/frontend/docs/api/page.js +3 -2
  8. package/dist/modules/api_docs/frontend/docs/api/page.js.map +2 -2
  9. package/dist/modules/api_keys/backend/api-keys/page.js +1 -1
  10. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  11. package/dist/modules/attachments/components/AttachmentLibrary.js +4 -0
  12. package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
  13. package/dist/modules/attachments/components/AttachmentPartitionSettings.js +2 -0
  14. package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
  15. package/dist/modules/auth/api/admin/nav.js +4 -3
  16. package/dist/modules/auth/api/admin/nav.js.map +2 -2
  17. package/dist/modules/auth/api/login.js +25 -6
  18. package/dist/modules/auth/api/login.js.map +2 -2
  19. package/dist/modules/auth/api/profile/route.js +157 -0
  20. package/dist/modules/auth/api/profile/route.js.map +7 -0
  21. package/dist/modules/auth/api/reset/confirm.js +25 -2
  22. package/dist/modules/auth/api/reset/confirm.js.map +2 -2
  23. package/dist/modules/auth/api/reset.js +23 -0
  24. package/dist/modules/auth/api/reset.js.map +2 -2
  25. package/dist/modules/auth/api/sidebar/preferences/route.js +14 -9
  26. package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
  27. package/dist/modules/auth/api/users/route.js +4 -2
  28. package/dist/modules/auth/api/users/route.js.map +2 -2
  29. package/dist/modules/auth/backend/auth/profile/page.js +141 -0
  30. package/dist/modules/auth/backend/auth/profile/page.js.map +7 -0
  31. package/dist/modules/auth/backend/auth/profile/page.meta.js +13 -0
  32. package/dist/modules/auth/backend/auth/profile/page.meta.js.map +7 -0
  33. package/dist/modules/auth/backend/roles/[id]/edit/page.js +4 -1
  34. package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
  35. package/dist/modules/auth/backend/roles/page.js +3 -3
  36. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  37. package/dist/modules/auth/backend/users/[id]/edit/page.js +18 -3
  38. package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
  39. package/dist/modules/auth/backend/users/create/page.js +15 -2
  40. package/dist/modules/auth/backend/users/create/page.js.map +2 -2
  41. package/dist/modules/auth/backend/users/page.js +3 -3
  42. package/dist/modules/auth/backend/users/page.js.map +2 -2
  43. package/dist/modules/auth/cli.js +25 -11
  44. package/dist/modules/auth/cli.js.map +2 -2
  45. package/dist/modules/auth/commands/users.js +59 -2
  46. package/dist/modules/auth/commands/users.js.map +2 -2
  47. package/dist/modules/auth/data/validators.js +6 -3
  48. package/dist/modules/auth/data/validators.js.map +2 -2
  49. package/dist/modules/auth/frontend/login.js +112 -3
  50. package/dist/modules/auth/frontend/login.js.map +2 -2
  51. package/dist/modules/auth/frontend/reset/[token]/page.js +20 -10
  52. package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
  53. package/dist/modules/auth/lib/setup-app.js +46 -8
  54. package/dist/modules/auth/lib/setup-app.js.map +2 -2
  55. package/dist/modules/auth/notifications.js +112 -0
  56. package/dist/modules/auth/notifications.js.map +7 -0
  57. package/dist/modules/auth/services/authService.js +24 -3
  58. package/dist/modules/auth/services/authService.js.map +2 -2
  59. package/dist/modules/business_rules/api/execute/route.js +7 -1
  60. package/dist/modules/business_rules/api/execute/route.js.map +2 -2
  61. package/dist/modules/business_rules/backend/rules/page.js +4 -0
  62. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  63. package/dist/modules/business_rules/backend/sets/page.js +3 -0
  64. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  65. package/dist/modules/business_rules/cli.js +2 -1
  66. package/dist/modules/business_rules/cli.js.map +2 -2
  67. package/dist/modules/business_rules/lib/rule-engine.js +33 -3
  68. package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
  69. package/dist/modules/business_rules/notifications.js +28 -0
  70. package/dist/modules/business_rules/notifications.js.map +7 -0
  71. package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js +37 -0
  72. package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js.map +7 -0
  73. package/dist/modules/catalog/components/PriceKindSettings.js +2 -0
  74. package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
  75. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -2
  76. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  77. package/dist/modules/catalog/components/products/ProductsDataTable.js +2 -0
  78. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  79. package/dist/modules/catalog/notifications.js +28 -0
  80. package/dist/modules/catalog/notifications.js.map +7 -0
  81. package/dist/modules/catalog/subscribers/low-stock-notification.js +38 -0
  82. package/dist/modules/catalog/subscribers/low-stock-notification.js.map +7 -0
  83. package/dist/modules/configs/cli.js +6 -0
  84. package/dist/modules/configs/cli.js.map +2 -2
  85. package/dist/modules/configs/components/CachePanel.js +4 -4
  86. package/dist/modules/configs/components/CachePanel.js.map +2 -2
  87. package/dist/modules/configs/lib/system-status.js +48 -1
  88. package/dist/modules/configs/lib/system-status.js.map +2 -2
  89. package/dist/modules/configs/lib/upgrade-actions.js +138 -306
  90. package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
  91. package/dist/modules/currencies/backend/currencies/page.js +3 -0
  92. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  93. package/dist/modules/currencies/backend/exchange-rates/page.js +2 -0
  94. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  95. package/dist/modules/customers/backend/customers/companies/page.js +3 -0
  96. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  97. package/dist/modules/customers/backend/customers/deals/page.js +3 -0
  98. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  99. package/dist/modules/customers/backend/customers/people/page.js +3 -0
  100. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  101. package/dist/modules/customers/commands/deals.js +31 -0
  102. package/dist/modules/customers/commands/deals.js.map +2 -2
  103. package/dist/modules/customers/components/CustomerTodosTable.js +1 -0
  104. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  105. package/dist/modules/customers/notifications.js +48 -0
  106. package/dist/modules/customers/notifications.js.map +7 -0
  107. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.js +2 -1
  108. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.js.map +2 -2
  109. package/dist/modules/customers/widgets/dashboard/new-customers/widget.js +2 -1
  110. package/dist/modules/customers/widgets/dashboard/new-customers/widget.js.map +2 -2
  111. package/dist/modules/customers/widgets/dashboard/new-deals/widget.js +2 -1
  112. package/dist/modules/customers/widgets/dashboard/new-deals/widget.js.map +2 -2
  113. package/dist/modules/customers/widgets/dashboard/next-interactions/widget.js +2 -1
  114. package/dist/modules/customers/widgets/dashboard/next-interactions/widget.js.map +2 -2
  115. package/dist/modules/dashboards/cli.js +44 -5
  116. package/dist/modules/dashboards/cli.js.map +2 -2
  117. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +16 -11
  118. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +3 -3
  119. package/dist/modules/dashboards/lib/role-widgets.js +58 -0
  120. package/dist/modules/dashboards/lib/role-widgets.js.map +7 -0
  121. package/dist/modules/dashboards/services/widgetDataService.js +139 -3
  122. package/dist/modules/dashboards/services/widgetDataService.js.map +2 -2
  123. package/dist/modules/dashboards/setup.js +15 -0
  124. package/dist/modules/dashboards/setup.js.map +2 -2
  125. package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.js +2 -1
  126. package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.js.map +2 -2
  127. package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.js +2 -1
  128. package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.js.map +2 -2
  129. package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.js +2 -1
  130. package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.js.map +2 -2
  131. package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.js +2 -1
  132. package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.js.map +2 -2
  133. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js +2 -1
  134. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js.map +2 -2
  135. package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.js +2 -1
  136. package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.js.map +2 -2
  137. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.js +2 -1
  138. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.js.map +2 -2
  139. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.js +2 -1
  140. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.js.map +2 -2
  141. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.js +2 -1
  142. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.js.map +2 -2
  143. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.js +2 -1
  144. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.js.map +2 -2
  145. package/dist/modules/dictionaries/components/DictionaryTable.js +2 -0
  146. package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
  147. package/dist/modules/directory/api/get/tenants/lookup.js +70 -0
  148. package/dist/modules/directory/api/get/tenants/lookup.js.map +7 -0
  149. package/dist/modules/directory/backend/directory/organizations/page.js +2 -2
  150. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  151. package/dist/modules/directory/backend/directory/tenants/page.js +2 -2
  152. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  153. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +2 -2
  154. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  155. package/dist/modules/entities/components/SystemEntitiesTable.js +1 -1
  156. package/dist/modules/entities/components/SystemEntitiesTable.js.map +2 -2
  157. package/dist/modules/entities/components/UserEntitiesTable.js +2 -2
  158. package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
  159. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +3 -3
  160. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  161. package/dist/modules/feature_toggles/components/OverridesTable.js +1 -1
  162. package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
  163. package/dist/modules/notifications/acl.js +11 -0
  164. package/dist/modules/notifications/acl.js.map +7 -0
  165. package/dist/modules/notifications/api/[id]/action/route.js +74 -0
  166. package/dist/modules/notifications/api/[id]/action/route.js.map +7 -0
  167. package/dist/modules/notifications/api/[id]/dismiss/route.js +15 -0
  168. package/dist/modules/notifications/api/[id]/dismiss/route.js.map +7 -0
  169. package/dist/modules/notifications/api/[id]/read/route.js +15 -0
  170. package/dist/modules/notifications/api/[id]/read/route.js.map +7 -0
  171. package/dist/modules/notifications/api/[id]/restore/route.js +53 -0
  172. package/dist/modules/notifications/api/[id]/restore/route.js.map +7 -0
  173. package/dist/modules/notifications/api/batch/route.js +17 -0
  174. package/dist/modules/notifications/api/batch/route.js.map +7 -0
  175. package/dist/modules/notifications/api/feature/route.js +17 -0
  176. package/dist/modules/notifications/api/feature/route.js.map +7 -0
  177. package/dist/modules/notifications/api/mark-all-read/route.js +35 -0
  178. package/dist/modules/notifications/api/mark-all-read/route.js.map +7 -0
  179. package/dist/modules/notifications/api/openapi.js +76 -0
  180. package/dist/modules/notifications/api/openapi.js.map +7 -0
  181. package/dist/modules/notifications/api/role/route.js +17 -0
  182. package/dist/modules/notifications/api/role/route.js.map +7 -0
  183. package/dist/modules/notifications/api/route.js +85 -0
  184. package/dist/modules/notifications/api/route.js.map +7 -0
  185. package/dist/modules/notifications/api/settings/route.js +155 -0
  186. package/dist/modules/notifications/api/settings/route.js.map +7 -0
  187. package/dist/modules/notifications/api/unread-count/route.js +38 -0
  188. package/dist/modules/notifications/api/unread-count/route.js.map +7 -0
  189. package/dist/modules/notifications/backend/config/notifications/page.js +10 -0
  190. package/dist/modules/notifications/backend/config/notifications/page.js.map +7 -0
  191. package/dist/modules/notifications/backend/config/notifications/page.meta.js +24 -0
  192. package/dist/modules/notifications/backend/config/notifications/page.meta.js.map +7 -0
  193. package/dist/modules/notifications/cli.js +16 -0
  194. package/dist/modules/notifications/cli.js.map +7 -0
  195. package/dist/modules/notifications/data/entities.js +112 -0
  196. package/dist/modules/notifications/data/entities.js.map +7 -0
  197. package/dist/modules/notifications/data/validators.js +98 -0
  198. package/dist/modules/notifications/data/validators.js.map +7 -0
  199. package/dist/modules/notifications/di.js +13 -0
  200. package/dist/modules/notifications/di.js.map +7 -0
  201. package/dist/modules/notifications/emails/NotificationEmail.js +58 -0
  202. package/dist/modules/notifications/emails/NotificationEmail.js.map +7 -0
  203. package/dist/modules/notifications/frontend/NotificationInboxPageClient.js +44 -0
  204. package/dist/modules/notifications/frontend/NotificationInboxPageClient.js.map +7 -0
  205. package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js +220 -0
  206. package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js.map +7 -0
  207. package/dist/modules/notifications/index.js +14 -0
  208. package/dist/modules/notifications/index.js.map +7 -0
  209. package/dist/modules/notifications/lib/deliveryConfig.js +107 -0
  210. package/dist/modules/notifications/lib/deliveryConfig.js.map +7 -0
  211. package/dist/modules/notifications/lib/deliveryStrategies.js +14 -0
  212. package/dist/modules/notifications/lib/deliveryStrategies.js.map +7 -0
  213. package/dist/modules/notifications/lib/events.js +12 -0
  214. package/dist/modules/notifications/lib/events.js.map +7 -0
  215. package/dist/modules/notifications/lib/notificationBuilder.js +66 -0
  216. package/dist/modules/notifications/lib/notificationBuilder.js.map +7 -0
  217. package/dist/modules/notifications/lib/notificationFactory.js +54 -0
  218. package/dist/modules/notifications/lib/notificationFactory.js.map +7 -0
  219. package/dist/modules/notifications/lib/notificationMapper.js +34 -0
  220. package/dist/modules/notifications/lib/notificationMapper.js.map +7 -0
  221. package/dist/modules/notifications/lib/notificationRecipients.js +35 -0
  222. package/dist/modules/notifications/lib/notificationRecipients.js.map +7 -0
  223. package/dist/modules/notifications/lib/notificationService.js +279 -0
  224. package/dist/modules/notifications/lib/notificationService.js.map +7 -0
  225. package/dist/modules/notifications/lib/routeHelpers.js +101 -0
  226. package/dist/modules/notifications/lib/routeHelpers.js.map +7 -0
  227. package/dist/modules/notifications/lib/safeHref.js +24 -0
  228. package/dist/modules/notifications/lib/safeHref.js.map +7 -0
  229. package/dist/modules/notifications/migrations/Migration20260123000001.js +70 -0
  230. package/dist/modules/notifications/migrations/Migration20260123000001.js.map +7 -0
  231. package/dist/modules/notifications/migrations/Migration20260126150000.js +37 -0
  232. package/dist/modules/notifications/migrations/Migration20260126150000.js.map +7 -0
  233. package/dist/modules/notifications/migrations/Migration20260129082610.js +13 -0
  234. package/dist/modules/notifications/migrations/Migration20260129082610.js.map +7 -0
  235. package/dist/modules/notifications/subscribers/deliver-notification.js +165 -0
  236. package/dist/modules/notifications/subscribers/deliver-notification.js.map +7 -0
  237. package/dist/modules/notifications/workers/create-notification.worker.js +70 -0
  238. package/dist/modules/notifications/workers/create-notification.worker.js.map +7 -0
  239. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +2 -2
  240. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  241. package/dist/modules/query_index/cli.js +63 -7
  242. package/dist/modules/query_index/cli.js.map +2 -2
  243. package/dist/modules/query_index/components/QueryIndexesTable.js +7 -1
  244. package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
  245. package/dist/modules/resources/backend/resources/resource-types/page.js +2 -2
  246. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  247. package/dist/modules/resources/backend/resources/resources/page.js +2 -2
  248. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  249. package/dist/modules/sales/backend/sales/channels/offers/page.js +2 -0
  250. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  251. package/dist/modules/sales/backend/sales/channels/page.js +2 -0
  252. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  253. package/dist/modules/sales/cli.js +2 -42
  254. package/dist/modules/sales/cli.js.map +2 -2
  255. package/dist/modules/sales/commands/documents.js +53 -0
  256. package/dist/modules/sales/commands/documents.js.map +2 -2
  257. package/dist/modules/sales/commands/payments.js +26 -0
  258. package/dist/modules/sales/commands/payments.js.map +2 -2
  259. package/dist/modules/sales/components/AdjustmentKindSettings.js +2 -2
  260. package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
  261. package/dist/modules/sales/components/PaymentMethodsSettings.js +2 -2
  262. package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
  263. package/dist/modules/sales/components/ShippingMethodsSettings.js +2 -2
  264. package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
  265. package/dist/modules/sales/components/TaxRatesSettings.js +2 -2
  266. package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
  267. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +2 -0
  268. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  269. package/dist/modules/sales/components/documents/AdjustmentsSection.js +2 -0
  270. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  271. package/dist/modules/sales/components/documents/PaymentsSection.js +2 -1
  272. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  273. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +2 -0
  274. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  275. package/dist/modules/sales/lib/seeds.js +48 -0
  276. package/dist/modules/sales/lib/seeds.js.map +7 -0
  277. package/dist/modules/sales/notifications.client.js +51 -0
  278. package/dist/modules/sales/notifications.client.js.map +7 -0
  279. package/dist/modules/sales/notifications.js +88 -0
  280. package/dist/modules/sales/notifications.js.map +7 -0
  281. package/dist/modules/sales/subscribers/quote-expiring-notification.js +38 -0
  282. package/dist/modules/sales/subscribers/quote-expiring-notification.js.map +7 -0
  283. package/dist/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.js +137 -0
  284. package/dist/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.js.map +7 -0
  285. package/dist/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.js +137 -0
  286. package/dist/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.js.map +7 -0
  287. package/dist/modules/sales/widgets/notifications/index.js +7 -0
  288. package/dist/modules/sales/widgets/notifications/index.js.map +7 -0
  289. package/dist/modules/sales/widgets/notifications/useSalesDocumentTotals.js +60 -0
  290. package/dist/modules/sales/widgets/notifications/useSalesDocumentTotals.js.map +7 -0
  291. package/dist/modules/staff/backend/staff/team-members/page.js +1 -1
  292. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  293. package/dist/modules/staff/backend/staff/team-roles/page.js +2 -2
  294. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  295. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +2 -2
  296. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  297. package/dist/modules/staff/backend/staff/teams/page.js +2 -2
  298. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  299. package/dist/modules/staff/commands/leave-requests.js +79 -0
  300. package/dist/modules/staff/commands/leave-requests.js.map +2 -2
  301. package/dist/modules/staff/notifications.js +75 -0
  302. package/dist/modules/staff/notifications.js.map +7 -0
  303. package/dist/modules/workflows/backend/definitions/page.js +5 -0
  304. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  305. package/dist/modules/workflows/backend/instances/page.js +3 -0
  306. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  307. package/dist/modules/workflows/backend/tasks/page.js +3 -0
  308. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  309. package/dist/modules/workflows/cli.js +12 -12
  310. package/dist/modules/workflows/cli.js.map +2 -2
  311. package/dist/modules/workflows/lib/transition-handler.js +14 -6
  312. package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
  313. package/dist/modules/workflows/notifications.js +28 -0
  314. package/dist/modules/workflows/notifications.js.map +7 -0
  315. package/dist/modules/workflows/subscribers/task-assigned-notification.js +38 -0
  316. package/dist/modules/workflows/subscribers/task-assigned-notification.js.map +7 -0
  317. package/generated/entities/notification/index.ts +27 -0
  318. package/generated/entities.ids.generated.ts +5 -1
  319. package/generated/entity-fields-registry.ts +2 -0
  320. package/package.json +2 -2
  321. package/src/modules/api_docs/frontend/docs/api/page.tsx +3 -2
  322. package/src/modules/api_keys/backend/api-keys/page.tsx +1 -1
  323. package/src/modules/attachments/components/AttachmentLibrary.tsx +4 -0
  324. package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +2 -0
  325. package/src/modules/auth/README.md +1 -1
  326. package/src/modules/auth/__tests__/cli-setup-acl.test.ts +1 -1
  327. package/src/modules/auth/api/__tests__/login.test.ts +2 -0
  328. package/src/modules/auth/api/admin/nav.ts +10 -6
  329. package/src/modules/auth/api/login.ts +26 -7
  330. package/src/modules/auth/api/profile/route.ts +163 -0
  331. package/src/modules/auth/api/reset/confirm.ts +25 -2
  332. package/src/modules/auth/api/reset.ts +23 -0
  333. package/src/modules/auth/api/sidebar/preferences/route.ts +21 -12
  334. package/src/modules/auth/api/users/route.ts +5 -2
  335. package/src/modules/auth/backend/auth/profile/page.meta.ts +9 -0
  336. package/src/modules/auth/backend/auth/profile/page.tsx +174 -0
  337. package/src/modules/auth/backend/roles/[id]/edit/page.tsx +4 -1
  338. package/src/modules/auth/backend/roles/page.tsx +3 -3
  339. package/src/modules/auth/backend/users/[id]/edit/page.tsx +22 -3
  340. package/src/modules/auth/backend/users/create/page.tsx +19 -2
  341. package/src/modules/auth/backend/users/page.tsx +3 -3
  342. package/src/modules/auth/cli.ts +38 -11
  343. package/src/modules/auth/commands/users.ts +73 -2
  344. package/src/modules/auth/data/validators.ts +6 -2
  345. package/src/modules/auth/frontend/login.tsx +134 -5
  346. package/src/modules/auth/frontend/reset/[token]/page.tsx +24 -11
  347. package/src/modules/auth/i18n/de.json +48 -1
  348. package/src/modules/auth/i18n/en.json +48 -1
  349. package/src/modules/auth/i18n/es.json +48 -1
  350. package/src/modules/auth/i18n/pl.json +48 -1
  351. package/src/modules/auth/lib/setup-app.ts +63 -9
  352. package/src/modules/auth/notifications.ts +109 -0
  353. package/src/modules/auth/services/authService.ts +27 -4
  354. package/src/modules/business_rules/api/execute/route.ts +8 -1
  355. package/src/modules/business_rules/backend/rules/page.tsx +4 -0
  356. package/src/modules/business_rules/backend/sets/page.tsx +3 -0
  357. package/src/modules/business_rules/cli.ts +2 -1
  358. package/src/modules/business_rules/i18n/en.json +3 -1
  359. package/src/modules/business_rules/lib/__tests__/rule-engine.test.ts +51 -0
  360. package/src/modules/business_rules/lib/rule-engine.ts +57 -3
  361. package/src/modules/business_rules/notifications.ts +25 -0
  362. package/src/modules/business_rules/subscribers/rule-execution-failed-notification.ts +50 -0
  363. package/src/modules/catalog/components/PriceKindSettings.tsx +2 -0
  364. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +2 -2
  365. package/src/modules/catalog/components/products/ProductsDataTable.tsx +2 -0
  366. package/src/modules/catalog/i18n/en.json +3 -1
  367. package/src/modules/catalog/notifications.ts +25 -0
  368. package/src/modules/catalog/subscribers/low-stock-notification.ts +52 -0
  369. package/src/modules/configs/cli.ts +6 -0
  370. package/src/modules/configs/components/CachePanel.tsx +4 -4
  371. package/src/modules/configs/i18n/en.json +12 -2
  372. package/src/modules/configs/i18n/pl.json +12 -2
  373. package/src/modules/configs/lib/system-status.ts +48 -1
  374. package/src/modules/configs/lib/system-status.types.ts +1 -0
  375. package/src/modules/configs/lib/upgrade-actions.ts +157 -351
  376. package/src/modules/currencies/backend/currencies/page.tsx +3 -0
  377. package/src/modules/currencies/backend/exchange-rates/page.tsx +2 -0
  378. package/src/modules/customers/backend/customers/companies/page.tsx +3 -0
  379. package/src/modules/customers/backend/customers/deals/page.tsx +3 -0
  380. package/src/modules/customers/backend/customers/people/page.tsx +3 -0
  381. package/src/modules/customers/commands/deals.ts +39 -0
  382. package/src/modules/customers/components/CustomerTodosTable.tsx +1 -0
  383. package/src/modules/customers/i18n/en.json +5 -1
  384. package/src/modules/customers/notifications.ts +44 -0
  385. package/src/modules/customers/widgets/dashboard/customer-todos/widget.ts +2 -2
  386. package/src/modules/customers/widgets/dashboard/new-customers/widget.ts +2 -2
  387. package/src/modules/customers/widgets/dashboard/new-deals/widget.ts +2 -2
  388. package/src/modules/customers/widgets/dashboard/next-interactions/widget.ts +2 -2
  389. package/src/modules/dashboards/cli.ts +55 -5
  390. package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +22 -11
  391. package/src/modules/dashboards/lib/role-widgets.ts +80 -0
  392. package/src/modules/dashboards/services/widgetDataService.ts +164 -4
  393. package/src/modules/dashboards/setup.ts +16 -0
  394. package/src/modules/dashboards/widgets/dashboard/aov-kpi/widget.ts +2 -2
  395. package/src/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.ts +2 -2
  396. package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.ts +2 -2
  397. package/src/modules/dashboards/widgets/dashboard/orders-kpi/widget.ts +2 -2
  398. package/src/modules/dashboards/widgets/dashboard/pipeline-summary/widget.ts +2 -2
  399. package/src/modules/dashboards/widgets/dashboard/revenue-kpi/widget.ts +2 -2
  400. package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.ts +2 -2
  401. package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.ts +2 -2
  402. package/src/modules/dashboards/widgets/dashboard/top-customers/widget.ts +2 -2
  403. package/src/modules/dashboards/widgets/dashboard/top-products/widget.ts +2 -2
  404. package/src/modules/dictionaries/components/DictionaryTable.tsx +2 -0
  405. package/src/modules/directory/api/get/tenants/lookup.ts +75 -0
  406. package/src/modules/directory/backend/directory/organizations/page.tsx +2 -2
  407. package/src/modules/directory/backend/directory/tenants/page.tsx +2 -2
  408. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +2 -2
  409. package/src/modules/entities/components/SystemEntitiesTable.tsx +1 -1
  410. package/src/modules/entities/components/UserEntitiesTable.tsx +2 -2
  411. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +3 -4
  412. package/src/modules/feature_toggles/components/OverridesTable.tsx +1 -1
  413. package/src/modules/notifications/__tests__/deliver-notification.test.ts +195 -0
  414. package/src/modules/notifications/__tests__/deliveryStrategies.test.ts +19 -0
  415. package/src/modules/notifications/__tests__/notificationService.test.ts +208 -0
  416. package/src/modules/notifications/acl.ts +7 -0
  417. package/src/modules/notifications/api/[id]/action/route.ts +75 -0
  418. package/src/modules/notifications/api/[id]/dismiss/route.ts +12 -0
  419. package/src/modules/notifications/api/[id]/read/route.ts +12 -0
  420. package/src/modules/notifications/api/[id]/restore/route.ts +53 -0
  421. package/src/modules/notifications/api/batch/route.ts +14 -0
  422. package/src/modules/notifications/api/feature/route.ts +14 -0
  423. package/src/modules/notifications/api/mark-all-read/route.ts +34 -0
  424. package/src/modules/notifications/api/openapi.ts +76 -0
  425. package/src/modules/notifications/api/role/route.ts +14 -0
  426. package/src/modules/notifications/api/route.ts +92 -0
  427. package/src/modules/notifications/api/settings/route.ts +157 -0
  428. package/src/modules/notifications/api/unread-count/route.ts +38 -0
  429. package/src/modules/notifications/backend/config/notifications/page.meta.ts +22 -0
  430. package/src/modules/notifications/backend/config/notifications/page.tsx +12 -0
  431. package/src/modules/notifications/cli.ts +18 -0
  432. package/src/modules/notifications/data/entities.ts +99 -0
  433. package/src/modules/notifications/data/validators.ts +115 -0
  434. package/src/modules/notifications/di.ts +11 -0
  435. package/src/modules/notifications/emails/NotificationEmail.tsx +98 -0
  436. package/src/modules/notifications/frontend/NotificationInboxPageClient.tsx +42 -0
  437. package/src/modules/notifications/frontend/NotificationSettingsPageClient.tsx +233 -0
  438. package/src/modules/notifications/i18n/de.json +50 -0
  439. package/src/modules/notifications/i18n/en.json +50 -0
  440. package/src/modules/notifications/i18n/es.json +50 -0
  441. package/src/modules/notifications/i18n/pl.json +50 -0
  442. package/src/modules/notifications/index.ts +12 -0
  443. package/src/modules/notifications/lib/deliveryConfig.ts +153 -0
  444. package/src/modules/notifications/lib/deliveryStrategies.ts +50 -0
  445. package/src/modules/notifications/lib/events.ts +48 -0
  446. package/src/modules/notifications/lib/notificationBuilder.ts +121 -0
  447. package/src/modules/notifications/lib/notificationFactory.ts +76 -0
  448. package/src/modules/notifications/lib/notificationMapper.ts +33 -0
  449. package/src/modules/notifications/lib/notificationRecipients.ts +83 -0
  450. package/src/modules/notifications/lib/notificationService.ts +414 -0
  451. package/src/modules/notifications/lib/routeHelpers.ts +151 -0
  452. package/src/modules/notifications/lib/safeHref.ts +29 -0
  453. package/src/modules/notifications/migrations/.snapshot-open-mercato.json +336 -0
  454. package/src/modules/notifications/migrations/Migration20260123000001.ts +73 -0
  455. package/src/modules/notifications/migrations/Migration20260126150000.ts +39 -0
  456. package/src/modules/notifications/migrations/Migration20260129082610.ts +13 -0
  457. package/src/modules/notifications/subscribers/deliver-notification.ts +204 -0
  458. package/src/modules/notifications/workers/create-notification.worker.ts +122 -0
  459. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +2 -2
  460. package/src/modules/query_index/cli.ts +82 -13
  461. package/src/modules/query_index/components/QueryIndexesTable.tsx +8 -2
  462. package/src/modules/resources/backend/resources/resource-types/page.tsx +2 -2
  463. package/src/modules/resources/backend/resources/resources/page.tsx +2 -2
  464. package/src/modules/sales/backend/sales/channels/offers/page.tsx +2 -0
  465. package/src/modules/sales/backend/sales/channels/page.tsx +2 -0
  466. package/src/modules/sales/cli.ts +2 -43
  467. package/src/modules/sales/commands/documents.ts +65 -0
  468. package/src/modules/sales/commands/payments.ts +33 -0
  469. package/src/modules/sales/components/AdjustmentKindSettings.tsx +2 -2
  470. package/src/modules/sales/components/PaymentMethodsSettings.tsx +2 -2
  471. package/src/modules/sales/components/ShippingMethodsSettings.tsx +2 -2
  472. package/src/modules/sales/components/TaxRatesSettings.tsx +2 -2
  473. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +2 -0
  474. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +2 -0
  475. package/src/modules/sales/components/documents/PaymentsSection.tsx +2 -1
  476. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +2 -0
  477. package/src/modules/sales/i18n/de.json +20 -0
  478. package/src/modules/sales/i18n/en.json +25 -1
  479. package/src/modules/sales/i18n/es.json +20 -0
  480. package/src/modules/sales/i18n/pl.json +20 -0
  481. package/src/modules/sales/lib/seeds.ts +53 -0
  482. package/src/modules/sales/notifications.client.ts +65 -0
  483. package/src/modules/sales/notifications.ts +82 -0
  484. package/src/modules/sales/subscribers/quote-expiring-notification.ts +53 -0
  485. package/src/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.tsx +156 -0
  486. package/src/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.tsx +156 -0
  487. package/src/modules/sales/widgets/notifications/index.ts +2 -0
  488. package/src/modules/sales/widgets/notifications/useSalesDocumentTotals.ts +81 -0
  489. package/src/modules/staff/backend/staff/team-members/page.tsx +1 -1
  490. package/src/modules/staff/backend/staff/team-roles/page.tsx +2 -2
  491. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +2 -2
  492. package/src/modules/staff/backend/staff/teams/page.tsx +2 -2
  493. package/src/modules/staff/commands/leave-requests.ts +94 -0
  494. package/src/modules/staff/i18n/de.json +6 -0
  495. package/src/modules/staff/i18n/en.json +9 -1
  496. package/src/modules/staff/i18n/es.json +6 -0
  497. package/src/modules/staff/i18n/pl.json +6 -0
  498. package/src/modules/staff/notifications.ts +71 -0
  499. package/src/modules/workflows/backend/definitions/page.tsx +5 -0
  500. package/src/modules/workflows/backend/instances/page.tsx +4 -1
  501. package/src/modules/workflows/backend/tasks/page.tsx +4 -1
  502. package/src/modules/workflows/cli.ts +12 -12
  503. package/src/modules/workflows/i18n/en.json +3 -1
  504. package/src/modules/workflows/lib/__tests__/transition-handler.test.ts +6 -3
  505. package/src/modules/workflows/lib/transition-handler.ts +18 -6
  506. package/src/modules/workflows/notifications.ts +25 -0
  507. package/src/modules/workflows/subscribers/task-assigned-notification.ts +53 -0
@@ -1,95 +1,15 @@
1
- import { runWithCacheTenant } from '@open-mercato/cache'
2
1
  import type { EntityManager } from '@mikro-orm/postgresql'
3
- import type { AwilixContainer } from 'awilix'
4
- import { Role, RoleAcl } from '@open-mercato/core/modules/auth/data/entities'
5
- import type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'
6
- import { reindexModules } from '@open-mercato/core/modules/configs/lib/reindex-helpers'
7
- // Optional module imports are loaded dynamically inside each upgrade action
8
- // so the app does not crash when a module is disabled.
9
- import { collectCrudCacheStats, purgeCrudCacheSegment } from '@open-mercato/shared/lib/crud/cache-stats'
10
- import { isCrudCacheEnabled, resolveCrudCache } from '@open-mercato/shared/lib/crud/cache'
11
2
  import * as semver from 'semver'
12
- import type { VectorIndexService } from '@open-mercato/search/vector'
13
- import { EncryptionMap } from '@open-mercato/core/modules/entities/data/entities'
14
- import { DEFAULT_ENCRYPTION_MAPS } from '@open-mercato/core/modules/entities/lib/encryptionDefaults'
15
- import type { TenantDataEncryptionService } from '@open-mercato/shared/lib/encryption/tenantDataEncryptionService'
16
-
17
- function resolveVectorService(container: AwilixContainer): VectorIndexService | null {
18
- try {
19
- return container.resolve<VectorIndexService>('vectorIndexService')
20
- } catch {
21
- return null
22
- }
23
- }
24
-
25
- function resolveEncryptionService(container: AwilixContainer): TenantDataEncryptionService | null {
26
- try {
27
- return container.resolve<TenantDataEncryptionService>('tenantEncryptionService')
28
- } catch {
29
- return null
30
- }
31
- }
32
-
33
- async function ensureVectorSearchEncryptionMap(
34
- em: EntityManager,
35
- tenantId: string,
36
- organizationId: string | null,
37
- ): Promise<boolean> {
38
- const spec = DEFAULT_ENCRYPTION_MAPS.find((entry) => entry.entityId === 'vector:vector_search')
39
- const required = spec?.fields ?? []
40
- if (!required.length) return false
41
-
42
- const repo = em.getRepository(EncryptionMap)
43
- const existing = await repo.findOne({
44
- entityId: 'vector:vector_search',
45
- tenantId,
46
- organizationId,
47
- deletedAt: null,
48
- })
49
-
50
- if (!existing) {
51
- em.persist(
52
- em.create(EncryptionMap, {
53
- entityId: 'vector:vector_search',
54
- tenantId,
55
- organizationId,
56
- fieldsJson: required,
57
- isActive: true,
58
- createdAt: new Date(),
59
- updatedAt: new Date(),
60
- }),
61
- )
62
- await em.flush()
63
- return true
64
- }
65
-
66
- const existingFields = Array.isArray(existing.fieldsJson) ? existing.fieldsJson : []
67
- const byField = new Map<string, { field: string; hashField?: string | null }>()
68
- for (const item of existingFields) {
69
- if (!item?.field) continue
70
- byField.set(item.field, item)
71
- }
72
- for (const req of required) {
73
- if (!req?.field) continue
74
- if (byField.has(req.field)) continue
75
- byField.set(req.field, req)
76
- }
77
-
78
- const merged = Array.from(byField.values())
79
- const changed = merged.length !== existingFields.length
80
- if (!changed && existing.isActive) return false
81
-
82
- existing.fieldsJson = merged
83
- existing.isActive = true
84
- existing.updatedAt = new Date()
85
- await em.flush()
86
- return true
87
- }
3
+ import { getModules } from '@open-mercato/shared/lib/modules/registry'
4
+ import type { Module } from '@open-mercato/shared/modules/registry'
5
+ import type { AppContainer } from '@open-mercato/shared/lib/di/container'
6
+ import { Role, RoleAcl } from '@open-mercato/core/modules/auth/data/entities'
7
+ import { normalizeTenantId } from '@open-mercato/core/modules/auth/lib/tenantAccess'
88
8
 
89
9
  export type UpgradeActionContext = {
90
10
  tenantId: string
91
11
  organizationId: string
92
- container: AwilixContainer
12
+ container: AppContainer
93
13
  em: EntityManager
94
14
  }
95
15
 
@@ -121,26 +41,108 @@ export function compareVersions(a: string, b: string): number {
121
41
  return semver.compare(cleanA, cleanB)
122
42
  }
123
43
 
124
- async function purgeCatalogCrudCache(container: AwilixContainer, tenantId: string | null) {
125
- if (!isCrudCacheEnabled()) return
126
- const cache = resolveCrudCache(container)
127
- if (!cache) return
128
- await runWithCacheTenant(tenantId ?? null, async () => {
129
- const stats = await collectCrudCacheStats(cache)
130
- const catalogSegments = stats.segments.filter((segment) => segment.resource?.startsWith('catalog.'))
131
- if (!catalogSegments.length) return
132
- for (const segment of catalogSegments) {
133
- try {
134
- await purgeCrudCacheSegment(cache, segment.segment)
135
- } catch (error) {
136
- console.warn('[upgrade-actions] failed to purge catalog cache segment', {
137
- tenantId,
138
- segment: segment.segment,
139
- error,
140
- })
141
- }
142
- }
143
- })
44
+ type RoleName = 'superadmin' | 'admin' | 'employee'
45
+
46
+ function collectRoleFeatures(modules: Module[], moduleIds: string[]): Record<RoleName, string[]> {
47
+ const result: Record<RoleName, string[]> = {
48
+ superadmin: [],
49
+ admin: [],
50
+ employee: [],
51
+ }
52
+ const targetIds = new Set(moduleIds)
53
+ for (const mod of modules) {
54
+ if (!targetIds.has(mod.id)) continue
55
+ const roleFeatures = mod.setup?.defaultRoleFeatures
56
+ if (roleFeatures?.superadmin) result.superadmin.push(...roleFeatures.superadmin)
57
+ if (roleFeatures?.admin) result.admin.push(...roleFeatures.admin)
58
+ if (roleFeatures?.employee) result.employee.push(...roleFeatures.employee)
59
+ }
60
+ result.superadmin = Array.from(new Set(result.superadmin))
61
+ result.admin = Array.from(new Set(result.admin))
62
+ result.employee = Array.from(new Set(result.employee))
63
+ return result
64
+ }
65
+
66
+ async function findRoleByName(
67
+ em: EntityManager,
68
+ name: string,
69
+ tenantId: string | null,
70
+ ): Promise<Role | null> {
71
+ const normalizedTenant = normalizeTenantId(tenantId ?? null) ?? null
72
+ let role = await em.findOne(Role, { name, tenantId: normalizedTenant })
73
+ if (!role && normalizedTenant !== null) {
74
+ role = await em.findOne(Role, { name, tenantId: null })
75
+ }
76
+ return role
77
+ }
78
+
79
+ async function ensureRoleAclFor(
80
+ em: EntityManager,
81
+ role: Role,
82
+ tenantId: string,
83
+ features: string[],
84
+ options: { isSuperAdmin?: boolean } = {},
85
+ ) {
86
+ const existing = await em.findOne(RoleAcl, { role, tenantId })
87
+ if (!existing) {
88
+ const acl = em.create(RoleAcl, {
89
+ role,
90
+ tenantId,
91
+ featuresJson: features,
92
+ isSuperAdmin: !!options.isSuperAdmin,
93
+ createdAt: new Date(),
94
+ })
95
+ await em.persistAndFlush(acl)
96
+ return
97
+ }
98
+ const currentFeatures = Array.isArray(existing.featuresJson) ? existing.featuresJson : []
99
+ const merged = Array.from(new Set([...currentFeatures, ...features]))
100
+ const changed =
101
+ merged.length !== currentFeatures.length ||
102
+ merged.some((value, index) => value !== currentFeatures[index])
103
+ if (changed) existing.featuresJson = merged
104
+ if (options.isSuperAdmin && !existing.isSuperAdmin) {
105
+ existing.isSuperAdmin = true
106
+ }
107
+ if (changed || options.isSuperAdmin) {
108
+ await em.persistAndFlush(existing)
109
+ }
110
+ }
111
+
112
+ async function ensureRoleAclsForModules(
113
+ em: EntityManager,
114
+ tenantId: string,
115
+ moduleIds: string[],
116
+ ) {
117
+ const modules = getModules()
118
+ const roleFeatures = collectRoleFeatures(modules, moduleIds)
119
+ if (!roleFeatures.superadmin.length && !roleFeatures.admin.length && !roleFeatures.employee.length) {
120
+ return
121
+ }
122
+ const normalizedTenant = normalizeTenantId(tenantId) ?? null
123
+ const [superadminRole, adminRole, employeeRole] = await Promise.all([
124
+ findRoleByName(em, 'superadmin', normalizedTenant),
125
+ findRoleByName(em, 'admin', normalizedTenant),
126
+ findRoleByName(em, 'employee', normalizedTenant),
127
+ ])
128
+ if (superadminRole && roleFeatures.superadmin.length) {
129
+ await ensureRoleAclFor(em, superadminRole, tenantId, roleFeatures.superadmin, { isSuperAdmin: true })
130
+ }
131
+ if (adminRole && roleFeatures.admin.length) {
132
+ await ensureRoleAclFor(em, adminRole, tenantId, roleFeatures.admin)
133
+ }
134
+ if (employeeRole && roleFeatures.employee.length) {
135
+ await ensureRoleAclFor(em, employeeRole, tenantId, roleFeatures.employee)
136
+ }
137
+ }
138
+
139
+ async function safeImport<T>(label: string, loader: () => Promise<T>): Promise<T | null> {
140
+ try {
141
+ return await loader()
142
+ } catch (error) {
143
+ console.warn(`[upgrade-actions] Skipping ${label} because module import failed.`, error)
144
+ return null
145
+ }
144
146
  }
145
147
 
146
148
  export const upgradeActions: UpgradeActionDefinition[] = [
@@ -151,64 +153,16 @@ export const upgradeActions: UpgradeActionDefinition[] = [
151
153
  ctaKey: 'upgrades.v034.cta',
152
154
  successKey: 'upgrades.v034.success',
153
155
  loadingKey: 'upgrades.v034.loading',
154
- async run({ container, em, tenantId, organizationId }) {
155
- let installExampleCatalogData: typeof import('@open-mercato/core/modules/catalog/lib/seeds')['installExampleCatalogData'] | undefined
156
- try {
157
- const catalogSeeds = await import('@open-mercato/core/modules/catalog/lib/seeds')
158
- installExampleCatalogData = catalogSeeds.installExampleCatalogData
159
- } catch {
160
- console.warn('[upgrade-actions] catalog module not available, skipping catalog example data')
161
- return
162
- }
163
- await installExampleCatalogData(container, { tenantId, organizationId }, em)
164
- const vectorService = resolveVectorService(container)
165
- await reindexModules(em, ['catalog'], { tenantId, organizationId, vectorService })
166
- },
167
- },
168
- {
169
- id: 'configs.upgrades.auth.admin_business_rules_acl',
170
- version: '0.3.5',
171
- messageKey: 'upgrades.v035.message',
172
- ctaKey: 'upgrades.v035.cta',
173
- successKey: 'upgrades.v035.success',
174
- loadingKey: 'upgrades.v035.loading',
175
- async run({ container, em, tenantId }) {
176
- const normalizedTenantId = tenantId.trim()
177
- await em.transactional(async (tem) => {
178
- const adminRole = await tem.findOne(Role, { name: 'admin', tenantId: normalizedTenantId, deletedAt: null })
179
- if (!adminRole) return
180
-
181
- const roleAcls = await tem.find(RoleAcl, { role: adminRole, tenantId: normalizedTenantId, deletedAt: null })
182
- let touched = false
183
- if (!roleAcls.length) {
184
- tem.persist(
185
- tem.create(RoleAcl, {
186
- role: adminRole,
187
- tenantId: normalizedTenantId,
188
- featuresJson: ['business_rules.*'],
189
- isSuperAdmin: false,
190
- createdAt: new Date(),
191
- updatedAt: new Date(),
192
- }),
193
- )
194
- touched = true
195
- }
196
-
197
- for (const acl of roleAcls) {
198
- const features = Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : []
199
- if (features.includes('business_rules.*')) continue
200
- acl.featuresJson = [...features, 'business_rules.*']
201
- acl.updatedAt = new Date()
202
- touched = true
203
- }
204
-
205
- if (touched) {
206
- await tem.flush()
207
- }
208
- })
209
-
210
- const rbac = container.resolve<RbacService>('rbacService')
211
- await rbac.invalidateTenantCache(normalizedTenantId)
156
+ async run(ctx) {
157
+ const catalogSeeds = await safeImport('catalog examples', () =>
158
+ import('@open-mercato/core/modules/catalog/lib/seeds')
159
+ )
160
+ if (!catalogSeeds?.installExampleCatalogData) return
161
+ await catalogSeeds.installExampleCatalogData(
162
+ ctx.container,
163
+ { tenantId: ctx.tenantId, organizationId: ctx.organizationId },
164
+ ctx.em,
165
+ )
212
166
  },
213
167
  },
214
168
  {
@@ -218,51 +172,15 @@ export const upgradeActions: UpgradeActionDefinition[] = [
218
172
  ctaKey: 'upgrades.v036.cta',
219
173
  successKey: 'upgrades.v036.success',
220
174
  loadingKey: 'upgrades.v036.loading',
221
- async run({ container, em, tenantId, organizationId }) {
222
- let seedSalesExamples: typeof import('@open-mercato/core/modules/sales/seed/examples')['seedSalesExamples'] | undefined
223
- try {
224
- const salesSeeds = await import('@open-mercato/core/modules/sales/seed/examples')
225
- seedSalesExamples = salesSeeds.seedSalesExamples
226
- } catch {
227
- console.warn('[upgrade-actions] sales module not available, skipping sales example data')
228
- return
229
- }
230
- await em.transactional(async (tem) => {
231
- await seedSalesExamples!(tem, container, { tenantId, organizationId })
175
+ async run(ctx) {
176
+ const salesSeeds = await safeImport('sales examples', () =>
177
+ import('@open-mercato/core/modules/sales/seed/examples')
178
+ )
179
+ if (!salesSeeds?.seedSalesExamples) return
180
+ await salesSeeds.seedSalesExamples(ctx.em, ctx.container, {
181
+ tenantId: ctx.tenantId,
182
+ organizationId: ctx.organizationId,
232
183
  })
233
- const vectorService = resolveVectorService(container)
234
- await reindexModules(em, ['sales', 'catalog'], { tenantId, organizationId, vectorService })
235
- await purgeCatalogCrudCache(container, tenantId)
236
- },
237
- },
238
- {
239
- id: 'configs.upgrades.vector.encryption_vector_search',
240
- version: '0.3.6',
241
- messageKey: 'upgrades.v036_vector_encryption.message',
242
- ctaKey: 'upgrades.v036_vector_encryption.cta',
243
- successKey: 'upgrades.v036_vector_encryption.success',
244
- loadingKey: 'upgrades.v036_vector_encryption.loading',
245
- async run({ container, em, tenantId, organizationId }) {
246
- const normalizedTenantId = tenantId.trim()
247
- const normalizedOrgId = organizationId ?? null
248
-
249
- const encryptionService = resolveEncryptionService(container)
250
- if (!encryptionService?.isEnabled?.()) {
251
- return
252
- }
253
-
254
- const updated = await em.transactional(async (tem) => {
255
- return ensureVectorSearchEncryptionMap(tem, normalizedTenantId, normalizedOrgId)
256
- })
257
-
258
- if (updated) {
259
- await encryptionService.invalidateMap('vector:vector_search', normalizedTenantId, normalizedOrgId)
260
- }
261
-
262
- const vectorService = resolveVectorService(container)
263
- if (vectorService) {
264
- await vectorService.reindexAll({ tenantId: normalizedTenantId, organizationId: normalizedOrgId, purgeFirst: false })
265
- }
266
184
  },
267
185
  },
268
186
  {
@@ -272,67 +190,21 @@ export const upgradeActions: UpgradeActionDefinition[] = [
272
190
  ctaKey: 'upgrades.v0313.cta',
273
191
  successKey: 'upgrades.v0313.success',
274
192
  loadingKey: 'upgrades.v0313.loading',
275
- async run({ container, em, tenantId, organizationId }) {
276
- const normalizedTenantId = tenantId.trim()
277
- const scope = { tenantId, organizationId }
278
-
279
- let seedExampleCurrencies: typeof import('@open-mercato/core/modules/currencies/lib/seeds')['seedExampleCurrencies'] | undefined
280
- try {
281
- const currenciesSeeds = await import('@open-mercato/core/modules/currencies/lib/seeds')
282
- seedExampleCurrencies = currenciesSeeds.seedExampleCurrencies
283
- } catch {
284
- console.warn('[upgrade-actions] currencies module not available, skipping currency seeding')
193
+ async run(ctx) {
194
+ const currenciesSeeds = await safeImport('currencies examples', () =>
195
+ import('@open-mercato/core/modules/currencies/lib/seeds')
196
+ )
197
+ const workflowsSeeds = await safeImport('workflows examples', () =>
198
+ import('@open-mercato/core/modules/workflows/lib/seeds')
199
+ )
200
+ const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId }
201
+ if (currenciesSeeds?.seedExampleCurrencies) {
202
+ await currenciesSeeds.seedExampleCurrencies(ctx.em, scope)
285
203
  }
286
-
287
- let seedExampleWorkflows: typeof import('@open-mercato/core/modules/workflows/lib/seeds')['seedExampleWorkflows'] | undefined
288
- try {
289
- const workflowsSeeds = await import('@open-mercato/core/modules/workflows/lib/seeds')
290
- seedExampleWorkflows = workflowsSeeds.seedExampleWorkflows
291
- } catch {
292
- console.warn('[upgrade-actions] workflows module not available, skipping workflow seeding')
204
+ if (workflowsSeeds?.seedExampleWorkflows) {
205
+ await workflowsSeeds.seedExampleWorkflows(ctx.em, scope)
293
206
  }
294
-
295
- await em.transactional(async (tem) => {
296
- if (seedExampleCurrencies) await seedExampleCurrencies(tem, scope)
297
- if (seedExampleWorkflows) await seedExampleWorkflows(tem, scope)
298
-
299
- const adminRole = await tem.findOne(Role, { name: 'admin', tenantId: normalizedTenantId, deletedAt: null })
300
- if (!adminRole) return
301
-
302
- const roleAcls = await tem.find(RoleAcl, { role: adminRole, tenantId: normalizedTenantId, deletedAt: null })
303
- let touched = false
304
- if (!roleAcls.length) {
305
- tem.persist(
306
- tem.create(RoleAcl, {
307
- role: adminRole,
308
- tenantId: normalizedTenantId,
309
- featuresJson: ['search.*', 'feature_toggles.*', 'currencies.*'],
310
- isSuperAdmin: false,
311
- createdAt: new Date(),
312
- updatedAt: new Date(),
313
- }),
314
- )
315
- touched = true
316
- }
317
-
318
- for (const acl of roleAcls) {
319
- const features = Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : []
320
- const nextFeatures = new Set(features)
321
- nextFeatures.add('search.*')
322
- nextFeatures.add('feature_toggles.*')
323
- nextFeatures.add('currencies.*')
324
- if (nextFeatures.size === features.length) continue
325
- acl.featuresJson = Array.from(nextFeatures)
326
- acl.updatedAt = new Date()
327
- touched = true
328
- }
329
-
330
- if (touched) {
331
- await tem.flush()
332
- }
333
- })
334
- const rbac = container.resolve<RbacService>('rbacService')
335
- await rbac.invalidateTenantCache(normalizedTenantId)
207
+ await ensureRoleAclsForModules(ctx.em, ctx.tenantId, ['currencies', 'workflows'])
336
208
  },
337
209
  },
338
210
  {
@@ -342,93 +214,27 @@ export const upgradeActions: UpgradeActionDefinition[] = [
342
214
  ctaKey: 'upgrades.v041.cta',
343
215
  successKey: 'upgrades.v041.success',
344
216
  loadingKey: 'upgrades.v041.loading',
345
- async run({ container, em, tenantId, organizationId }) {
346
- const normalizedTenantId = tenantId.trim()
347
- const scope = { tenantId, organizationId }
348
-
349
- let seedPlannerAvailabilityRuleSetDefaults: typeof import('@open-mercato/core/modules/planner/lib/seeds')['seedPlannerAvailabilityRuleSetDefaults'] | undefined
350
- let seedPlannerUnavailabilityReasons: typeof import('@open-mercato/core/modules/planner/lib/seeds')['seedPlannerUnavailabilityReasons'] | undefined
351
- try {
352
- const plannerSeeds = await import('@open-mercato/core/modules/planner/lib/seeds')
353
- seedPlannerAvailabilityRuleSetDefaults = plannerSeeds.seedPlannerAvailabilityRuleSetDefaults
354
- seedPlannerUnavailabilityReasons = plannerSeeds.seedPlannerUnavailabilityReasons
355
- } catch {
356
- console.warn('[upgrade-actions] planner module not available, skipping planner seeding')
217
+ async run(ctx) {
218
+ const plannerSeeds = await safeImport('planner examples', () =>
219
+ import('@open-mercato/core/modules/planner/lib/seeds')
220
+ )
221
+ const staffSeeds = await safeImport('staff examples', () =>
222
+ import('@open-mercato/core/modules/staff/lib/seeds')
223
+ )
224
+ const resourcesSeeds = await safeImport('resources examples', () =>
225
+ import('@open-mercato/core/modules/resources/lib/seeds')
226
+ )
227
+ const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId }
228
+ if (plannerSeeds?.seedPlannerAvailabilityRuleSetDefaults) {
229
+ await plannerSeeds.seedPlannerAvailabilityRuleSetDefaults(ctx.em, scope)
357
230
  }
358
-
359
- let seedStaffTeamExamples: typeof import('@open-mercato/core/modules/staff/lib/seeds')['seedStaffTeamExamples'] | undefined
360
- try {
361
- const staffSeeds = await import('@open-mercato/core/modules/staff/lib/seeds')
362
- seedStaffTeamExamples = staffSeeds.seedStaffTeamExamples
363
- } catch {
364
- console.warn('[upgrade-actions] staff module not available, skipping staff seeding')
231
+ if (staffSeeds?.seedStaffTeamExamples) {
232
+ await staffSeeds.seedStaffTeamExamples(ctx.em, scope)
365
233
  }
366
-
367
- let seedResourcesAddressTypes: typeof import('@open-mercato/core/modules/resources/lib/seeds')['seedResourcesAddressTypes'] | undefined
368
- let seedResourcesCapacityUnits: typeof import('@open-mercato/core/modules/resources/lib/seeds')['seedResourcesCapacityUnits'] | undefined
369
- let seedResourcesResourceExamples: typeof import('@open-mercato/core/modules/resources/lib/seeds')['seedResourcesResourceExamples'] | undefined
370
- try {
371
- const resourcesSeeds = await import('@open-mercato/core/modules/resources/lib/seeds')
372
- seedResourcesAddressTypes = resourcesSeeds.seedResourcesAddressTypes
373
- seedResourcesCapacityUnits = resourcesSeeds.seedResourcesCapacityUnits
374
- seedResourcesResourceExamples = resourcesSeeds.seedResourcesResourceExamples
375
- } catch {
376
- console.warn('[upgrade-actions] resources module not available, skipping resources seeding')
234
+ if (resourcesSeeds?.seedResourcesResourceExamples) {
235
+ await resourcesSeeds.seedResourcesResourceExamples(ctx.em, scope)
377
236
  }
378
-
379
- await em.transactional(async (tem) => {
380
- if (seedPlannerAvailabilityRuleSetDefaults) await seedPlannerAvailabilityRuleSetDefaults(tem, scope)
381
- if (seedPlannerUnavailabilityReasons) await seedPlannerUnavailabilityReasons(tem, scope)
382
- if (seedStaffTeamExamples) await seedStaffTeamExamples(tem, scope)
383
- if (seedResourcesCapacityUnits) await seedResourcesCapacityUnits(tem, scope)
384
- if (seedResourcesAddressTypes) await seedResourcesAddressTypes(tem, scope)
385
- if (seedResourcesResourceExamples) await seedResourcesResourceExamples(tem, scope)
386
-
387
- const adminRole = await tem.findOne(Role, { name: 'admin', tenantId: normalizedTenantId, deletedAt: null })
388
- if (!adminRole) return
389
-
390
- const roleAcls = await tem.find(RoleAcl, { role: adminRole, tenantId: normalizedTenantId, deletedAt: null })
391
- const addedFeatures = [
392
- 'staff.*',
393
- 'staff.leave_requests.manage',
394
- 'resources.*',
395
- 'planner.*',
396
- ]
397
- let touched = false
398
- if (!roleAcls.length) {
399
- tem.persist(
400
- tem.create(RoleAcl, {
401
- role: adminRole,
402
- tenantId: normalizedTenantId,
403
- featuresJson: addedFeatures,
404
- isSuperAdmin: false,
405
- createdAt: new Date(),
406
- updatedAt: new Date(),
407
- }),
408
- )
409
- touched = true
410
- }
411
-
412
- for (const acl of roleAcls) {
413
- const features = Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : []
414
- const nextFeatures = new Set(features)
415
- for (const feature of addedFeatures) nextFeatures.add(feature)
416
- if (nextFeatures.size === features.length) continue
417
- acl.featuresJson = Array.from(nextFeatures)
418
- acl.updatedAt = new Date()
419
- touched = true
420
- }
421
-
422
- if (touched) {
423
- await tem.flush()
424
- }
425
- })
426
-
427
- const rbac = container.resolve<RbacService>('rbacService')
428
- await rbac.invalidateTenantCache(normalizedTenantId)
429
-
430
- const vectorService = resolveVectorService(container)
431
- await reindexModules(em, ['planner', 'staff', 'resources'], { tenantId, organizationId, vectorService })
237
+ await ensureRoleAclsForModules(ctx.em, ctx.tenantId, ['planner', 'staff', 'resources'])
432
238
  },
433
239
  },
434
240
  ]
@@ -256,12 +256,14 @@ export default function CurrenciesPage() {
256
256
  <RowActions
257
257
  items={[
258
258
  {
259
+ id: 'edit',
259
260
  label: t('common.edit'),
260
261
  href: `/backend/currencies/${row.id}`,
261
262
  },
262
263
  ...(!row.isBase
263
264
  ? [
264
265
  {
266
+ id: 'set-base',
265
267
  label: t('currencies.list.actions.setBase'),
266
268
  onSelect: () => handleSetBase(row),
267
269
  },
@@ -270,6 +272,7 @@ export default function CurrenciesPage() {
270
272
  ...(!row.isBase
271
273
  ? [
272
274
  {
275
+ id: 'delete',
273
276
  label: t('common.delete'),
274
277
  destructive: true,
275
278
  onSelect: () => handleDelete(row),
@@ -279,10 +279,12 @@ export default function ExchangeRatesPage() {
279
279
  <RowActions
280
280
  items={[
281
281
  {
282
+ id: 'edit',
282
283
  label: t('common.edit'),
283
284
  href: `/backend/exchange-rates/${row.id}`,
284
285
  },
285
286
  {
287
+ id: 'delete',
286
288
  label: t('common.delete'),
287
289
  destructive: true,
288
290
  onSelect: () => handleDelete(row),
@@ -597,14 +597,17 @@ export default function CustomersCompaniesPage() {
597
597
  <RowActions
598
598
  items={[
599
599
  {
600
+ id: 'view',
600
601
  label: t('customers.companies.list.actions.view'),
601
602
  onSelect: () => { router.push(`/backend/customers/companies/${row.id}`) },
602
603
  },
603
604
  {
605
+ id: 'open-new-tab',
604
606
  label: t('customers.companies.list.actions.openInNewTab'),
605
607
  onSelect: () => window.open(`/backend/customers/companies/${row.id}`, '_blank', 'noopener'),
606
608
  },
607
609
  {
610
+ id: 'delete',
608
611
  label: t('customers.companies.list.actions.delete'),
609
612
  destructive: true,
610
613
  onSelect: () => handleDelete(row),
@@ -889,10 +889,12 @@ export default function CustomersDealsPage() {
889
889
  <RowActions
890
890
  items={[
891
891
  {
892
+ id: 'edit',
892
893
  label: t('customers.deals.list.actions.edit', 'Edit'),
893
894
  onSelect: () => { router.push(`/backend/customers/deals/${row.id}`) },
894
895
  },
895
896
  {
897
+ id: 'open-new-tab',
896
898
  label: t('customers.deals.list.actions.openInNewTab', 'Open in new tab'),
897
899
  onSelect: () => {
898
900
  if (typeof window !== 'undefined') {
@@ -901,6 +903,7 @@ export default function CustomersDealsPage() {
901
903
  },
902
904
  },
903
905
  {
906
+ id: 'delete',
904
907
  label: isDeleting
905
908
  ? t('customers.deals.list.actions.deleting', 'Deleting…')
906
909
  : t('customers.deals.list.actions.delete', 'Delete'),
@@ -614,14 +614,17 @@ export default function CustomersPeoplePage() {
614
614
  <RowActions
615
615
  items={[
616
616
  {
617
+ id: 'view',
617
618
  label: t('customers.people.list.actions.view'),
618
619
  onSelect: () => { router.push(`/backend/customers/people/${row.id}`) },
619
620
  },
620
621
  {
622
+ id: 'open-new-tab',
621
623
  label: t('customers.people.list.actions.openInNewTab'),
622
624
  onSelect: () => window.open(`/backend/customers/people/${row.id}`, '_blank', 'noopener'),
623
625
  },
624
626
  {
627
+ id: 'delete',
625
628
  label: t('customers.people.list.actions.delete'),
626
629
  destructive: true,
627
630
  onSelect: () => handleDelete(row),