@open-mercato/core 0.4.2-canary-f075c3eb92 → 0.4.2-canary-e2aeb1a7bf

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 (506) 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 +41 -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 +1 -352
  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 +57 -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 +2 -396
  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 +4 -0
  495. package/src/modules/staff/i18n/en.json +9 -1
  496. package/src/modules/staff/i18n/es.json +4 -0
  497. package/src/modules/staff/i18n/pl.json +4 -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/transition-handler.ts +18 -6
  505. package/src/modules/workflows/notifications.ts +25 -0
  506. package/src/modules/workflows/subscribers/task-assigned-notification.ts +53 -0
@@ -1,90 +1,6 @@
1
- import { runWithCacheTenant } from '@open-mercato/cache'
2
- import type { EntityManager } from '@mikro-orm/postgresql'
3
1
  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'
2
+ import type { EntityManager } from '@mikro-orm/postgresql'
11
3
  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
- }
88
4
 
89
5
  export type UpgradeActionContext = {
90
6
  tenantId: string
@@ -121,317 +37,7 @@ export function compareVersions(a: string, b: string): number {
121
37
  return semver.compare(cleanA, cleanB)
122
38
  }
123
39
 
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
- })
144
- }
145
-
146
- export const upgradeActions: UpgradeActionDefinition[] = [
147
- {
148
- id: 'configs.upgrades.catalog.examples',
149
- version: '0.3.4',
150
- messageKey: 'upgrades.v034.message',
151
- ctaKey: 'upgrades.v034.cta',
152
- successKey: 'upgrades.v034.success',
153
- 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)
212
- },
213
- },
214
- {
215
- id: 'configs.upgrades.sales.examples',
216
- version: '0.3.6',
217
- messageKey: 'upgrades.v036.message',
218
- ctaKey: 'upgrades.v036.cta',
219
- successKey: 'upgrades.v036.success',
220
- 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 })
232
- })
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
- },
267
- },
268
- {
269
- id: 'configs.upgrades.examples.currencies_workflows',
270
- version: '0.3.13',
271
- messageKey: 'upgrades.v0313.message',
272
- ctaKey: 'upgrades.v0313.cta',
273
- successKey: 'upgrades.v0313.success',
274
- 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')
285
- }
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')
293
- }
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)
336
- },
337
- },
338
- {
339
- id: 'configs.upgrades.examples.planner_staff_resources',
340
- version: '0.4.1',
341
- messageKey: 'upgrades.v041.message',
342
- ctaKey: 'upgrades.v041.cta',
343
- successKey: 'upgrades.v041.success',
344
- 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')
357
- }
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')
365
- }
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')
377
- }
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 })
432
- },
433
- },
434
- ]
40
+ export const upgradeActions: UpgradeActionDefinition[] = []
435
41
 
436
42
  export function actionsUpToVersion(version: string): UpgradeActionDefinition[] {
437
43
  return upgradeActions
@@ -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),
@@ -35,6 +35,9 @@ import { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'
35
35
  import type { CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'
36
36
  import { E } from '#generated/entities.ids.generated'
37
37
  import { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
38
+ import { resolveNotificationService } from '../../notifications/lib/notificationService'
39
+ import { buildNotificationFromType } from '../../notifications/lib/notificationBuilder'
40
+ import { notificationTypes } from '../notifications'
38
41
 
39
42
  const DEAL_ENTITY_ID = 'customers:customer_deal'
40
43
  const dealCrudIndexer: CrudIndexerConfig<CustomerDeal> = {
@@ -281,6 +284,8 @@ const updateDealCommand: CommandHandler<DealUpdateInput, { dealId: string }> = {
281
284
  ensureTenantScope(ctx, record.tenantId)
282
285
  ensureOrganizationScope(ctx, record.organizationId)
283
286
 
287
+ const previousStatus = record.status
288
+
284
289
  if (parsed.title !== undefined) record.title = parsed.title
285
290
  if (parsed.description !== undefined) record.description = parsed.description ?? null
286
291
  if (parsed.status !== undefined) record.status = parsed.status ?? record.status
@@ -319,6 +324,40 @@ const updateDealCommand: CommandHandler<DealUpdateInput, { dealId: string }> = {
319
324
  indexer: dealCrudIndexer,
320
325
  })
321
326
 
327
+ // Send notifications for deal won/lost status changes
328
+ const newStatus = record.status
329
+ const normalizedStatus = newStatus === 'win' ? 'won' : newStatus === 'loose' ? 'lost' : newStatus
330
+ if (previousStatus !== newStatus && (normalizedStatus === 'won' || normalizedStatus === 'lost') && record.ownerUserId) {
331
+ try {
332
+ const notificationService = resolveNotificationService(ctx.container)
333
+ const notificationType = normalizedStatus === 'won' ? 'customers.deal.won' : 'customers.deal.lost'
334
+ const typeDef = notificationTypes.find((type) => type.type === notificationType)
335
+ if (typeDef) {
336
+ const valueDisplay = record.valueAmount && record.valueCurrency
337
+ ? `${record.valueCurrency} ${record.valueAmount}`
338
+ : ''
339
+
340
+ const notificationInput = buildNotificationFromType(typeDef, {
341
+ recipientUserId: record.ownerUserId,
342
+ bodyVariables: {
343
+ dealTitle: record.title,
344
+ dealValue: valueDisplay,
345
+ },
346
+ sourceEntityType: 'customers:customer_deal',
347
+ sourceEntityId: record.id,
348
+ linkHref: `/backend/customers/deals/${record.id}`,
349
+ })
350
+
351
+ await notificationService.create(notificationInput, {
352
+ tenantId: record.tenantId,
353
+ organizationId: record.organizationId,
354
+ })
355
+ }
356
+ } catch {
357
+ // Notification creation is non-critical, don't fail the command
358
+ }
359
+ }
360
+
322
361
  return { dealId: record.id }
323
362
  },
324
363
  buildLog: async ({ snapshots, ctx }) => {
@@ -253,6 +253,7 @@ export function CustomerTodosTable(): React.JSX.Element {
253
253
  <RowActions
254
254
  items={[
255
255
  {
256
+ id: 'open-customer',
256
257
  label: t('customers.workPlan.customerTodos.table.actions.openCustomer'),
257
258
  href: customerLink,
258
259
  },
@@ -943,5 +943,9 @@
943
943
  "customers.workPlan.customerTodos.table.state.empty": "No customer tasks yet.",
944
944
  "customers.workPlan.customerTodos.table.error.load": "Failed to load customer tasks.",
945
945
  "customers.workPlan.customerTodos.table.export.view": "Exports the current list with filters and visible columns.",
946
- "customers.workPlan.customerTodos.table.export.full": "Exports every linked task field, including hidden attributes."
946
+ "customers.workPlan.customerTodos.table.export.full": "Exports every linked task field, including hidden attributes.",
947
+ "customers.notifications.deal.won.title": "Deal Won",
948
+ "customers.notifications.deal.won.body": "{dealTitle} has been marked as won{dealValue, select, other { ({dealValue})}}",
949
+ "customers.notifications.deal.lost.title": "Deal Lost",
950
+ "customers.notifications.deal.lost.body": "{dealTitle} has been marked as lost"
947
951
  }
@@ -0,0 +1,44 @@
1
+ import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
2
+
3
+ export const notificationTypes: NotificationTypeDefinition[] = [
4
+ {
5
+ type: 'customers.deal.won',
6
+ module: 'customers',
7
+ titleKey: 'customers.notifications.deal.won.title',
8
+ bodyKey: 'customers.notifications.deal.won.body',
9
+ icon: 'trophy',
10
+ severity: 'success',
11
+ actions: [
12
+ {
13
+ id: 'view',
14
+ labelKey: 'common.view',
15
+ variant: 'outline',
16
+ href: '/backend/customers/deals/{sourceEntityId}',
17
+ icon: 'external-link',
18
+ },
19
+ ],
20
+ linkHref: '/backend/customers/deals/{sourceEntityId}',
21
+ expiresAfterHours: 168, // 7 days
22
+ },
23
+ {
24
+ type: 'customers.deal.lost',
25
+ module: 'customers',
26
+ titleKey: 'customers.notifications.deal.lost.title',
27
+ bodyKey: 'customers.notifications.deal.lost.body',
28
+ icon: 'x-circle',
29
+ severity: 'warning',
30
+ actions: [
31
+ {
32
+ id: 'view',
33
+ labelKey: 'common.view',
34
+ variant: 'outline',
35
+ href: '/backend/customers/deals/{sourceEntityId}',
36
+ icon: 'external-link',
37
+ },
38
+ ],
39
+ linkHref: '/backend/customers/deals/{sourceEntityId}',
40
+ expiresAfterHours: 168, // 7 days
41
+ },
42
+ ]
43
+
44
+ export default notificationTypes
@@ -1,6 +1,6 @@
1
- import type { DashboardWidgetModule } from '@open-mercato/shared/modules/dashboard/widgets'
2
- import CustomerTodosWidget from './widget.client'
1
+ import { lazyDashboardWidget, type DashboardWidgetModule } from '@open-mercato/shared/modules/dashboard/widgets'
3
2
  import { DEFAULT_SETTINGS, hydrateCustomerTodoSettings, type CustomerTodoWidgetSettings } from './config'
3
+ const CustomerTodosWidget = lazyDashboardWidget(() => import('./widget.client'))
4
4
 
5
5
  const widget: DashboardWidgetModule<CustomerTodoWidgetSettings> = {
6
6
  metadata: {
@@ -1,6 +1,6 @@
1
- import type { DashboardWidgetModule } from '@open-mercato/shared/modules/dashboard/widgets'
2
- import CustomerNewCustomersWidget from './widget.client'
1
+ import { lazyDashboardWidget, type DashboardWidgetModule } from '@open-mercato/shared/modules/dashboard/widgets'
3
2
  import { DEFAULT_SETTINGS, hydrateNewCustomersSettings, type CustomerNewCustomersSettings } from './config'
3
+ const CustomerNewCustomersWidget = lazyDashboardWidget(() => import('./widget.client'))
4
4
 
5
5
  const widget: DashboardWidgetModule<CustomerNewCustomersSettings> = {
6
6
  metadata: {
@@ -1,6 +1,6 @@
1
- import type { DashboardWidgetModule } from '@open-mercato/shared/modules/dashboard/widgets'
2
- import CustomerNewDealsWidget from './widget.client'
1
+ import { lazyDashboardWidget, type DashboardWidgetModule } from '@open-mercato/shared/modules/dashboard/widgets'
3
2
  import { DEFAULT_SETTINGS, hydrateNewDealsSettings, type CustomerNewDealsSettings } from './config'
3
+ const CustomerNewDealsWidget = lazyDashboardWidget(() => import('./widget.client'))
4
4
 
5
5
  const widget: DashboardWidgetModule<CustomerNewDealsSettings> = {
6
6
  metadata: {