@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,102 +1,98 @@
1
- import { runWithCacheTenant } from "@open-mercato/cache";
2
- import { Role, RoleAcl } from "@open-mercato/core/modules/auth/data/entities";
3
- import { reindexModules } from "@open-mercato/core/modules/configs/lib/reindex-helpers";
4
- import { collectCrudCacheStats, purgeCrudCacheSegment } from "@open-mercato/shared/lib/crud/cache-stats";
5
- import { isCrudCacheEnabled, resolveCrudCache } from "@open-mercato/shared/lib/crud/cache";
6
1
  import * as semver from "semver";
7
- import { EncryptionMap } from "@open-mercato/core/modules/entities/data/entities";
8
- import { DEFAULT_ENCRYPTION_MAPS } from "@open-mercato/core/modules/entities/lib/encryptionDefaults";
9
- function resolveVectorService(container) {
10
- try {
11
- return container.resolve("vectorIndexService");
12
- } catch {
13
- return null;
2
+ import { getModules } from "@open-mercato/shared/lib/modules/registry";
3
+ import { Role, RoleAcl } from "@open-mercato/core/modules/auth/data/entities";
4
+ import { normalizeTenantId } from "@open-mercato/core/modules/auth/lib/tenantAccess";
5
+ function compareVersions(a, b) {
6
+ const cleanA = semver.valid(semver.coerce(a));
7
+ const cleanB = semver.valid(semver.coerce(b));
8
+ if (!cleanA) {
9
+ throw new Error(`Invalid version string: "${a}". Expected a valid semver format (e.g., "1.2.3").`);
10
+ }
11
+ if (!cleanB) {
12
+ throw new Error(`Invalid version string: "${b}". Expected a valid semver format (e.g., "1.2.3").`);
14
13
  }
14
+ return semver.compare(cleanA, cleanB);
15
15
  }
16
- function resolveEncryptionService(container) {
17
- try {
18
- return container.resolve("tenantEncryptionService");
19
- } catch {
20
- return null;
16
+ function collectRoleFeatures(modules, moduleIds) {
17
+ const result = {
18
+ superadmin: [],
19
+ admin: [],
20
+ employee: []
21
+ };
22
+ const targetIds = new Set(moduleIds);
23
+ for (const mod of modules) {
24
+ if (!targetIds.has(mod.id)) continue;
25
+ const roleFeatures = mod.setup?.defaultRoleFeatures;
26
+ if (roleFeatures?.superadmin) result.superadmin.push(...roleFeatures.superadmin);
27
+ if (roleFeatures?.admin) result.admin.push(...roleFeatures.admin);
28
+ if (roleFeatures?.employee) result.employee.push(...roleFeatures.employee);
21
29
  }
30
+ result.superadmin = Array.from(new Set(result.superadmin));
31
+ result.admin = Array.from(new Set(result.admin));
32
+ result.employee = Array.from(new Set(result.employee));
33
+ return result;
22
34
  }
23
- async function ensureVectorSearchEncryptionMap(em, tenantId, organizationId) {
24
- const spec = DEFAULT_ENCRYPTION_MAPS.find((entry) => entry.entityId === "vector:vector_search");
25
- const required = spec?.fields ?? [];
26
- if (!required.length) return false;
27
- const repo = em.getRepository(EncryptionMap);
28
- const existing = await repo.findOne({
29
- entityId: "vector:vector_search",
30
- tenantId,
31
- organizationId,
32
- deletedAt: null
33
- });
35
+ async function findRoleByName(em, name, tenantId) {
36
+ const normalizedTenant = normalizeTenantId(tenantId ?? null) ?? null;
37
+ let role = await em.findOne(Role, { name, tenantId: normalizedTenant });
38
+ if (!role && normalizedTenant !== null) {
39
+ role = await em.findOne(Role, { name, tenantId: null });
40
+ }
41
+ return role;
42
+ }
43
+ async function ensureRoleAclFor(em, role, tenantId, features, options = {}) {
44
+ const existing = await em.findOne(RoleAcl, { role, tenantId });
34
45
  if (!existing) {
35
- em.persist(
36
- em.create(EncryptionMap, {
37
- entityId: "vector:vector_search",
38
- tenantId,
39
- organizationId,
40
- fieldsJson: required,
41
- isActive: true,
42
- createdAt: /* @__PURE__ */ new Date(),
43
- updatedAt: /* @__PURE__ */ new Date()
44
- })
45
- );
46
- await em.flush();
47
- return true;
46
+ const acl = em.create(RoleAcl, {
47
+ role,
48
+ tenantId,
49
+ featuresJson: features,
50
+ isSuperAdmin: !!options.isSuperAdmin,
51
+ createdAt: /* @__PURE__ */ new Date()
52
+ });
53
+ await em.persistAndFlush(acl);
54
+ return;
48
55
  }
49
- const existingFields = Array.isArray(existing.fieldsJson) ? existing.fieldsJson : [];
50
- const byField = /* @__PURE__ */ new Map();
51
- for (const item of existingFields) {
52
- if (!item?.field) continue;
53
- byField.set(item.field, item);
56
+ const currentFeatures = Array.isArray(existing.featuresJson) ? existing.featuresJson : [];
57
+ const merged = Array.from(/* @__PURE__ */ new Set([...currentFeatures, ...features]));
58
+ const changed = merged.length !== currentFeatures.length || merged.some((value, index) => value !== currentFeatures[index]);
59
+ if (changed) existing.featuresJson = merged;
60
+ if (options.isSuperAdmin && !existing.isSuperAdmin) {
61
+ existing.isSuperAdmin = true;
54
62
  }
55
- for (const req of required) {
56
- if (!req?.field) continue;
57
- if (byField.has(req.field)) continue;
58
- byField.set(req.field, req);
63
+ if (changed || options.isSuperAdmin) {
64
+ await em.persistAndFlush(existing);
59
65
  }
60
- const merged = Array.from(byField.values());
61
- const changed = merged.length !== existingFields.length;
62
- if (!changed && existing.isActive) return false;
63
- existing.fieldsJson = merged;
64
- existing.isActive = true;
65
- existing.updatedAt = /* @__PURE__ */ new Date();
66
- await em.flush();
67
- return true;
68
66
  }
69
- function compareVersions(a, b) {
70
- const cleanA = semver.valid(semver.coerce(a));
71
- const cleanB = semver.valid(semver.coerce(b));
72
- if (!cleanA) {
73
- throw new Error(`Invalid version string: "${a}". Expected a valid semver format (e.g., "1.2.3").`);
67
+ async function ensureRoleAclsForModules(em, tenantId, moduleIds) {
68
+ const modules = getModules();
69
+ const roleFeatures = collectRoleFeatures(modules, moduleIds);
70
+ if (!roleFeatures.superadmin.length && !roleFeatures.admin.length && !roleFeatures.employee.length) {
71
+ return;
74
72
  }
75
- if (!cleanB) {
76
- throw new Error(`Invalid version string: "${b}". Expected a valid semver format (e.g., "1.2.3").`);
73
+ const normalizedTenant = normalizeTenantId(tenantId) ?? null;
74
+ const [superadminRole, adminRole, employeeRole] = await Promise.all([
75
+ findRoleByName(em, "superadmin", normalizedTenant),
76
+ findRoleByName(em, "admin", normalizedTenant),
77
+ findRoleByName(em, "employee", normalizedTenant)
78
+ ]);
79
+ if (superadminRole && roleFeatures.superadmin.length) {
80
+ await ensureRoleAclFor(em, superadminRole, tenantId, roleFeatures.superadmin, { isSuperAdmin: true });
81
+ }
82
+ if (adminRole && roleFeatures.admin.length) {
83
+ await ensureRoleAclFor(em, adminRole, tenantId, roleFeatures.admin);
84
+ }
85
+ if (employeeRole && roleFeatures.employee.length) {
86
+ await ensureRoleAclFor(em, employeeRole, tenantId, roleFeatures.employee);
77
87
  }
78
- return semver.compare(cleanA, cleanB);
79
88
  }
80
- async function purgeCatalogCrudCache(container, tenantId) {
81
- if (!isCrudCacheEnabled()) return;
82
- const cache = resolveCrudCache(container);
83
- if (!cache) return;
84
- await runWithCacheTenant(tenantId ?? null, async () => {
85
- const stats = await collectCrudCacheStats(cache);
86
- const catalogSegments = stats.segments.filter((segment) => segment.resource?.startsWith("catalog."));
87
- if (!catalogSegments.length) return;
88
- for (const segment of catalogSegments) {
89
- try {
90
- await purgeCrudCacheSegment(cache, segment.segment);
91
- } catch (error) {
92
- console.warn("[upgrade-actions] failed to purge catalog cache segment", {
93
- tenantId,
94
- segment: segment.segment,
95
- error
96
- });
97
- }
98
- }
99
- });
89
+ async function safeImport(label, loader) {
90
+ try {
91
+ return await loader();
92
+ } catch (error) {
93
+ console.warn(`[upgrade-actions] Skipping ${label} because module import failed.`, error);
94
+ return null;
95
+ }
100
96
  }
101
97
  const upgradeActions = [
102
98
  {
@@ -106,60 +102,17 @@ const upgradeActions = [
106
102
  ctaKey: "upgrades.v034.cta",
107
103
  successKey: "upgrades.v034.success",
108
104
  loadingKey: "upgrades.v034.loading",
109
- async run({ container, em, tenantId, organizationId }) {
110
- let installExampleCatalogData;
111
- try {
112
- const catalogSeeds = await import("@open-mercato/core/modules/catalog/lib/seeds");
113
- installExampleCatalogData = catalogSeeds.installExampleCatalogData;
114
- } catch {
115
- console.warn("[upgrade-actions] catalog module not available, skipping catalog example data");
116
- return;
117
- }
118
- await installExampleCatalogData(container, { tenantId, organizationId }, em);
119
- const vectorService = resolveVectorService(container);
120
- await reindexModules(em, ["catalog"], { tenantId, organizationId, vectorService });
121
- }
122
- },
123
- {
124
- id: "configs.upgrades.auth.admin_business_rules_acl",
125
- version: "0.3.5",
126
- messageKey: "upgrades.v035.message",
127
- ctaKey: "upgrades.v035.cta",
128
- successKey: "upgrades.v035.success",
129
- loadingKey: "upgrades.v035.loading",
130
- async run({ container, em, tenantId }) {
131
- const normalizedTenantId = tenantId.trim();
132
- await em.transactional(async (tem) => {
133
- const adminRole = await tem.findOne(Role, { name: "admin", tenantId: normalizedTenantId, deletedAt: null });
134
- if (!adminRole) return;
135
- const roleAcls = await tem.find(RoleAcl, { role: adminRole, tenantId: normalizedTenantId, deletedAt: null });
136
- let touched = false;
137
- if (!roleAcls.length) {
138
- tem.persist(
139
- tem.create(RoleAcl, {
140
- role: adminRole,
141
- tenantId: normalizedTenantId,
142
- featuresJson: ["business_rules.*"],
143
- isSuperAdmin: false,
144
- createdAt: /* @__PURE__ */ new Date(),
145
- updatedAt: /* @__PURE__ */ new Date()
146
- })
147
- );
148
- touched = true;
149
- }
150
- for (const acl of roleAcls) {
151
- const features = Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : [];
152
- if (features.includes("business_rules.*")) continue;
153
- acl.featuresJson = [...features, "business_rules.*"];
154
- acl.updatedAt = /* @__PURE__ */ new Date();
155
- touched = true;
156
- }
157
- if (touched) {
158
- await tem.flush();
159
- }
160
- });
161
- const rbac = container.resolve("rbacService");
162
- await rbac.invalidateTenantCache(normalizedTenantId);
105
+ async run(ctx) {
106
+ const catalogSeeds = await safeImport(
107
+ "catalog examples",
108
+ () => import("@open-mercato/core/modules/catalog/lib/seeds")
109
+ );
110
+ if (!catalogSeeds?.installExampleCatalogData) return;
111
+ await catalogSeeds.installExampleCatalogData(
112
+ ctx.container,
113
+ { tenantId: ctx.tenantId, organizationId: ctx.organizationId },
114
+ ctx.em
115
+ );
163
116
  }
164
117
  },
165
118
  {
@@ -169,47 +122,16 @@ const upgradeActions = [
169
122
  ctaKey: "upgrades.v036.cta",
170
123
  successKey: "upgrades.v036.success",
171
124
  loadingKey: "upgrades.v036.loading",
172
- async run({ container, em, tenantId, organizationId }) {
173
- let seedSalesExamples;
174
- try {
175
- const salesSeeds = await import("@open-mercato/core/modules/sales/seed/examples");
176
- seedSalesExamples = salesSeeds.seedSalesExamples;
177
- } catch {
178
- console.warn("[upgrade-actions] sales module not available, skipping sales example data");
179
- return;
180
- }
181
- await em.transactional(async (tem) => {
182
- await seedSalesExamples(tem, container, { tenantId, organizationId });
183
- });
184
- const vectorService = resolveVectorService(container);
185
- await reindexModules(em, ["sales", "catalog"], { tenantId, organizationId, vectorService });
186
- await purgeCatalogCrudCache(container, tenantId);
187
- }
188
- },
189
- {
190
- id: "configs.upgrades.vector.encryption_vector_search",
191
- version: "0.3.6",
192
- messageKey: "upgrades.v036_vector_encryption.message",
193
- ctaKey: "upgrades.v036_vector_encryption.cta",
194
- successKey: "upgrades.v036_vector_encryption.success",
195
- loadingKey: "upgrades.v036_vector_encryption.loading",
196
- async run({ container, em, tenantId, organizationId }) {
197
- const normalizedTenantId = tenantId.trim();
198
- const normalizedOrgId = organizationId ?? null;
199
- const encryptionService = resolveEncryptionService(container);
200
- if (!encryptionService?.isEnabled?.()) {
201
- return;
202
- }
203
- const updated = await em.transactional(async (tem) => {
204
- return ensureVectorSearchEncryptionMap(tem, normalizedTenantId, normalizedOrgId);
125
+ async run(ctx) {
126
+ const salesSeeds = await safeImport(
127
+ "sales examples",
128
+ () => import("@open-mercato/core/modules/sales/seed/examples")
129
+ );
130
+ if (!salesSeeds?.seedSalesExamples) return;
131
+ await salesSeeds.seedSalesExamples(ctx.em, ctx.container, {
132
+ tenantId: ctx.tenantId,
133
+ organizationId: ctx.organizationId
205
134
  });
206
- if (updated) {
207
- await encryptionService.invalidateMap("vector:vector_search", normalizedTenantId, normalizedOrgId);
208
- }
209
- const vectorService = resolveVectorService(container);
210
- if (vectorService) {
211
- await vectorService.reindexAll({ tenantId: normalizedTenantId, organizationId: normalizedOrgId, purgeFirst: false });
212
- }
213
135
  }
214
136
  },
215
137
  {
@@ -219,60 +141,23 @@ const upgradeActions = [
219
141
  ctaKey: "upgrades.v0313.cta",
220
142
  successKey: "upgrades.v0313.success",
221
143
  loadingKey: "upgrades.v0313.loading",
222
- async run({ container, em, tenantId, organizationId }) {
223
- const normalizedTenantId = tenantId.trim();
224
- const scope = { tenantId, organizationId };
225
- let seedExampleCurrencies;
226
- try {
227
- const currenciesSeeds = await import("@open-mercato/core/modules/currencies/lib/seeds");
228
- seedExampleCurrencies = currenciesSeeds.seedExampleCurrencies;
229
- } catch {
230
- console.warn("[upgrade-actions] currencies module not available, skipping currency seeding");
144
+ async run(ctx) {
145
+ const currenciesSeeds = await safeImport(
146
+ "currencies examples",
147
+ () => import("@open-mercato/core/modules/currencies/lib/seeds")
148
+ );
149
+ const workflowsSeeds = await safeImport(
150
+ "workflows examples",
151
+ () => import("@open-mercato/core/modules/workflows/lib/seeds")
152
+ );
153
+ const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId };
154
+ if (currenciesSeeds?.seedExampleCurrencies) {
155
+ await currenciesSeeds.seedExampleCurrencies(ctx.em, scope);
231
156
  }
232
- let seedExampleWorkflows;
233
- try {
234
- const workflowsSeeds = await import("@open-mercato/core/modules/workflows/lib/seeds");
235
- seedExampleWorkflows = workflowsSeeds.seedExampleWorkflows;
236
- } catch {
237
- console.warn("[upgrade-actions] workflows module not available, skipping workflow seeding");
157
+ if (workflowsSeeds?.seedExampleWorkflows) {
158
+ await workflowsSeeds.seedExampleWorkflows(ctx.em, scope);
238
159
  }
239
- await em.transactional(async (tem) => {
240
- if (seedExampleCurrencies) await seedExampleCurrencies(tem, scope);
241
- if (seedExampleWorkflows) await seedExampleWorkflows(tem, scope);
242
- const adminRole = await tem.findOne(Role, { name: "admin", tenantId: normalizedTenantId, deletedAt: null });
243
- if (!adminRole) return;
244
- const roleAcls = await tem.find(RoleAcl, { role: adminRole, tenantId: normalizedTenantId, deletedAt: null });
245
- let touched = false;
246
- if (!roleAcls.length) {
247
- tem.persist(
248
- tem.create(RoleAcl, {
249
- role: adminRole,
250
- tenantId: normalizedTenantId,
251
- featuresJson: ["search.*", "feature_toggles.*", "currencies.*"],
252
- isSuperAdmin: false,
253
- createdAt: /* @__PURE__ */ new Date(),
254
- updatedAt: /* @__PURE__ */ new Date()
255
- })
256
- );
257
- touched = true;
258
- }
259
- for (const acl of roleAcls) {
260
- const features = Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : [];
261
- const nextFeatures = new Set(features);
262
- nextFeatures.add("search.*");
263
- nextFeatures.add("feature_toggles.*");
264
- nextFeatures.add("currencies.*");
265
- if (nextFeatures.size === features.length) continue;
266
- acl.featuresJson = Array.from(nextFeatures);
267
- acl.updatedAt = /* @__PURE__ */ new Date();
268
- touched = true;
269
- }
270
- if (touched) {
271
- await tem.flush();
272
- }
273
- });
274
- const rbac = container.resolve("rbacService");
275
- await rbac.invalidateTenantCache(normalizedTenantId);
160
+ await ensureRoleAclsForModules(ctx.em, ctx.tenantId, ["currencies", "workflows"]);
276
161
  }
277
162
  },
278
163
  {
@@ -282,83 +167,30 @@ const upgradeActions = [
282
167
  ctaKey: "upgrades.v041.cta",
283
168
  successKey: "upgrades.v041.success",
284
169
  loadingKey: "upgrades.v041.loading",
285
- async run({ container, em, tenantId, organizationId }) {
286
- const normalizedTenantId = tenantId.trim();
287
- const scope = { tenantId, organizationId };
288
- let seedPlannerAvailabilityRuleSetDefaults;
289
- let seedPlannerUnavailabilityReasons;
290
- try {
291
- const plannerSeeds = await import("@open-mercato/core/modules/planner/lib/seeds");
292
- seedPlannerAvailabilityRuleSetDefaults = plannerSeeds.seedPlannerAvailabilityRuleSetDefaults;
293
- seedPlannerUnavailabilityReasons = plannerSeeds.seedPlannerUnavailabilityReasons;
294
- } catch {
295
- console.warn("[upgrade-actions] planner module not available, skipping planner seeding");
170
+ async run(ctx) {
171
+ const plannerSeeds = await safeImport(
172
+ "planner examples",
173
+ () => import("@open-mercato/core/modules/planner/lib/seeds")
174
+ );
175
+ const staffSeeds = await safeImport(
176
+ "staff examples",
177
+ () => import("@open-mercato/core/modules/staff/lib/seeds")
178
+ );
179
+ const resourcesSeeds = await safeImport(
180
+ "resources examples",
181
+ () => import("@open-mercato/core/modules/resources/lib/seeds")
182
+ );
183
+ const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId };
184
+ if (plannerSeeds?.seedPlannerAvailabilityRuleSetDefaults) {
185
+ await plannerSeeds.seedPlannerAvailabilityRuleSetDefaults(ctx.em, scope);
296
186
  }
297
- let seedStaffTeamExamples;
298
- try {
299
- const staffSeeds = await import("@open-mercato/core/modules/staff/lib/seeds");
300
- seedStaffTeamExamples = staffSeeds.seedStaffTeamExamples;
301
- } catch {
302
- console.warn("[upgrade-actions] staff module not available, skipping staff seeding");
187
+ if (staffSeeds?.seedStaffTeamExamples) {
188
+ await staffSeeds.seedStaffTeamExamples(ctx.em, scope);
303
189
  }
304
- let seedResourcesAddressTypes;
305
- let seedResourcesCapacityUnits;
306
- let seedResourcesResourceExamples;
307
- try {
308
- const resourcesSeeds = await import("@open-mercato/core/modules/resources/lib/seeds");
309
- seedResourcesAddressTypes = resourcesSeeds.seedResourcesAddressTypes;
310
- seedResourcesCapacityUnits = resourcesSeeds.seedResourcesCapacityUnits;
311
- seedResourcesResourceExamples = resourcesSeeds.seedResourcesResourceExamples;
312
- } catch {
313
- console.warn("[upgrade-actions] resources module not available, skipping resources seeding");
190
+ if (resourcesSeeds?.seedResourcesResourceExamples) {
191
+ await resourcesSeeds.seedResourcesResourceExamples(ctx.em, scope);
314
192
  }
315
- await em.transactional(async (tem) => {
316
- if (seedPlannerAvailabilityRuleSetDefaults) await seedPlannerAvailabilityRuleSetDefaults(tem, scope);
317
- if (seedPlannerUnavailabilityReasons) await seedPlannerUnavailabilityReasons(tem, scope);
318
- if (seedStaffTeamExamples) await seedStaffTeamExamples(tem, scope);
319
- if (seedResourcesCapacityUnits) await seedResourcesCapacityUnits(tem, scope);
320
- if (seedResourcesAddressTypes) await seedResourcesAddressTypes(tem, scope);
321
- if (seedResourcesResourceExamples) await seedResourcesResourceExamples(tem, scope);
322
- const adminRole = await tem.findOne(Role, { name: "admin", tenantId: normalizedTenantId, deletedAt: null });
323
- if (!adminRole) return;
324
- const roleAcls = await tem.find(RoleAcl, { role: adminRole, tenantId: normalizedTenantId, deletedAt: null });
325
- const addedFeatures = [
326
- "staff.*",
327
- "staff.leave_requests.manage",
328
- "resources.*",
329
- "planner.*"
330
- ];
331
- let touched = false;
332
- if (!roleAcls.length) {
333
- tem.persist(
334
- tem.create(RoleAcl, {
335
- role: adminRole,
336
- tenantId: normalizedTenantId,
337
- featuresJson: addedFeatures,
338
- isSuperAdmin: false,
339
- createdAt: /* @__PURE__ */ new Date(),
340
- updatedAt: /* @__PURE__ */ new Date()
341
- })
342
- );
343
- touched = true;
344
- }
345
- for (const acl of roleAcls) {
346
- const features = Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : [];
347
- const nextFeatures = new Set(features);
348
- for (const feature of addedFeatures) nextFeatures.add(feature);
349
- if (nextFeatures.size === features.length) continue;
350
- acl.featuresJson = Array.from(nextFeatures);
351
- acl.updatedAt = /* @__PURE__ */ new Date();
352
- touched = true;
353
- }
354
- if (touched) {
355
- await tem.flush();
356
- }
357
- });
358
- const rbac = container.resolve("rbacService");
359
- await rbac.invalidateTenantCache(normalizedTenantId);
360
- const vectorService = resolveVectorService(container);
361
- await reindexModules(em, ["planner", "staff", "resources"], { tenantId, organizationId, vectorService });
193
+ await ensureRoleAclsForModules(ctx.em, ctx.tenantId, ["planner", "staff", "resources"]);
362
194
  }
363
195
  }
364
196
  ];
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/configs/lib/upgrade-actions.ts"],
4
- "sourcesContent": ["import { runWithCacheTenant } from '@open-mercato/cache'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { AwilixContainer } from 'awilix'\nimport { Role, RoleAcl } from '@open-mercato/core/modules/auth/data/entities'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\nimport { reindexModules } from '@open-mercato/core/modules/configs/lib/reindex-helpers'\n// Optional module imports are loaded dynamically inside each upgrade action\n// so the app does not crash when a module is disabled.\nimport { collectCrudCacheStats, purgeCrudCacheSegment } from '@open-mercato/shared/lib/crud/cache-stats'\nimport { isCrudCacheEnabled, resolveCrudCache } from '@open-mercato/shared/lib/crud/cache'\nimport * as semver from 'semver'\nimport type { VectorIndexService } from '@open-mercato/search/vector'\nimport { EncryptionMap } from '@open-mercato/core/modules/entities/data/entities'\nimport { DEFAULT_ENCRYPTION_MAPS } from '@open-mercato/core/modules/entities/lib/encryptionDefaults'\nimport type { TenantDataEncryptionService } from '@open-mercato/shared/lib/encryption/tenantDataEncryptionService'\n\nfunction resolveVectorService(container: AwilixContainer): VectorIndexService | null {\n try {\n return container.resolve<VectorIndexService>('vectorIndexService')\n } catch {\n return null\n }\n}\n\nfunction resolveEncryptionService(container: AwilixContainer): TenantDataEncryptionService | null {\n try {\n return container.resolve<TenantDataEncryptionService>('tenantEncryptionService')\n } catch {\n return null\n }\n}\n\nasync function ensureVectorSearchEncryptionMap(\n em: EntityManager,\n tenantId: string,\n organizationId: string | null,\n): Promise<boolean> {\n const spec = DEFAULT_ENCRYPTION_MAPS.find((entry) => entry.entityId === 'vector:vector_search')\n const required = spec?.fields ?? []\n if (!required.length) return false\n\n const repo = em.getRepository(EncryptionMap)\n const existing = await repo.findOne({\n entityId: 'vector:vector_search',\n tenantId,\n organizationId,\n deletedAt: null,\n })\n\n if (!existing) {\n em.persist(\n em.create(EncryptionMap, {\n entityId: 'vector:vector_search',\n tenantId,\n organizationId,\n fieldsJson: required,\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n }),\n )\n await em.flush()\n return true\n }\n\n const existingFields = Array.isArray(existing.fieldsJson) ? existing.fieldsJson : []\n const byField = new Map<string, { field: string; hashField?: string | null }>()\n for (const item of existingFields) {\n if (!item?.field) continue\n byField.set(item.field, item)\n }\n for (const req of required) {\n if (!req?.field) continue\n if (byField.has(req.field)) continue\n byField.set(req.field, req)\n }\n\n const merged = Array.from(byField.values())\n const changed = merged.length !== existingFields.length\n if (!changed && existing.isActive) return false\n\n existing.fieldsJson = merged\n existing.isActive = true\n existing.updatedAt = new Date()\n await em.flush()\n return true\n}\n\nexport type UpgradeActionContext = {\n tenantId: string\n organizationId: string\n container: AwilixContainer\n em: EntityManager\n}\n\nexport type UpgradeActionDefinition = {\n id: string\n version: string\n messageKey: string\n ctaKey: string\n successKey: string\n loadingKey?: string\n run: (ctx: UpgradeActionContext) => Promise<void>\n}\n\n/**\n * Compare two semantic version strings.\n * Uses the semver library for robust version comparison.\n * Returns negative if a < b, positive if a > b, 0 if equal.\n * Throws an error if either version string is invalid.\n */\nexport function compareVersions(a: string, b: string): number {\n const cleanA = semver.valid(semver.coerce(a))\n const cleanB = semver.valid(semver.coerce(b))\n if (!cleanA) {\n throw new Error(`Invalid version string: \"${a}\". Expected a valid semver format (e.g., \"1.2.3\").`)\n }\n if (!cleanB) {\n throw new Error(`Invalid version string: \"${b}\". Expected a valid semver format (e.g., \"1.2.3\").`)\n }\n return semver.compare(cleanA, cleanB)\n}\n\nasync function purgeCatalogCrudCache(container: AwilixContainer, tenantId: string | null) {\n if (!isCrudCacheEnabled()) return\n const cache = resolveCrudCache(container)\n if (!cache) return\n await runWithCacheTenant(tenantId ?? null, async () => {\n const stats = await collectCrudCacheStats(cache)\n const catalogSegments = stats.segments.filter((segment) => segment.resource?.startsWith('catalog.'))\n if (!catalogSegments.length) return\n for (const segment of catalogSegments) {\n try {\n await purgeCrudCacheSegment(cache, segment.segment)\n } catch (error) {\n console.warn('[upgrade-actions] failed to purge catalog cache segment', {\n tenantId,\n segment: segment.segment,\n error,\n })\n }\n }\n })\n}\n\nexport const upgradeActions: UpgradeActionDefinition[] = [\n {\n id: 'configs.upgrades.catalog.examples',\n version: '0.3.4',\n messageKey: 'upgrades.v034.message',\n ctaKey: 'upgrades.v034.cta',\n successKey: 'upgrades.v034.success',\n loadingKey: 'upgrades.v034.loading',\n async run({ container, em, tenantId, organizationId }) {\n let installExampleCatalogData: typeof import('@open-mercato/core/modules/catalog/lib/seeds')['installExampleCatalogData'] | undefined\n try {\n const catalogSeeds = await import('@open-mercato/core/modules/catalog/lib/seeds')\n installExampleCatalogData = catalogSeeds.installExampleCatalogData\n } catch {\n console.warn('[upgrade-actions] catalog module not available, skipping catalog example data')\n return\n }\n await installExampleCatalogData(container, { tenantId, organizationId }, em)\n const vectorService = resolveVectorService(container)\n await reindexModules(em, ['catalog'], { tenantId, organizationId, vectorService })\n },\n },\n {\n id: 'configs.upgrades.auth.admin_business_rules_acl',\n version: '0.3.5',\n messageKey: 'upgrades.v035.message',\n ctaKey: 'upgrades.v035.cta',\n successKey: 'upgrades.v035.success',\n loadingKey: 'upgrades.v035.loading',\n async run({ container, em, tenantId }) {\n const normalizedTenantId = tenantId.trim()\n await em.transactional(async (tem) => {\n const adminRole = await tem.findOne(Role, { name: 'admin', tenantId: normalizedTenantId, deletedAt: null })\n if (!adminRole) return\n\n const roleAcls = await tem.find(RoleAcl, { role: adminRole, tenantId: normalizedTenantId, deletedAt: null })\n let touched = false\n if (!roleAcls.length) {\n tem.persist(\n tem.create(RoleAcl, {\n role: adminRole,\n tenantId: normalizedTenantId,\n featuresJson: ['business_rules.*'],\n isSuperAdmin: false,\n createdAt: new Date(),\n updatedAt: new Date(),\n }),\n )\n touched = true\n }\n\n for (const acl of roleAcls) {\n const features = Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : []\n if (features.includes('business_rules.*')) continue\n acl.featuresJson = [...features, 'business_rules.*']\n acl.updatedAt = new Date()\n touched = true\n }\n\n if (touched) {\n await tem.flush()\n }\n })\n\n const rbac = container.resolve<RbacService>('rbacService')\n await rbac.invalidateTenantCache(normalizedTenantId)\n },\n },\n {\n id: 'configs.upgrades.sales.examples',\n version: '0.3.6',\n messageKey: 'upgrades.v036.message',\n ctaKey: 'upgrades.v036.cta',\n successKey: 'upgrades.v036.success',\n loadingKey: 'upgrades.v036.loading',\n async run({ container, em, tenantId, organizationId }) {\n let seedSalesExamples: typeof import('@open-mercato/core/modules/sales/seed/examples')['seedSalesExamples'] | undefined\n try {\n const salesSeeds = await import('@open-mercato/core/modules/sales/seed/examples')\n seedSalesExamples = salesSeeds.seedSalesExamples\n } catch {\n console.warn('[upgrade-actions] sales module not available, skipping sales example data')\n return\n }\n await em.transactional(async (tem) => {\n await seedSalesExamples!(tem, container, { tenantId, organizationId })\n })\n const vectorService = resolveVectorService(container)\n await reindexModules(em, ['sales', 'catalog'], { tenantId, organizationId, vectorService })\n await purgeCatalogCrudCache(container, tenantId)\n },\n },\n {\n id: 'configs.upgrades.vector.encryption_vector_search',\n version: '0.3.6',\n messageKey: 'upgrades.v036_vector_encryption.message',\n ctaKey: 'upgrades.v036_vector_encryption.cta',\n successKey: 'upgrades.v036_vector_encryption.success',\n loadingKey: 'upgrades.v036_vector_encryption.loading',\n async run({ container, em, tenantId, organizationId }) {\n const normalizedTenantId = tenantId.trim()\n const normalizedOrgId = organizationId ?? null\n\n const encryptionService = resolveEncryptionService(container)\n if (!encryptionService?.isEnabled?.()) {\n return\n }\n\n const updated = await em.transactional(async (tem) => {\n return ensureVectorSearchEncryptionMap(tem, normalizedTenantId, normalizedOrgId)\n })\n\n if (updated) {\n await encryptionService.invalidateMap('vector:vector_search', normalizedTenantId, normalizedOrgId)\n }\n\n const vectorService = resolveVectorService(container)\n if (vectorService) {\n await vectorService.reindexAll({ tenantId: normalizedTenantId, organizationId: normalizedOrgId, purgeFirst: false })\n }\n },\n },\n {\n id: 'configs.upgrades.examples.currencies_workflows',\n version: '0.3.13',\n messageKey: 'upgrades.v0313.message',\n ctaKey: 'upgrades.v0313.cta',\n successKey: 'upgrades.v0313.success',\n loadingKey: 'upgrades.v0313.loading',\n async run({ container, em, tenantId, organizationId }) {\n const normalizedTenantId = tenantId.trim()\n const scope = { tenantId, organizationId }\n\n let seedExampleCurrencies: typeof import('@open-mercato/core/modules/currencies/lib/seeds')['seedExampleCurrencies'] | undefined\n try {\n const currenciesSeeds = await import('@open-mercato/core/modules/currencies/lib/seeds')\n seedExampleCurrencies = currenciesSeeds.seedExampleCurrencies\n } catch {\n console.warn('[upgrade-actions] currencies module not available, skipping currency seeding')\n }\n\n let seedExampleWorkflows: typeof import('@open-mercato/core/modules/workflows/lib/seeds')['seedExampleWorkflows'] | undefined\n try {\n const workflowsSeeds = await import('@open-mercato/core/modules/workflows/lib/seeds')\n seedExampleWorkflows = workflowsSeeds.seedExampleWorkflows\n } catch {\n console.warn('[upgrade-actions] workflows module not available, skipping workflow seeding')\n }\n\n await em.transactional(async (tem) => {\n if (seedExampleCurrencies) await seedExampleCurrencies(tem, scope)\n if (seedExampleWorkflows) await seedExampleWorkflows(tem, scope)\n\n const adminRole = await tem.findOne(Role, { name: 'admin', tenantId: normalizedTenantId, deletedAt: null })\n if (!adminRole) return\n\n const roleAcls = await tem.find(RoleAcl, { role: adminRole, tenantId: normalizedTenantId, deletedAt: null })\n let touched = false\n if (!roleAcls.length) {\n tem.persist(\n tem.create(RoleAcl, {\n role: adminRole,\n tenantId: normalizedTenantId,\n featuresJson: ['search.*', 'feature_toggles.*', 'currencies.*'],\n isSuperAdmin: false,\n createdAt: new Date(),\n updatedAt: new Date(),\n }),\n )\n touched = true\n }\n\n for (const acl of roleAcls) {\n const features = Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : []\n const nextFeatures = new Set(features)\n nextFeatures.add('search.*')\n nextFeatures.add('feature_toggles.*')\n nextFeatures.add('currencies.*')\n if (nextFeatures.size === features.length) continue\n acl.featuresJson = Array.from(nextFeatures)\n acl.updatedAt = new Date()\n touched = true\n }\n\n if (touched) {\n await tem.flush()\n }\n })\n const rbac = container.resolve<RbacService>('rbacService')\n await rbac.invalidateTenantCache(normalizedTenantId)\n },\n },\n {\n id: 'configs.upgrades.examples.planner_staff_resources',\n version: '0.4.1',\n messageKey: 'upgrades.v041.message',\n ctaKey: 'upgrades.v041.cta',\n successKey: 'upgrades.v041.success',\n loadingKey: 'upgrades.v041.loading',\n async run({ container, em, tenantId, organizationId }) {\n const normalizedTenantId = tenantId.trim()\n const scope = { tenantId, organizationId }\n\n let seedPlannerAvailabilityRuleSetDefaults: typeof import('@open-mercato/core/modules/planner/lib/seeds')['seedPlannerAvailabilityRuleSetDefaults'] | undefined\n let seedPlannerUnavailabilityReasons: typeof import('@open-mercato/core/modules/planner/lib/seeds')['seedPlannerUnavailabilityReasons'] | undefined\n try {\n const plannerSeeds = await import('@open-mercato/core/modules/planner/lib/seeds')\n seedPlannerAvailabilityRuleSetDefaults = plannerSeeds.seedPlannerAvailabilityRuleSetDefaults\n seedPlannerUnavailabilityReasons = plannerSeeds.seedPlannerUnavailabilityReasons\n } catch {\n console.warn('[upgrade-actions] planner module not available, skipping planner seeding')\n }\n\n let seedStaffTeamExamples: typeof import('@open-mercato/core/modules/staff/lib/seeds')['seedStaffTeamExamples'] | undefined\n try {\n const staffSeeds = await import('@open-mercato/core/modules/staff/lib/seeds')\n seedStaffTeamExamples = staffSeeds.seedStaffTeamExamples\n } catch {\n console.warn('[upgrade-actions] staff module not available, skipping staff seeding')\n }\n\n let seedResourcesAddressTypes: typeof import('@open-mercato/core/modules/resources/lib/seeds')['seedResourcesAddressTypes'] | undefined\n let seedResourcesCapacityUnits: typeof import('@open-mercato/core/modules/resources/lib/seeds')['seedResourcesCapacityUnits'] | undefined\n let seedResourcesResourceExamples: typeof import('@open-mercato/core/modules/resources/lib/seeds')['seedResourcesResourceExamples'] | undefined\n try {\n const resourcesSeeds = await import('@open-mercato/core/modules/resources/lib/seeds')\n seedResourcesAddressTypes = resourcesSeeds.seedResourcesAddressTypes\n seedResourcesCapacityUnits = resourcesSeeds.seedResourcesCapacityUnits\n seedResourcesResourceExamples = resourcesSeeds.seedResourcesResourceExamples\n } catch {\n console.warn('[upgrade-actions] resources module not available, skipping resources seeding')\n }\n\n await em.transactional(async (tem) => {\n if (seedPlannerAvailabilityRuleSetDefaults) await seedPlannerAvailabilityRuleSetDefaults(tem, scope)\n if (seedPlannerUnavailabilityReasons) await seedPlannerUnavailabilityReasons(tem, scope)\n if (seedStaffTeamExamples) await seedStaffTeamExamples(tem, scope)\n if (seedResourcesCapacityUnits) await seedResourcesCapacityUnits(tem, scope)\n if (seedResourcesAddressTypes) await seedResourcesAddressTypes(tem, scope)\n if (seedResourcesResourceExamples) await seedResourcesResourceExamples(tem, scope)\n\n const adminRole = await tem.findOne(Role, { name: 'admin', tenantId: normalizedTenantId, deletedAt: null })\n if (!adminRole) return\n\n const roleAcls = await tem.find(RoleAcl, { role: adminRole, tenantId: normalizedTenantId, deletedAt: null })\n const addedFeatures = [\n 'staff.*',\n 'staff.leave_requests.manage',\n 'resources.*',\n 'planner.*',\n ]\n let touched = false\n if (!roleAcls.length) {\n tem.persist(\n tem.create(RoleAcl, {\n role: adminRole,\n tenantId: normalizedTenantId,\n featuresJson: addedFeatures,\n isSuperAdmin: false,\n createdAt: new Date(),\n updatedAt: new Date(),\n }),\n )\n touched = true\n }\n\n for (const acl of roleAcls) {\n const features = Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : []\n const nextFeatures = new Set(features)\n for (const feature of addedFeatures) nextFeatures.add(feature)\n if (nextFeatures.size === features.length) continue\n acl.featuresJson = Array.from(nextFeatures)\n acl.updatedAt = new Date()\n touched = true\n }\n\n if (touched) {\n await tem.flush()\n }\n })\n\n const rbac = container.resolve<RbacService>('rbacService')\n await rbac.invalidateTenantCache(normalizedTenantId)\n\n const vectorService = resolveVectorService(container)\n await reindexModules(em, ['planner', 'staff', 'resources'], { tenantId, organizationId, vectorService })\n },\n },\n]\n\nexport function actionsUpToVersion(version: string): UpgradeActionDefinition[] {\n return upgradeActions\n .filter((action) => compareVersions(action.version, version) <= 0)\n .sort((a, b) => compareVersions(a.version, b.version) || a.id.localeCompare(b.id))\n}\n\nexport function findUpgradeAction(actionId: string, maxVersion: string): UpgradeActionDefinition | undefined {\n const matches = actionsUpToVersion(maxVersion).filter((action) => action.id === actionId)\n if (!matches.length) return undefined\n return matches[matches.length - 1]\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport * as semver from 'semver'\nimport { getModules } from '@open-mercato/shared/lib/modules/registry'\nimport type { Module } from '@open-mercato/shared/modules/registry'\nimport type { AppContainer } from '@open-mercato/shared/lib/di/container'\nimport { Role, RoleAcl } from '@open-mercato/core/modules/auth/data/entities'\nimport { normalizeTenantId } from '@open-mercato/core/modules/auth/lib/tenantAccess'\n\nexport type UpgradeActionContext = {\n tenantId: string\n organizationId: string\n container: AppContainer\n em: EntityManager\n}\n\nexport type UpgradeActionDefinition = {\n id: string\n version: string\n messageKey: string\n ctaKey: string\n successKey: string\n loadingKey?: string\n run: (ctx: UpgradeActionContext) => Promise<void>\n}\n\n/**\n * Compare two semantic version strings.\n * Uses the semver library for robust version comparison.\n * Returns negative if a < b, positive if a > b, 0 if equal.\n * Throws an error if either version string is invalid.\n */\nexport function compareVersions(a: string, b: string): number {\n const cleanA = semver.valid(semver.coerce(a))\n const cleanB = semver.valid(semver.coerce(b))\n if (!cleanA) {\n throw new Error(`Invalid version string: \"${a}\". Expected a valid semver format (e.g., \"1.2.3\").`)\n }\n if (!cleanB) {\n throw new Error(`Invalid version string: \"${b}\". Expected a valid semver format (e.g., \"1.2.3\").`)\n }\n return semver.compare(cleanA, cleanB)\n}\n\ntype RoleName = 'superadmin' | 'admin' | 'employee'\n\nfunction collectRoleFeatures(modules: Module[], moduleIds: string[]): Record<RoleName, string[]> {\n const result: Record<RoleName, string[]> = {\n superadmin: [],\n admin: [],\n employee: [],\n }\n const targetIds = new Set(moduleIds)\n for (const mod of modules) {\n if (!targetIds.has(mod.id)) continue\n const roleFeatures = mod.setup?.defaultRoleFeatures\n if (roleFeatures?.superadmin) result.superadmin.push(...roleFeatures.superadmin)\n if (roleFeatures?.admin) result.admin.push(...roleFeatures.admin)\n if (roleFeatures?.employee) result.employee.push(...roleFeatures.employee)\n }\n result.superadmin = Array.from(new Set(result.superadmin))\n result.admin = Array.from(new Set(result.admin))\n result.employee = Array.from(new Set(result.employee))\n return result\n}\n\nasync function findRoleByName(\n em: EntityManager,\n name: string,\n tenantId: string | null,\n): Promise<Role | null> {\n const normalizedTenant = normalizeTenantId(tenantId ?? null) ?? null\n let role = await em.findOne(Role, { name, tenantId: normalizedTenant })\n if (!role && normalizedTenant !== null) {\n role = await em.findOne(Role, { name, tenantId: null })\n }\n return role\n}\n\nasync function ensureRoleAclFor(\n em: EntityManager,\n role: Role,\n tenantId: string,\n features: string[],\n options: { isSuperAdmin?: boolean } = {},\n) {\n const existing = await em.findOne(RoleAcl, { role, tenantId })\n if (!existing) {\n const acl = em.create(RoleAcl, {\n role,\n tenantId,\n featuresJson: features,\n isSuperAdmin: !!options.isSuperAdmin,\n createdAt: new Date(),\n })\n await em.persistAndFlush(acl)\n return\n }\n const currentFeatures = Array.isArray(existing.featuresJson) ? existing.featuresJson : []\n const merged = Array.from(new Set([...currentFeatures, ...features]))\n const changed =\n merged.length !== currentFeatures.length ||\n merged.some((value, index) => value !== currentFeatures[index])\n if (changed) existing.featuresJson = merged\n if (options.isSuperAdmin && !existing.isSuperAdmin) {\n existing.isSuperAdmin = true\n }\n if (changed || options.isSuperAdmin) {\n await em.persistAndFlush(existing)\n }\n}\n\nasync function ensureRoleAclsForModules(\n em: EntityManager,\n tenantId: string,\n moduleIds: string[],\n) {\n const modules = getModules()\n const roleFeatures = collectRoleFeatures(modules, moduleIds)\n if (!roleFeatures.superadmin.length && !roleFeatures.admin.length && !roleFeatures.employee.length) {\n return\n }\n const normalizedTenant = normalizeTenantId(tenantId) ?? null\n const [superadminRole, adminRole, employeeRole] = await Promise.all([\n findRoleByName(em, 'superadmin', normalizedTenant),\n findRoleByName(em, 'admin', normalizedTenant),\n findRoleByName(em, 'employee', normalizedTenant),\n ])\n if (superadminRole && roleFeatures.superadmin.length) {\n await ensureRoleAclFor(em, superadminRole, tenantId, roleFeatures.superadmin, { isSuperAdmin: true })\n }\n if (adminRole && roleFeatures.admin.length) {\n await ensureRoleAclFor(em, adminRole, tenantId, roleFeatures.admin)\n }\n if (employeeRole && roleFeatures.employee.length) {\n await ensureRoleAclFor(em, employeeRole, tenantId, roleFeatures.employee)\n }\n}\n\nasync function safeImport<T>(label: string, loader: () => Promise<T>): Promise<T | null> {\n try {\n return await loader()\n } catch (error) {\n console.warn(`[upgrade-actions] Skipping ${label} because module import failed.`, error)\n return null\n }\n}\n\nexport const upgradeActions: UpgradeActionDefinition[] = [\n {\n id: 'configs.upgrades.catalog.examples',\n version: '0.3.4',\n messageKey: 'upgrades.v034.message',\n ctaKey: 'upgrades.v034.cta',\n successKey: 'upgrades.v034.success',\n loadingKey: 'upgrades.v034.loading',\n async run(ctx) {\n const catalogSeeds = await safeImport('catalog examples', () =>\n import('@open-mercato/core/modules/catalog/lib/seeds')\n )\n if (!catalogSeeds?.installExampleCatalogData) return\n await catalogSeeds.installExampleCatalogData(\n ctx.container,\n { tenantId: ctx.tenantId, organizationId: ctx.organizationId },\n ctx.em,\n )\n },\n },\n {\n id: 'configs.upgrades.sales.examples',\n version: '0.3.6',\n messageKey: 'upgrades.v036.message',\n ctaKey: 'upgrades.v036.cta',\n successKey: 'upgrades.v036.success',\n loadingKey: 'upgrades.v036.loading',\n async run(ctx) {\n const salesSeeds = await safeImport('sales examples', () =>\n import('@open-mercato/core/modules/sales/seed/examples')\n )\n if (!salesSeeds?.seedSalesExamples) return\n await salesSeeds.seedSalesExamples(ctx.em, ctx.container, {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId,\n })\n },\n },\n {\n id: 'configs.upgrades.examples.currencies_workflows',\n version: '0.3.13',\n messageKey: 'upgrades.v0313.message',\n ctaKey: 'upgrades.v0313.cta',\n successKey: 'upgrades.v0313.success',\n loadingKey: 'upgrades.v0313.loading',\n async run(ctx) {\n const currenciesSeeds = await safeImport('currencies examples', () =>\n import('@open-mercato/core/modules/currencies/lib/seeds')\n )\n const workflowsSeeds = await safeImport('workflows examples', () =>\n import('@open-mercato/core/modules/workflows/lib/seeds')\n )\n const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId }\n if (currenciesSeeds?.seedExampleCurrencies) {\n await currenciesSeeds.seedExampleCurrencies(ctx.em, scope)\n }\n if (workflowsSeeds?.seedExampleWorkflows) {\n await workflowsSeeds.seedExampleWorkflows(ctx.em, scope)\n }\n await ensureRoleAclsForModules(ctx.em, ctx.tenantId, ['currencies', 'workflows'])\n },\n },\n {\n id: 'configs.upgrades.examples.planner_staff_resources',\n version: '0.4.1',\n messageKey: 'upgrades.v041.message',\n ctaKey: 'upgrades.v041.cta',\n successKey: 'upgrades.v041.success',\n loadingKey: 'upgrades.v041.loading',\n async run(ctx) {\n const plannerSeeds = await safeImport('planner examples', () =>\n import('@open-mercato/core/modules/planner/lib/seeds')\n )\n const staffSeeds = await safeImport('staff examples', () =>\n import('@open-mercato/core/modules/staff/lib/seeds')\n )\n const resourcesSeeds = await safeImport('resources examples', () =>\n import('@open-mercato/core/modules/resources/lib/seeds')\n )\n const scope = { tenantId: ctx.tenantId, organizationId: ctx.organizationId }\n if (plannerSeeds?.seedPlannerAvailabilityRuleSetDefaults) {\n await plannerSeeds.seedPlannerAvailabilityRuleSetDefaults(ctx.em, scope)\n }\n if (staffSeeds?.seedStaffTeamExamples) {\n await staffSeeds.seedStaffTeamExamples(ctx.em, scope)\n }\n if (resourcesSeeds?.seedResourcesResourceExamples) {\n await resourcesSeeds.seedResourcesResourceExamples(ctx.em, scope)\n }\n await ensureRoleAclsForModules(ctx.em, ctx.tenantId, ['planner', 'staff', 'resources'])\n },\n },\n]\n\nexport function actionsUpToVersion(version: string): UpgradeActionDefinition[] {\n return upgradeActions\n .filter((action) => compareVersions(action.version, version) <= 0)\n .sort((a, b) => compareVersions(a.version, b.version) || a.id.localeCompare(b.id))\n}\n\nexport function findUpgradeAction(actionId: string, maxVersion: string): UpgradeActionDefinition | undefined {\n const matches = actionsUpToVersion(maxVersion).filter((action) => action.id === actionId)\n if (!matches.length) return undefined\n return matches[matches.length - 1]\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }