@open-mercato/core 0.6.8-develop.6983.1.e4f794099e → 0.6.8-develop.6985.1.fb93574faa

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 (597) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/notification/index.js +6 -0
  3. package/dist/generated/entities/notification/index.js.map +2 -2
  4. package/dist/generated/entities/notification_preference/index.js +19 -0
  5. package/dist/generated/entities/notification_preference/index.js.map +7 -0
  6. package/dist/generated/entities/notification_type/index.js +21 -0
  7. package/dist/generated/entities/notification_type/index.js.map +7 -0
  8. package/dist/generated/entities/notification_type_override/index.js +17 -0
  9. package/dist/generated/entities/notification_type_override/index.js.map +7 -0
  10. package/dist/generated/entities/push_notification_delivery/index.js +41 -0
  11. package/dist/generated/entities/push_notification_delivery/index.js.map +7 -0
  12. package/dist/generated/entities/user_device/index.js +35 -0
  13. package/dist/generated/entities/user_device/index.js.map +7 -0
  14. package/dist/generated/entities.ids.generated.js +12 -1
  15. package/dist/generated/entities.ids.generated.js.map +2 -2
  16. package/dist/generated/entity-fields-registry.js +72 -0
  17. package/dist/generated/entity-fields-registry.js.map +2 -2
  18. package/dist/helpers/integration/api.js +2 -1
  19. package/dist/helpers/integration/api.js.map +2 -2
  20. package/dist/helpers/integration/appRoot.js +9 -0
  21. package/dist/helpers/integration/appRoot.js.map +7 -0
  22. package/dist/helpers/integration/dbFixtures.js +1 -4
  23. package/dist/helpers/integration/dbFixtures.js.map +2 -2
  24. package/dist/helpers/integration/pushFake.js +126 -0
  25. package/dist/helpers/integration/pushFake.js.map +7 -0
  26. package/dist/modules/auth/notifications.js +16 -0
  27. package/dist/modules/auth/notifications.js.map +2 -2
  28. package/dist/modules/business_rules/notifications.js +2 -0
  29. package/dist/modules/business_rules/notifications.js.map +2 -2
  30. package/dist/modules/catalog/notifications.js +2 -0
  31. package/dist/modules/catalog/notifications.js.map +2 -2
  32. package/dist/modules/communication_channels/acl.js +9 -0
  33. package/dist/modules/communication_channels/acl.js.map +2 -2
  34. package/dist/modules/communication_channels/api/delete/admin/channels/[id]/route.js +133 -0
  35. package/dist/modules/communication_channels/api/delete/admin/channels/[id]/route.js.map +7 -0
  36. package/dist/modules/communication_channels/api/get/channels/[id]/health/route.js +6 -2
  37. package/dist/modules/communication_channels/api/get/channels/[id]/health/route.js.map +2 -2
  38. package/dist/modules/communication_channels/api/get/channels/[id]/route.js +6 -2
  39. package/dist/modules/communication_channels/api/get/channels/[id]/route.js.map +2 -2
  40. package/dist/modules/communication_channels/api/get/channels/route.js +2 -1
  41. package/dist/modules/communication_channels/api/get/channels/route.js.map +2 -2
  42. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +10 -5
  43. package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +2 -2
  44. package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js +29 -1
  45. package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js.map +2 -2
  46. package/dist/modules/communication_channels/api/post/channels/connect/tenant-credentials/route.js +157 -0
  47. package/dist/modules/communication_channels/api/post/channels/connect/tenant-credentials/route.js.map +7 -0
  48. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +8 -1
  49. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
  50. package/dist/modules/communication_channels/commands/admin-delete-channel.js +141 -0
  51. package/dist/modules/communication_channels/commands/admin-delete-channel.js.map +7 -0
  52. package/dist/modules/communication_channels/commands/connect-credential-channel.js +25 -8
  53. package/dist/modules/communication_channels/commands/connect-credential-channel.js.map +2 -2
  54. package/dist/modules/communication_channels/commands/deliver-outbound-message.js +2 -2
  55. package/dist/modules/communication_channels/commands/deliver-outbound-message.js.map +2 -2
  56. package/dist/modules/communication_channels/commands/push-register.js +1 -1
  57. package/dist/modules/communication_channels/commands/push-register.js.map +2 -2
  58. package/dist/modules/communication_channels/commands/push-unregister.js +4 -3
  59. package/dist/modules/communication_channels/commands/push-unregister.js.map +2 -2
  60. package/dist/modules/communication_channels/data/entities.js +4 -0
  61. package/dist/modules/communication_channels/data/entities.js.map +2 -2
  62. package/dist/modules/communication_channels/data/validators.js +2 -1
  63. package/dist/modules/communication_channels/data/validators.js.map +2 -2
  64. package/dist/modules/communication_channels/lib/access-control.js +11 -1
  65. package/dist/modules/communication_channels/lib/access-control.js.map +2 -2
  66. package/dist/modules/communication_channels/lib/connect-channel.js +20 -12
  67. package/dist/modules/communication_channels/lib/connect-channel.js.map +2 -2
  68. package/dist/modules/communication_channels/lib/push-adapter.js +68 -0
  69. package/dist/modules/communication_channels/lib/push-adapter.js.map +7 -0
  70. package/dist/modules/communication_channels/lib/push-capabilities.js +31 -0
  71. package/dist/modules/communication_channels/lib/push-capabilities.js.map +7 -0
  72. package/dist/modules/communication_channels/lib/push-connect-error.js +20 -0
  73. package/dist/modules/communication_channels/lib/push-connect-error.js.map +7 -0
  74. package/dist/modules/communication_channels/lib/push-credential-errors.js +41 -0
  75. package/dist/modules/communication_channels/lib/push-credential-errors.js.map +7 -0
  76. package/dist/modules/communication_channels/lib/push-envelope.js +46 -0
  77. package/dist/modules/communication_channels/lib/push-envelope.js.map +7 -0
  78. package/dist/modules/communication_channels/lib/refcounted-client-cache.js +64 -0
  79. package/dist/modules/communication_channels/lib/refcounted-client-cache.js.map +7 -0
  80. package/dist/modules/communication_channels/migrations/Migration20260703123630_communication_channels.js +13 -0
  81. package/dist/modules/communication_channels/migrations/Migration20260703123630_communication_channels.js.map +7 -0
  82. package/dist/modules/communication_channels/notifications.js +4 -0
  83. package/dist/modules/communication_channels/notifications.js.map +2 -2
  84. package/dist/modules/communication_channels/setup.js +2 -0
  85. package/dist/modules/communication_channels/setup.js.map +2 -2
  86. package/dist/modules/configs/lib/upgrade-actions.js +21 -0
  87. package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
  88. package/dist/modules/customer_accounts/notifications.js +12 -0
  89. package/dist/modules/customer_accounts/notifications.js.map +2 -2
  90. package/dist/modules/customers/notifications.js +4 -0
  91. package/dist/modules/customers/notifications.js.map +2 -2
  92. package/dist/modules/devices/acl.js +11 -0
  93. package/dist/modules/devices/acl.js.map +7 -0
  94. package/dist/modules/devices/api/[id]/route.js +167 -0
  95. package/dist/modules/devices/api/[id]/route.js.map +7 -0
  96. package/dist/modules/devices/api/admin/devices/[id]/route.js +219 -0
  97. package/dist/modules/devices/api/admin/devices/[id]/route.js.map +7 -0
  98. package/dist/modules/devices/api/admin/devices/route.js +140 -0
  99. package/dist/modules/devices/api/admin/devices/route.js.map +7 -0
  100. package/dist/modules/devices/api/auth.js +9 -0
  101. package/dist/modules/devices/api/auth.js.map +7 -0
  102. package/dist/modules/devices/api/deviceList.js +53 -0
  103. package/dist/modules/devices/api/deviceList.js.map +7 -0
  104. package/dist/modules/devices/api/deviceOps.js +118 -0
  105. package/dist/modules/devices/api/deviceOps.js.map +7 -0
  106. package/dist/modules/devices/api/openapi.js +19 -0
  107. package/dist/modules/devices/api/openapi.js.map +7 -0
  108. package/dist/modules/devices/api/route.js +143 -0
  109. package/dist/modules/devices/api/route.js.map +7 -0
  110. package/dist/modules/devices/backend/devices/[id]/page.js +135 -0
  111. package/dist/modules/devices/backend/devices/[id]/page.js.map +7 -0
  112. package/dist/modules/devices/backend/devices/[id]/page.meta.js +16 -0
  113. package/dist/modules/devices/backend/devices/[id]/page.meta.js.map +7 -0
  114. package/dist/modules/devices/backend/devices/create/page.js +68 -0
  115. package/dist/modules/devices/backend/devices/create/page.js.map +7 -0
  116. package/dist/modules/devices/backend/devices/create/page.meta.js +16 -0
  117. package/dist/modules/devices/backend/devices/create/page.meta.js.map +7 -0
  118. package/dist/modules/devices/backend/devices/page.js +235 -0
  119. package/dist/modules/devices/backend/devices/page.js.map +7 -0
  120. package/dist/modules/devices/backend/devices/page.meta.js +23 -0
  121. package/dist/modules/devices/backend/devices/page.meta.js.map +7 -0
  122. package/dist/modules/devices/commands/deactivate.js +107 -0
  123. package/dist/modules/devices/commands/deactivate.js.map +7 -0
  124. package/dist/modules/devices/commands/index.js +4 -0
  125. package/dist/modules/devices/commands/index.js.map +7 -0
  126. package/dist/modules/devices/commands/register.js +183 -0
  127. package/dist/modules/devices/commands/register.js.map +7 -0
  128. package/dist/modules/devices/commands/shared.js +74 -0
  129. package/dist/modules/devices/commands/shared.js.map +7 -0
  130. package/dist/modules/devices/commands/update.js +126 -0
  131. package/dist/modules/devices/commands/update.js.map +7 -0
  132. package/dist/modules/devices/data/entities.js +83 -0
  133. package/dist/modules/devices/data/entities.js.map +7 -0
  134. package/dist/modules/devices/data/validators.js +49 -0
  135. package/dist/modules/devices/data/validators.js.map +7 -0
  136. package/dist/modules/devices/di.js +11 -0
  137. package/dist/modules/devices/di.js.map +7 -0
  138. package/dist/modules/devices/encryption.js +12 -0
  139. package/dist/modules/devices/encryption.js.map +7 -0
  140. package/dist/modules/devices/events.js +19 -0
  141. package/dist/modules/devices/events.js.map +7 -0
  142. package/dist/modules/devices/index.js +17 -0
  143. package/dist/modules/devices/index.js.map +7 -0
  144. package/dist/modules/devices/lib/operationMetadata.js +20 -0
  145. package/dist/modules/devices/lib/operationMetadata.js.map +7 -0
  146. package/dist/modules/devices/migrations/Migration20260602120000.js +15 -0
  147. package/dist/modules/devices/migrations/Migration20260602120000.js.map +7 -0
  148. package/dist/modules/devices/migrations/Migration20260630120000.js +15 -0
  149. package/dist/modules/devices/migrations/Migration20260630120000.js.map +7 -0
  150. package/dist/modules/devices/migrations/Migration20260701120000.js +13 -0
  151. package/dist/modules/devices/migrations/Migration20260701120000.js.map +7 -0
  152. package/dist/modules/devices/migrations/Migration20260721120000.js +15 -0
  153. package/dist/modules/devices/migrations/Migration20260721120000.js.map +7 -0
  154. package/dist/modules/devices/setup.js +13 -0
  155. package/dist/modules/devices/setup.js.map +7 -0
  156. package/dist/modules/entities/cli.js +8 -3
  157. package/dist/modules/entities/cli.js.map +2 -2
  158. package/dist/modules/entities/migrations/Migration20260722120000.js +28 -0
  159. package/dist/modules/entities/migrations/Migration20260722120000.js.map +7 -0
  160. package/dist/modules/inbox_ops/notifications.js +2 -0
  161. package/dist/modules/inbox_ops/notifications.js.map +2 -2
  162. package/dist/modules/messages/notifications.js +2 -0
  163. package/dist/modules/messages/notifications.js.map +2 -2
  164. package/dist/modules/notifications/acl.js +3 -1
  165. package/dist/modules/notifications/acl.js.map +2 -2
  166. package/dist/modules/notifications/api/admin/preferences/route.js +167 -0
  167. package/dist/modules/notifications/api/admin/preferences/route.js.map +7 -0
  168. package/dist/modules/notifications/api/channels/route.js +54 -0
  169. package/dist/modules/notifications/api/channels/route.js.map +7 -0
  170. package/dist/modules/notifications/api/preferences/route.js +126 -0
  171. package/dist/modules/notifications/api/preferences/route.js.map +7 -0
  172. package/dist/modules/notifications/api/route.js +8 -1
  173. package/dist/modules/notifications/api/route.js.map +2 -2
  174. package/dist/modules/notifications/api/types/[id]/channels/[channel]/route.js +187 -0
  175. package/dist/modules/notifications/api/types/[id]/channels/[channel]/route.js.map +7 -0
  176. package/dist/modules/notifications/api/types/route.js +225 -0
  177. package/dist/modules/notifications/api/types/route.js.map +7 -0
  178. package/dist/modules/notifications/api/unread-count/route.js +5 -1
  179. package/dist/modules/notifications/api/unread-count/route.js.map +2 -2
  180. package/dist/modules/notifications/backend/notifications/user-preferences/page.js +10 -0
  181. package/dist/modules/notifications/backend/notifications/user-preferences/page.js.map +7 -0
  182. package/dist/modules/notifications/backend/notifications/user-preferences/page.meta.js +28 -0
  183. package/dist/modules/notifications/backend/notifications/user-preferences/page.meta.js.map +7 -0
  184. package/dist/modules/notifications/backend/profile/notification-preferences/page.js +10 -0
  185. package/dist/modules/notifications/backend/profile/notification-preferences/page.js.map +7 -0
  186. package/dist/modules/notifications/backend/profile/notification-preferences/page.meta.js +33 -0
  187. package/dist/modules/notifications/backend/profile/notification-preferences/page.meta.js.map +7 -0
  188. package/dist/modules/notifications/data/entities.js +128 -1
  189. package/dist/modules/notifications/data/entities.js.map +2 -2
  190. package/dist/modules/notifications/data/validators.js +95 -2
  191. package/dist/modules/notifications/data/validators.js.map +2 -2
  192. package/dist/modules/notifications/di.js +7 -0
  193. package/dist/modules/notifications/di.js.map +2 -2
  194. package/dist/modules/notifications/events.js +17 -0
  195. package/dist/modules/notifications/events.js.map +2 -2
  196. package/dist/modules/notifications/frontend/NotificationPreferenceMatrix.js +190 -0
  197. package/dist/modules/notifications/frontend/NotificationPreferenceMatrix.js.map +7 -0
  198. package/dist/modules/notifications/frontend/NotificationPreferencesPageClient.js +124 -0
  199. package/dist/modules/notifications/frontend/NotificationPreferencesPageClient.js.map +7 -0
  200. package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js +166 -1
  201. package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js.map +2 -2
  202. package/dist/modules/notifications/frontend/NotificationUserPreferencesAdminPageClient.js +172 -0
  203. package/dist/modules/notifications/frontend/NotificationUserPreferencesAdminPageClient.js.map +7 -0
  204. package/dist/modules/notifications/generators.js +63 -0
  205. package/dist/modules/notifications/generators.js.map +7 -0
  206. package/dist/modules/notifications/lib/delivery-strategies-registry.js +19 -0
  207. package/dist/modules/notifications/lib/delivery-strategies-registry.js.map +7 -0
  208. package/dist/modules/notifications/lib/deliveryStrategies.js.map +2 -2
  209. package/dist/modules/notifications/lib/derive-category.js +8 -0
  210. package/dist/modules/notifications/lib/derive-category.js.map +7 -0
  211. package/dist/modules/notifications/lib/notification-channel-registry.js +35 -0
  212. package/dist/modules/notifications/lib/notification-channel-registry.js.map +7 -0
  213. package/dist/modules/notifications/lib/notification-type-registry.js +87 -0
  214. package/dist/modules/notifications/lib/notification-type-registry.js.map +7 -0
  215. package/dist/modules/notifications/lib/notificationCopy.js +14 -0
  216. package/dist/modules/notifications/lib/notificationCopy.js.map +7 -0
  217. package/dist/modules/notifications/lib/notificationFactory.js +4 -1
  218. package/dist/modules/notifications/lib/notificationFactory.js.map +2 -2
  219. package/dist/modules/notifications/lib/notificationMapper.js +2 -0
  220. package/dist/modules/notifications/lib/notificationMapper.js.map +2 -2
  221. package/dist/modules/notifications/lib/notificationPreferenceService.js +83 -0
  222. package/dist/modules/notifications/lib/notificationPreferenceService.js.map +7 -0
  223. package/dist/modules/notifications/lib/notificationService.js +83 -28
  224. package/dist/modules/notifications/lib/notificationService.js.map +2 -2
  225. package/dist/modules/notifications/lib/notificationVisibility.js +24 -0
  226. package/dist/modules/notifications/lib/notificationVisibility.js.map +7 -0
  227. package/dist/modules/notifications/lib/routeHelpers.js +11 -1
  228. package/dist/modules/notifications/lib/routeHelpers.js.map +2 -2
  229. package/dist/modules/notifications/lib/shouldDeliver.js +46 -0
  230. package/dist/modules/notifications/lib/shouldDeliver.js.map +7 -0
  231. package/dist/modules/notifications/lib/strategies/email-delivery-strategy.js +54 -0
  232. package/dist/modules/notifications/lib/strategies/email-delivery-strategy.js.map +7 -0
  233. package/dist/modules/notifications/lib/strategies/in-app-delivery-strategy.js +12 -0
  234. package/dist/modules/notifications/lib/strategies/in-app-delivery-strategy.js.map +7 -0
  235. package/dist/modules/notifications/lib/typeCatalogue.js +71 -0
  236. package/dist/modules/notifications/lib/typeCatalogue.js.map +7 -0
  237. package/dist/modules/notifications/lib/typeChannelSettings.js +12 -0
  238. package/dist/modules/notifications/lib/typeChannelSettings.js.map +7 -0
  239. package/dist/modules/notifications/lib/typeOverrides.js +19 -0
  240. package/dist/modules/notifications/lib/typeOverrides.js.map +7 -0
  241. package/dist/modules/notifications/migrations/Migration20260625122947_notifications.js +14 -0
  242. package/dist/modules/notifications/migrations/Migration20260625122947_notifications.js.map +7 -0
  243. package/dist/modules/notifications/migrations/Migration20260626120500_notifications_push_payload.js +15 -0
  244. package/dist/modules/notifications/migrations/Migration20260626120500_notifications_push_payload.js.map +7 -0
  245. package/dist/modules/notifications/migrations/Migration20260626130000_notifications_non_opt_out.js +13 -0
  246. package/dist/modules/notifications/migrations/Migration20260626130000_notifications_non_opt_out.js.map +7 -0
  247. package/dist/modules/notifications/migrations/Migration20260626140000_notifications_type_category_silent.js +15 -0
  248. package/dist/modules/notifications/migrations/Migration20260626140000_notifications_type_category_silent.js.map +7 -0
  249. package/dist/modules/notifications/migrations/Migration20260706120000_notifications_channels.js +13 -0
  250. package/dist/modules/notifications/migrations/Migration20260706120000_notifications_channels.js.map +7 -0
  251. package/dist/modules/notifications/migrations/Migration20260716123121_notifications.js +14 -0
  252. package/dist/modules/notifications/migrations/Migration20260716123121_notifications.js.map +7 -0
  253. package/dist/modules/notifications/notification-channels.js +26 -0
  254. package/dist/modules/notifications/notification-channels.js.map +7 -0
  255. package/dist/modules/notifications/notifications.delivery-strategies.js +12 -0
  256. package/dist/modules/notifications/notifications.delivery-strategies.js.map +7 -0
  257. package/dist/modules/notifications/setup.js +16 -1
  258. package/dist/modules/notifications/setup.js.map +2 -2
  259. package/dist/modules/notifications/subscribers/deliver-notification.js +66 -57
  260. package/dist/modules/notifications/subscribers/deliver-notification.js.map +2 -2
  261. package/dist/modules/notifications/subscribers/sync-notification-types.js +16 -0
  262. package/dist/modules/notifications/subscribers/sync-notification-types.js.map +7 -0
  263. package/dist/modules/notifications/widgets/injection/profile-preferences-menu/widget.js +23 -0
  264. package/dist/modules/notifications/widgets/injection/profile-preferences-menu/widget.js.map +7 -0
  265. package/dist/modules/notifications/widgets/injection-table.js +14 -0
  266. package/dist/modules/notifications/widgets/injection-table.js.map +7 -0
  267. package/dist/modules/push_notifications/acl.js +13 -0
  268. package/dist/modules/push_notifications/acl.js.map +7 -0
  269. package/dist/modules/push_notifications/api/custom-send/route.js +141 -0
  270. package/dist/modules/push_notifications/api/custom-send/route.js.map +7 -0
  271. package/dist/modules/push_notifications/api/deliveries/[id]/route.js +110 -0
  272. package/dist/modules/push_notifications/api/deliveries/[id]/route.js.map +7 -0
  273. package/dist/modules/push_notifications/api/deliveries/route.js +56 -0
  274. package/dist/modules/push_notifications/api/deliveries/route.js.map +7 -0
  275. package/dist/modules/push_notifications/api/openapi.js +19 -0
  276. package/dist/modules/push_notifications/api/openapi.js.map +7 -0
  277. package/dist/modules/push_notifications/backend/push_notifications/[id]/page.js +103 -0
  278. package/dist/modules/push_notifications/backend/push_notifications/[id]/page.js.map +7 -0
  279. package/dist/modules/push_notifications/backend/push_notifications/[id]/page.meta.js +13 -0
  280. package/dist/modules/push_notifications/backend/push_notifications/[id]/page.meta.js.map +7 -0
  281. package/dist/modules/push_notifications/backend/push_notifications/page.js +213 -0
  282. package/dist/modules/push_notifications/backend/push_notifications/page.js.map +7 -0
  283. package/dist/modules/push_notifications/backend/push_notifications/page.meta.js +23 -0
  284. package/dist/modules/push_notifications/backend/push_notifications/page.meta.js.map +7 -0
  285. package/dist/modules/push_notifications/backend/push_notifications/send/page.js +245 -0
  286. package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +7 -0
  287. package/dist/modules/push_notifications/backend/push_notifications/send/page.meta.js +26 -0
  288. package/dist/modules/push_notifications/backend/push_notifications/send/page.meta.js.map +7 -0
  289. package/dist/modules/push_notifications/data/entities.js +92 -0
  290. package/dist/modules/push_notifications/data/entities.js.map +7 -0
  291. package/dist/modules/push_notifications/data/extensions.js +23 -0
  292. package/dist/modules/push_notifications/data/extensions.js.map +7 -0
  293. package/dist/modules/push_notifications/data/validators.js +89 -0
  294. package/dist/modules/push_notifications/data/validators.js.map +7 -0
  295. package/dist/modules/push_notifications/di.js +17 -0
  296. package/dist/modules/push_notifications/di.js.map +7 -0
  297. package/dist/modules/push_notifications/events.js +24 -0
  298. package/dist/modules/push_notifications/events.js.map +7 -0
  299. package/dist/modules/push_notifications/index.js +16 -0
  300. package/dist/modules/push_notifications/index.js.map +7 -0
  301. package/dist/modules/push_notifications/lib/fake-provider-recorder.js +80 -0
  302. package/dist/modules/push_notifications/lib/fake-provider-recorder.js.map +7 -0
  303. package/dist/modules/push_notifications/lib/push-delivery-strategy.js +54 -0
  304. package/dist/modules/push_notifications/lib/push-delivery-strategy.js.map +7 -0
  305. package/dist/modules/push_notifications/lib/push-delivery.js +297 -0
  306. package/dist/modules/push_notifications/lib/push-delivery.js.map +7 -0
  307. package/dist/modules/push_notifications/lib/push-fanout.js +138 -0
  308. package/dist/modules/push_notifications/lib/push-fanout.js.map +7 -0
  309. package/dist/modules/push_notifications/lib/push-health.js +32 -0
  310. package/dist/modules/push_notifications/lib/push-health.js.map +7 -0
  311. package/dist/modules/push_notifications/lib/push-reaper.js +87 -0
  312. package/dist/modules/push_notifications/lib/push-reaper.js.map +7 -0
  313. package/dist/modules/push_notifications/lib/push-receipt-reaper.js +136 -0
  314. package/dist/modules/push_notifications/lib/push-receipt-reaper.js.map +7 -0
  315. package/dist/modules/push_notifications/lib/push-stub-adapter.js +63 -0
  316. package/dist/modules/push_notifications/lib/push-stub-adapter.js.map +7 -0
  317. package/dist/modules/push_notifications/lib/queue.js +53 -0
  318. package/dist/modules/push_notifications/lib/queue.js.map +7 -0
  319. package/dist/modules/push_notifications/lib/reclaim-window.js +13 -0
  320. package/dist/modules/push_notifications/lib/reclaim-window.js.map +7 -0
  321. package/dist/modules/push_notifications/lib/send-custom-push.js +48 -0
  322. package/dist/modules/push_notifications/lib/send-custom-push.js.map +7 -0
  323. package/dist/modules/push_notifications/migrations/Migration20260625150049_push_notifications.js +16 -0
  324. package/dist/modules/push_notifications/migrations/Migration20260625150049_push_notifications.js.map +7 -0
  325. package/dist/modules/push_notifications/migrations/Migration20260626120000_push_notifications_silent.js +13 -0
  326. package/dist/modules/push_notifications/migrations/Migration20260626120000_push_notifications_silent.js.map +7 -0
  327. package/dist/modules/push_notifications/notifications.delivery-strategies.js +8 -0
  328. package/dist/modules/push_notifications/notifications.delivery-strategies.js.map +7 -0
  329. package/dist/modules/push_notifications/notifications.js +40 -0
  330. package/dist/modules/push_notifications/notifications.js.map +7 -0
  331. package/dist/modules/push_notifications/setup.js +52 -0
  332. package/dist/modules/push_notifications/setup.js.map +7 -0
  333. package/dist/modules/push_notifications/workers/reclaim-stuck.worker.js +57 -0
  334. package/dist/modules/push_notifications/workers/reclaim-stuck.worker.js.map +7 -0
  335. package/dist/modules/push_notifications/workers/send-push.worker.js +27 -0
  336. package/dist/modules/push_notifications/workers/send-push.worker.js.map +7 -0
  337. package/dist/modules/sales/notifications.js +8 -0
  338. package/dist/modules/sales/notifications.js.map +2 -2
  339. package/dist/modules/staff/notifications.js +6 -0
  340. package/dist/modules/staff/notifications.js.map +2 -2
  341. package/dist/modules/workflows/notifications.js +2 -0
  342. package/dist/modules/workflows/notifications.js.map +2 -2
  343. package/generated/entities/notification/index.ts +3 -0
  344. package/generated/entities/notification_preference/index.ts +8 -0
  345. package/generated/entities/notification_type/index.ts +9 -0
  346. package/generated/entities/notification_type_override/index.ts +7 -0
  347. package/generated/entities/push_notification_delivery/index.ts +19 -0
  348. package/generated/entities/user_device/index.ts +16 -0
  349. package/generated/entities.ids.generated.ts +12 -1
  350. package/generated/entity-fields-registry.ts +72 -0
  351. package/package.json +7 -7
  352. package/src/helpers/integration/api.ts +2 -1
  353. package/src/helpers/integration/appRoot.ts +13 -0
  354. package/src/helpers/integration/dbFixtures.ts +1 -5
  355. package/src/helpers/integration/pushFake.ts +219 -0
  356. package/src/modules/auth/i18n/de.json +1 -0
  357. package/src/modules/auth/i18n/en.json +1 -0
  358. package/src/modules/auth/i18n/es.json +1 -0
  359. package/src/modules/auth/i18n/ko.json +1 -0
  360. package/src/modules/auth/i18n/pl.json +1 -0
  361. package/src/modules/auth/notifications.ts +16 -0
  362. package/src/modules/business_rules/i18n/de.json +2 -1
  363. package/src/modules/business_rules/i18n/en.json +2 -1
  364. package/src/modules/business_rules/i18n/es.json +2 -1
  365. package/src/modules/business_rules/i18n/ko.json +2 -1
  366. package/src/modules/business_rules/i18n/pl.json +2 -1
  367. package/src/modules/business_rules/notifications.ts +2 -0
  368. package/src/modules/catalog/i18n/de.json +2 -1
  369. package/src/modules/catalog/i18n/en.json +2 -1
  370. package/src/modules/catalog/i18n/es.json +2 -1
  371. package/src/modules/catalog/i18n/ko.json +2 -1
  372. package/src/modules/catalog/i18n/pl.json +2 -1
  373. package/src/modules/catalog/notifications.ts +2 -0
  374. package/src/modules/communication_channels/acl.ts +9 -0
  375. package/src/modules/communication_channels/api/delete/admin/channels/[id]/route.ts +168 -0
  376. package/src/modules/communication_channels/api/get/channels/[id]/health/route.ts +6 -2
  377. package/src/modules/communication_channels/api/get/channels/[id]/route.ts +6 -2
  378. package/src/modules/communication_channels/api/get/channels/route.ts +2 -1
  379. package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +16 -5
  380. package/src/modules/communication_channels/api/post/channels/connect/credentials/route.ts +37 -1
  381. package/src/modules/communication_channels/api/post/channels/connect/tenant-credentials/route.ts +175 -0
  382. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +11 -1
  383. package/src/modules/communication_channels/commands/admin-delete-channel.ts +203 -0
  384. package/src/modules/communication_channels/commands/connect-credential-channel.ts +63 -15
  385. package/src/modules/communication_channels/commands/deliver-outbound-message.ts +10 -2
  386. package/src/modules/communication_channels/commands/push-register.ts +7 -1
  387. package/src/modules/communication_channels/commands/push-unregister.ts +14 -3
  388. package/src/modules/communication_channels/data/entities.ts +10 -0
  389. package/src/modules/communication_channels/data/validators.ts +1 -0
  390. package/src/modules/communication_channels/i18n/de.json +35 -1
  391. package/src/modules/communication_channels/i18n/en.json +35 -1
  392. package/src/modules/communication_channels/i18n/es.json +35 -1
  393. package/src/modules/communication_channels/i18n/ko.json +35 -1
  394. package/src/modules/communication_channels/i18n/pl.json +35 -1
  395. package/src/modules/communication_channels/lib/access-control.ts +42 -0
  396. package/src/modules/communication_channels/lib/adapter.ts +25 -0
  397. package/src/modules/communication_channels/lib/connect-channel.ts +61 -26
  398. package/src/modules/communication_channels/lib/push-adapter.ts +139 -0
  399. package/src/modules/communication_channels/lib/push-capabilities.ts +42 -0
  400. package/src/modules/communication_channels/lib/push-connect-error.ts +52 -0
  401. package/src/modules/communication_channels/lib/push-credential-errors.ts +58 -0
  402. package/src/modules/communication_channels/lib/push-envelope.ts +104 -0
  403. package/src/modules/communication_channels/lib/refcounted-client-cache.ts +123 -0
  404. package/src/modules/communication_channels/migrations/.snapshot-open-mercato.json +9 -0
  405. package/src/modules/communication_channels/migrations/Migration20260703123630_communication_channels.ts +20 -0
  406. package/src/modules/communication_channels/notifications.ts +4 -0
  407. package/src/modules/communication_channels/setup.ts +2 -0
  408. package/src/modules/configs/i18n/de.json +5 -1
  409. package/src/modules/configs/i18n/en.json +5 -1
  410. package/src/modules/configs/i18n/es.json +5 -1
  411. package/src/modules/configs/i18n/ko.json +5 -1
  412. package/src/modules/configs/i18n/pl.json +5 -1
  413. package/src/modules/configs/lib/upgrade-actions.ts +21 -0
  414. package/src/modules/customer_accounts/i18n/de.json +2 -1
  415. package/src/modules/customer_accounts/i18n/en.json +2 -1
  416. package/src/modules/customer_accounts/i18n/es.json +2 -1
  417. package/src/modules/customer_accounts/i18n/ko.json +2 -1
  418. package/src/modules/customer_accounts/i18n/pl.json +2 -1
  419. package/src/modules/customer_accounts/notifications.ts +12 -0
  420. package/src/modules/customers/i18n/de.json +2 -1
  421. package/src/modules/customers/i18n/en.json +2 -1
  422. package/src/modules/customers/i18n/es.json +2 -1
  423. package/src/modules/customers/i18n/ko.json +2 -1
  424. package/src/modules/customers/i18n/pl.json +2 -1
  425. package/src/modules/customers/notifications.ts +4 -0
  426. package/src/modules/devices/AGENTS.md +101 -0
  427. package/src/modules/devices/acl.ts +7 -0
  428. package/src/modules/devices/api/[id]/route.ts +180 -0
  429. package/src/modules/devices/api/admin/devices/[id]/route.ts +235 -0
  430. package/src/modules/devices/api/admin/devices/route.ts +160 -0
  431. package/src/modules/devices/api/auth.ts +13 -0
  432. package/src/modules/devices/api/deviceList.ts +54 -0
  433. package/src/modules/devices/api/deviceOps.ts +186 -0
  434. package/src/modules/devices/api/openapi.ts +23 -0
  435. package/src/modules/devices/api/route.ts +165 -0
  436. package/src/modules/devices/backend/devices/[id]/page.meta.ts +12 -0
  437. package/src/modules/devices/backend/devices/[id]/page.tsx +164 -0
  438. package/src/modules/devices/backend/devices/create/page.meta.ts +12 -0
  439. package/src/modules/devices/backend/devices/create/page.tsx +81 -0
  440. package/src/modules/devices/backend/devices/page.meta.ts +21 -0
  441. package/src/modules/devices/backend/devices/page.tsx +259 -0
  442. package/src/modules/devices/commands/deactivate.ts +126 -0
  443. package/src/modules/devices/commands/index.ts +3 -0
  444. package/src/modules/devices/commands/register.ts +199 -0
  445. package/src/modules/devices/commands/shared.ts +119 -0
  446. package/src/modules/devices/commands/update.ts +142 -0
  447. package/src/modules/devices/data/entities.ts +79 -0
  448. package/src/modules/devices/data/validators.ts +65 -0
  449. package/src/modules/devices/di.ts +9 -0
  450. package/src/modules/devices/encryption.ts +15 -0
  451. package/src/modules/devices/events.ts +16 -0
  452. package/src/modules/devices/i18n/de.json +45 -0
  453. package/src/modules/devices/i18n/en.json +45 -0
  454. package/src/modules/devices/i18n/es.json +45 -0
  455. package/src/modules/devices/i18n/ko.json +45 -0
  456. package/src/modules/devices/i18n/pl.json +45 -0
  457. package/src/modules/devices/index.ts +15 -0
  458. package/src/modules/devices/lib/operationMetadata.ts +35 -0
  459. package/src/modules/devices/migrations/.snapshot-open-mercato.json +200 -0
  460. package/src/modules/devices/migrations/Migration20260602120000.ts +15 -0
  461. package/src/modules/devices/migrations/Migration20260630120000.ts +20 -0
  462. package/src/modules/devices/migrations/Migration20260701120000.ts +13 -0
  463. package/src/modules/devices/migrations/Migration20260721120000.ts +18 -0
  464. package/src/modules/devices/setup.ts +11 -0
  465. package/src/modules/entities/cli.ts +16 -2
  466. package/src/modules/entities/migrations/Migration20260722120000.ts +38 -0
  467. package/src/modules/inbox_ops/i18n/de.json +2 -1
  468. package/src/modules/inbox_ops/i18n/en.json +2 -1
  469. package/src/modules/inbox_ops/i18n/es.json +2 -1
  470. package/src/modules/inbox_ops/i18n/ko.json +2 -1
  471. package/src/modules/inbox_ops/i18n/pl.json +2 -1
  472. package/src/modules/inbox_ops/notifications.ts +2 -0
  473. package/src/modules/messages/i18n/de.json +2 -1
  474. package/src/modules/messages/i18n/en.json +2 -1
  475. package/src/modules/messages/i18n/es.json +2 -1
  476. package/src/modules/messages/i18n/ko.json +2 -1
  477. package/src/modules/messages/i18n/pl.json +2 -1
  478. package/src/modules/messages/notifications.ts +2 -0
  479. package/src/modules/notifications/AGENTS.md +54 -0
  480. package/src/modules/notifications/acl.ts +2 -0
  481. package/src/modules/notifications/api/admin/preferences/route.ts +193 -0
  482. package/src/modules/notifications/api/channels/route.ts +54 -0
  483. package/src/modules/notifications/api/preferences/route.ts +131 -0
  484. package/src/modules/notifications/api/route.ts +8 -1
  485. package/src/modules/notifications/api/types/[id]/channels/[channel]/route.ts +226 -0
  486. package/src/modules/notifications/api/types/route.ts +239 -0
  487. package/src/modules/notifications/api/unread-count/route.ts +5 -1
  488. package/src/modules/notifications/backend/notifications/user-preferences/page.meta.ts +26 -0
  489. package/src/modules/notifications/backend/notifications/user-preferences/page.tsx +12 -0
  490. package/src/modules/notifications/backend/profile/notification-preferences/page.meta.ts +31 -0
  491. package/src/modules/notifications/backend/profile/notification-preferences/page.tsx +12 -0
  492. package/src/modules/notifications/data/entities.ts +144 -0
  493. package/src/modules/notifications/data/validators.ts +116 -0
  494. package/src/modules/notifications/di.ts +7 -0
  495. package/src/modules/notifications/events.ts +23 -0
  496. package/src/modules/notifications/frontend/NotificationPreferenceMatrix.tsx +287 -0
  497. package/src/modules/notifications/frontend/NotificationPreferencesPageClient.tsx +155 -0
  498. package/src/modules/notifications/frontend/NotificationSettingsPageClient.tsx +273 -2
  499. package/src/modules/notifications/frontend/NotificationUserPreferencesAdminPageClient.tsx +214 -0
  500. package/src/modules/notifications/generators.ts +82 -0
  501. package/src/modules/notifications/i18n/de.json +43 -0
  502. package/src/modules/notifications/i18n/en.json +43 -0
  503. package/src/modules/notifications/i18n/es.json +43 -0
  504. package/src/modules/notifications/i18n/ko.json +43 -0
  505. package/src/modules/notifications/i18n/pl.json +44 -1
  506. package/src/modules/notifications/lib/delivery-strategies-registry.ts +30 -0
  507. package/src/modules/notifications/lib/deliveryStrategies.ts +40 -4
  508. package/src/modules/notifications/lib/derive-category.ts +15 -0
  509. package/src/modules/notifications/lib/notification-channel-registry.ts +59 -0
  510. package/src/modules/notifications/lib/notification-type-registry.ts +182 -0
  511. package/src/modules/notifications/lib/notificationCopy.ts +34 -0
  512. package/src/modules/notifications/lib/notificationFactory.ts +5 -1
  513. package/src/modules/notifications/lib/notificationMapper.ts +2 -0
  514. package/src/modules/notifications/lib/notificationPreferenceService.ts +138 -0
  515. package/src/modules/notifications/lib/notificationService.ts +129 -25
  516. package/src/modules/notifications/lib/notificationVisibility.ts +48 -0
  517. package/src/modules/notifications/lib/routeHelpers.ts +14 -1
  518. package/src/modules/notifications/lib/shouldDeliver.ts +112 -0
  519. package/src/modules/notifications/lib/strategies/email-delivery-strategy.ts +63 -0
  520. package/src/modules/notifications/lib/strategies/in-app-delivery-strategy.ts +21 -0
  521. package/src/modules/notifications/lib/typeCatalogue.ts +141 -0
  522. package/src/modules/notifications/lib/typeChannelSettings.ts +29 -0
  523. package/src/modules/notifications/lib/typeOverrides.ts +46 -0
  524. package/src/modules/notifications/migrations/.snapshot-open-mercato.json +874 -100
  525. package/src/modules/notifications/migrations/Migration20260625122947_notifications.ts +14 -0
  526. package/src/modules/notifications/migrations/Migration20260626120500_notifications_push_payload.ts +15 -0
  527. package/src/modules/notifications/migrations/Migration20260626130000_notifications_non_opt_out.ts +13 -0
  528. package/src/modules/notifications/migrations/Migration20260626140000_notifications_type_category_silent.ts +15 -0
  529. package/src/modules/notifications/migrations/Migration20260706120000_notifications_channels.ts +13 -0
  530. package/src/modules/notifications/migrations/Migration20260716123121_notifications.ts +14 -0
  531. package/src/modules/notifications/notification-channels.ts +30 -0
  532. package/src/modules/notifications/notifications.delivery-strategies.ts +15 -0
  533. package/src/modules/notifications/setup.ts +23 -1
  534. package/src/modules/notifications/subscribers/deliver-notification.ts +105 -71
  535. package/src/modules/notifications/subscribers/sync-notification-types.ts +18 -0
  536. package/src/modules/notifications/widgets/injection/profile-preferences-menu/widget.ts +35 -0
  537. package/src/modules/notifications/widgets/injection-table.ts +18 -0
  538. package/src/modules/push_notifications/AGENTS.md +92 -0
  539. package/src/modules/push_notifications/acl.ts +9 -0
  540. package/src/modules/push_notifications/api/custom-send/route.ts +175 -0
  541. package/src/modules/push_notifications/api/deliveries/[id]/route.ts +122 -0
  542. package/src/modules/push_notifications/api/deliveries/route.ts +58 -0
  543. package/src/modules/push_notifications/api/openapi.ts +22 -0
  544. package/src/modules/push_notifications/backend/push_notifications/[id]/page.meta.ts +9 -0
  545. package/src/modules/push_notifications/backend/push_notifications/[id]/page.tsx +149 -0
  546. package/src/modules/push_notifications/backend/push_notifications/page.meta.ts +21 -0
  547. package/src/modules/push_notifications/backend/push_notifications/page.tsx +239 -0
  548. package/src/modules/push_notifications/backend/push_notifications/send/page.meta.ts +24 -0
  549. package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +327 -0
  550. package/src/modules/push_notifications/data/entities.ts +111 -0
  551. package/src/modules/push_notifications/data/extensions.ts +29 -0
  552. package/src/modules/push_notifications/data/validators.ts +102 -0
  553. package/src/modules/push_notifications/di.ts +20 -0
  554. package/src/modules/push_notifications/events.ts +21 -0
  555. package/src/modules/push_notifications/i18n/de.json +79 -0
  556. package/src/modules/push_notifications/i18n/en.json +79 -0
  557. package/src/modules/push_notifications/i18n/es.json +79 -0
  558. package/src/modules/push_notifications/i18n/ko.json +79 -0
  559. package/src/modules/push_notifications/i18n/pl.json +79 -0
  560. package/src/modules/push_notifications/index.ts +15 -0
  561. package/src/modules/push_notifications/lib/fake-provider-recorder.ts +154 -0
  562. package/src/modules/push_notifications/lib/push-delivery-strategy.ts +90 -0
  563. package/src/modules/push_notifications/lib/push-delivery.ts +455 -0
  564. package/src/modules/push_notifications/lib/push-fanout.ts +237 -0
  565. package/src/modules/push_notifications/lib/push-health.ts +47 -0
  566. package/src/modules/push_notifications/lib/push-reaper.ts +140 -0
  567. package/src/modules/push_notifications/lib/push-receipt-reaper.ts +210 -0
  568. package/src/modules/push_notifications/lib/push-stub-adapter.ts +80 -0
  569. package/src/modules/push_notifications/lib/queue.ts +74 -0
  570. package/src/modules/push_notifications/lib/reclaim-window.ts +16 -0
  571. package/src/modules/push_notifications/lib/send-custom-push.ts +100 -0
  572. package/src/modules/push_notifications/migrations/.snapshot-open-mercato.json +386 -0
  573. package/src/modules/push_notifications/migrations/Migration20260625150049_push_notifications.ts +16 -0
  574. package/src/modules/push_notifications/migrations/Migration20260626120000_push_notifications_silent.ts +13 -0
  575. package/src/modules/push_notifications/notifications.delivery-strategies.ts +8 -0
  576. package/src/modules/push_notifications/notifications.ts +50 -0
  577. package/src/modules/push_notifications/setup.ts +92 -0
  578. package/src/modules/push_notifications/workers/reclaim-stuck.worker.ts +78 -0
  579. package/src/modules/push_notifications/workers/send-push.worker.ts +34 -0
  580. package/src/modules/sales/i18n/de.json +1 -0
  581. package/src/modules/sales/i18n/en.json +1 -0
  582. package/src/modules/sales/i18n/es.json +1 -0
  583. package/src/modules/sales/i18n/ko.json +1 -0
  584. package/src/modules/sales/i18n/pl.json +1 -0
  585. package/src/modules/sales/notifications.ts +8 -0
  586. package/src/modules/staff/i18n/de.json +1 -0
  587. package/src/modules/staff/i18n/en.json +1 -0
  588. package/src/modules/staff/i18n/es.json +1 -0
  589. package/src/modules/staff/i18n/ko.json +1 -0
  590. package/src/modules/staff/i18n/pl.json +1 -0
  591. package/src/modules/staff/notifications.ts +6 -0
  592. package/src/modules/workflows/i18n/de.json +1 -0
  593. package/src/modules/workflows/i18n/en.json +1 -0
  594. package/src/modules/workflows/i18n/es.json +1 -0
  595. package/src/modules/workflows/i18n/ko.json +1 -0
  596. package/src/modules/workflows/i18n/pl.json +1 -0
  597. package/src/modules/workflows/notifications.ts +2 -0
@@ -0,0 +1,82 @@
1
+ import type { GeneratorPlugin } from '@open-mercato/shared/modules/generators'
2
+
3
+ function buildDeliveryStrategiesOutput({
4
+ importSection,
5
+ entriesLiteral,
6
+ }: {
7
+ importSection: string
8
+ entriesLiteral: string
9
+ }): string {
10
+ return `// AUTO-GENERATED by mercato generate registry
11
+ ${importSection ? `${importSection}\n` : ''}type NotificationDeliveryStrategyEntry = { moduleId: string; strategies: unknown[] }
12
+
13
+ export const notificationDeliveryStrategyEntries: NotificationDeliveryStrategyEntry[] = [
14
+ ${entriesLiteral ? ` ${entriesLiteral}\n` : ''}]
15
+ `
16
+ }
17
+
18
+ /**
19
+ * Lets any module contribute notification delivery strategies by exporting
20
+ * `notifications.delivery-strategies.ts` (`export const deliveryStrategies = [...]`). The generator
21
+ * aggregates them and wires a bootstrap registration call, so the strategy registry is populated at
22
+ * boot without `bootstrap.ts` knowing about individual modules. Mirrors the security MFA-provider plugin.
23
+ */
24
+ const deliveryStrategiesPlugin: GeneratorPlugin = {
25
+ id: 'notifications.delivery-strategies',
26
+ conventionFile: 'notifications.delivery-strategies.ts',
27
+ importPrefix: 'NOTIFICATIONS_DELIVERY_STRATEGIES',
28
+ configExpr: (importName: string, moduleId: string) =>
29
+ `{ moduleId: '${moduleId}', strategies: ((${importName}.default ?? ${importName}.deliveryStrategies ?? []) as unknown[]) }`,
30
+ outputFileName: 'notifications-delivery-strategies.generated.ts',
31
+ buildOutput: buildDeliveryStrategiesOutput,
32
+ bootstrapRegistration: {
33
+ entriesExportName: 'notificationDeliveryStrategyEntries',
34
+ registrationImports: [
35
+ `import { registerNotificationDeliveryStrategyEntries } from '@open-mercato/core/modules/notifications/lib/delivery-strategies-registry'`,
36
+ ],
37
+ buildCall: (name: string) => `registerNotificationDeliveryStrategyEntries(${name})`,
38
+ },
39
+ }
40
+
41
+ function buildChannelsOutput({
42
+ importSection,
43
+ entriesLiteral,
44
+ }: {
45
+ importSection: string
46
+ entriesLiteral: string
47
+ }): string {
48
+ return `// AUTO-GENERATED by mercato generate registry
49
+ ${importSection ? `${importSection}\n` : ''}type NotificationChannelEntry = { moduleId: string; channels: unknown[] }
50
+
51
+ export const notificationChannelEntries: NotificationChannelEntry[] = [
52
+ ${entriesLiteral ? ` ${entriesLiteral}\n` : ''}]
53
+ `
54
+ }
55
+
56
+ /**
57
+ * Lets any module contribute notification channels (metadata for the preferences UI + the
58
+ * `/api/notifications/channels` endpoint) by exporting `notification-channels.ts`
59
+ * (`export const notificationChannels = [...]`). The generator aggregates them and wires a bootstrap
60
+ * registration call, so the channel catalogue is populated at boot without `bootstrap.ts` knowing about
61
+ * individual modules. Mirrors the delivery-strategies plugin.
62
+ */
63
+ const channelsPlugin: GeneratorPlugin = {
64
+ id: 'notifications.channels',
65
+ conventionFile: 'notification-channels.ts',
66
+ importPrefix: 'NOTIFICATION_CHANNELS',
67
+ configExpr: (importName: string, moduleId: string) =>
68
+ `{ moduleId: '${moduleId}', channels: ((${importName}.default ?? ${importName}.notificationChannels ?? []) as unknown[]) }`,
69
+ outputFileName: 'notification-channels.generated.ts',
70
+ buildOutput: buildChannelsOutput,
71
+ bootstrapRegistration: {
72
+ entriesExportName: 'notificationChannelEntries',
73
+ registrationImports: [
74
+ `import { registerNotificationChannelEntries } from '@open-mercato/core/modules/notifications/lib/notification-channel-registry'`,
75
+ ],
76
+ buildCall: (name: string) => `registerNotificationChannelEntries(${name})`,
77
+ },
78
+ }
79
+
80
+ export const generatorPlugins: GeneratorPlugin[] = [deliveryStrategiesPlugin, channelsPlugin]
81
+
82
+ export default generatorPlugins
@@ -23,6 +23,35 @@
23
23
  "notifications.footer.useHint": "Verwende",
24
24
  "notifications.markAllRead": "Alle als gelesen markieren",
25
25
  "notifications.nav.title": "Benachrichtigungen",
26
+ "notifications.preferences.admin.editingFor": "Einstellungen für {user}",
27
+ "notifications.preferences.admin.noUsers": "Keine Benutzer gefunden.",
28
+ "notifications.preferences.admin.pageDescription": "Suchen Sie einen Benutzer, um dessen Benachrichtigungskanäle zu überprüfen und zu bearbeiten.",
29
+ "notifications.preferences.admin.pageTitle": "Benachrichtigungseinstellungen der Benutzer",
30
+ "notifications.preferences.admin.searchPlaceholder": "Benutzer nach Name oder E-Mail suchen...",
31
+ "notifications.preferences.admin.searching": "Suche läuft...",
32
+ "notifications.preferences.channelDisabledHint": "Dieser Kanal wurde für diese Benachrichtigung von Ihrem Administrator deaktiviert.",
33
+ "notifications.preferences.channels.email": "E-Mail",
34
+ "notifications.preferences.channels.emailHint": "An die E-Mail-Adresse Ihres Kontos gesendet.",
35
+ "notifications.preferences.channels.inApp": "In-App",
36
+ "notifications.preferences.channels.inAppHint": "Benachrichtigungszentrale und Glocke.",
37
+ "notifications.preferences.channels.push": "Push",
38
+ "notifications.preferences.channels.pushHint": "Mobile Push (aktiv, sobald ein Push-Kanal verbunden ist).",
39
+ "notifications.preferences.columns.type": "Benachrichtigungstyp",
40
+ "notifications.preferences.empty": "Es sind noch keine Benachrichtigungstypen registriert.",
41
+ "notifications.preferences.entityNamePlural": "Benachrichtigungstypen",
42
+ "notifications.preferences.filters.category": "Kategorie",
43
+ "notifications.preferences.filters.categoryPlaceholder": "Kategorien suchen",
44
+ "notifications.preferences.loadError": "Benachrichtigungseinstellungen konnten nicht geladen werden",
45
+ "notifications.preferences.loading": "Benachrichtigungseinstellungen werden geladen...",
46
+ "notifications.preferences.pageDescription": "Wählen Sie, über welche Kanäle die einzelnen Benachrichtigungstypen zugestellt werden. Nicht gesetzte Optionen bleiben standardmäßig aktiviert.",
47
+ "notifications.preferences.pageTitle": "Benachrichtigungseinstellungen",
48
+ "notifications.preferences.profileGroup": "Profil",
49
+ "notifications.preferences.requiredHint": "Diese Benachrichtigung ist erforderlich und kann nicht deaktiviert werden.",
50
+ "notifications.preferences.save": "Einstellungen speichern",
51
+ "notifications.preferences.saveError": "Benachrichtigungseinstellungen konnten nicht gespeichert werden",
52
+ "notifications.preferences.saveSuccess": "Benachrichtigungseinstellungen gespeichert",
53
+ "notifications.preferences.saving": "Wird gespeichert...",
54
+ "notifications.preferences.userNotFound": "Benutzer nicht gefunden",
26
55
  "notifications.settings.core.appUrl": "Anwendungs-URL",
27
56
  "notifications.settings.core.appUrlHint": "Wird verwendet, um absolute Links in E-Mail-Benachrichtigungen zu erstellen.",
28
57
  "notifications.settings.core.databaseHint": "Speichert Benachrichtigungen in der Datenbank für Panel und Glocke.",
@@ -46,10 +75,24 @@
46
75
  "notifications.settings.saveError": "Benachrichtigungseinstellungen konnten nicht gespeichert werden",
47
76
  "notifications.settings.saveSuccess": "Benachrichtigungseinstellungen gespeichert",
48
77
  "notifications.settings.saving": "Speichern...",
78
+ "notifications.settings.types.description": "Zustellkanäle pro Benachrichtigungstyp. Das Ausschalten eines Kanals deaktiviert ihn vollständig für diesen Typ in Ihrem Tenant — er wird nie zugestellt und Nutzer können ihn nicht in ihren Einstellungen aktivieren. Ein eingeschalteter Kanal lässt Nutzer pro Typ entscheiden; erforderliche (Non-Opt-out-)Typen werden auf aktivierten Kanälen immer zugestellt. Ihre Einstellung überschreibt den Modul-Standard.",
79
+ "notifications.settings.types.empty": "Es sind noch keine Benachrichtigungstypen registriert.",
80
+ "notifications.settings.types.lastChannelRestored": "Ein Benachrichtigungstyp muss mindestens einen Kanal behalten, daher wurde die Standardeinstellung des Moduls wiederhergestellt.",
81
+ "notifications.settings.types.loadError": "Benachrichtigungstypen konnten nicht geladen werden",
82
+ "notifications.settings.types.requiredColumn": "Erforderlich",
83
+ "notifications.settings.types.requiredHint": "Nutzer können sich nicht abmelden, wenn aktiviert.",
84
+ "notifications.settings.types.saveError": "Einstellungen des Benachrichtigungstyps konnten nicht gespeichert werden",
85
+ "notifications.settings.types.saveSuccess": "Einstellungen des Benachrichtigungstyps gespeichert",
86
+ "notifications.settings.types.title": "Zustellkanäle pro Typ",
87
+ "notifications.settings.types.typeColumn": "Benachrichtigungstyp",
49
88
  "notifications.title": "Benachrichtigungen",
50
89
  "notifications.toast.actionError": "Aktion konnte nicht ausgeführt werden",
51
90
  "notifications.toast.actionSuccess": "Aktion erfolgreich ausgeführt",
52
91
  "notifications.toast.dismissed": "Benachrichtigung verworfen",
53
92
  "notifications.toast.new": "Neue Benachrichtigung",
93
+ "notifications.types.invalidChannels": "Ungültige Kanal-Daten",
94
+ "notifications.types.overrideConflict": "Ein anderer Operator hat diesen Benachrichtigungstyp gerade gespeichert. Bitte neu laden und erneut versuchen.",
95
+ "notifications.types.unknownChannel": "Unbekannter Benachrichtigungskanal",
96
+ "notifications.types.unknownType": "Unbekannter Benachrichtigungstyp",
54
97
  "notifications.unreadSummary": "{count} ungelesen"
55
98
  }
@@ -23,6 +23,35 @@
23
23
  "notifications.footer.useHint": "Use",
24
24
  "notifications.markAllRead": "Mark all read",
25
25
  "notifications.nav.title": "Notifications",
26
+ "notifications.preferences.admin.editingFor": "Preferences for {user}",
27
+ "notifications.preferences.admin.noUsers": "No users found.",
28
+ "notifications.preferences.admin.pageDescription": "Search for a user to review and edit their notification channel preferences.",
29
+ "notifications.preferences.admin.pageTitle": "User Notification Preferences",
30
+ "notifications.preferences.admin.searchPlaceholder": "Search users by name or email...",
31
+ "notifications.preferences.admin.searching": "Searching...",
32
+ "notifications.preferences.channelDisabledHint": "This channel is turned off for this notification by your administrator.",
33
+ "notifications.preferences.channels.email": "Email",
34
+ "notifications.preferences.channels.emailHint": "Sent to your account email address.",
35
+ "notifications.preferences.channels.inApp": "In-app",
36
+ "notifications.preferences.channels.inAppHint": "Notification center and bell.",
37
+ "notifications.preferences.channels.push": "Push",
38
+ "notifications.preferences.channels.pushHint": "Mobile push (active once a push channel is connected).",
39
+ "notifications.preferences.columns.type": "Notification type",
40
+ "notifications.preferences.empty": "No notification types are registered yet.",
41
+ "notifications.preferences.entityNamePlural": "notification types",
42
+ "notifications.preferences.filters.category": "Category",
43
+ "notifications.preferences.filters.categoryPlaceholder": "Search categories",
44
+ "notifications.preferences.loadError": "Failed to load notification preferences",
45
+ "notifications.preferences.loading": "Loading notification preferences...",
46
+ "notifications.preferences.pageDescription": "Choose which channels deliver each notification type. Unset choices stay enabled by default.",
47
+ "notifications.preferences.pageTitle": "Notification Preferences",
48
+ "notifications.preferences.profileGroup": "Profile",
49
+ "notifications.preferences.requiredHint": "This notification is required and cannot be turned off.",
50
+ "notifications.preferences.save": "Save preferences",
51
+ "notifications.preferences.saveError": "Failed to save notification preferences",
52
+ "notifications.preferences.saveSuccess": "Notification preferences saved",
53
+ "notifications.preferences.saving": "Saving...",
54
+ "notifications.preferences.userNotFound": "User not found",
26
55
  "notifications.settings.core.appUrl": "Application URL",
27
56
  "notifications.settings.core.appUrlHint": "Used to build absolute links in email notifications.",
28
57
  "notifications.settings.core.databaseHint": "Store notifications in the database for the panel and bell.",
@@ -46,10 +75,24 @@
46
75
  "notifications.settings.saveError": "Failed to save notification settings",
47
76
  "notifications.settings.saveSuccess": "Notification settings saved",
48
77
  "notifications.settings.saving": "Saving...",
78
+ "notifications.settings.types.description": "Delivery channels per notification type. Turning a channel off disables it completely for that type in your tenant — it never delivers and users cannot enable it in their preferences. Turning it on lets users opt in or out per type; required (non-opt-out) types always deliver on enabled channels. Your setting overrides the module default.",
79
+ "notifications.settings.types.empty": "No notification types are registered yet.",
80
+ "notifications.settings.types.lastChannelRestored": "A notification type must keep at least one channel, so the module default was restored.",
81
+ "notifications.settings.types.loadError": "Failed to load notification types",
82
+ "notifications.settings.types.requiredColumn": "Required",
83
+ "notifications.settings.types.requiredHint": "Users cannot opt out when on.",
84
+ "notifications.settings.types.saveError": "Failed to save notification type settings",
85
+ "notifications.settings.types.saveSuccess": "Notification type settings saved",
86
+ "notifications.settings.types.title": "Delivery channels per type",
87
+ "notifications.settings.types.typeColumn": "Notification type",
49
88
  "notifications.title": "Notifications",
50
89
  "notifications.toast.actionError": "Failed to execute action",
51
90
  "notifications.toast.actionSuccess": "Action completed successfully",
52
91
  "notifications.toast.dismissed": "Notification dismissed",
53
92
  "notifications.toast.new": "New notification",
93
+ "notifications.types.invalidChannels": "Invalid channels payload",
94
+ "notifications.types.overrideConflict": "Another operator just saved this notification type. Reload and try again.",
95
+ "notifications.types.unknownChannel": "Unknown notification channel",
96
+ "notifications.types.unknownType": "Unknown notification type",
54
97
  "notifications.unreadSummary": "{count} unread"
55
98
  }
@@ -23,6 +23,35 @@
23
23
  "notifications.footer.useHint": "Usa",
24
24
  "notifications.markAllRead": "Marcar todo como leído",
25
25
  "notifications.nav.title": "Notificaciones",
26
+ "notifications.preferences.admin.editingFor": "Preferencias de {user}",
27
+ "notifications.preferences.admin.noUsers": "No se encontraron usuarios.",
28
+ "notifications.preferences.admin.pageDescription": "Busca un usuario para revisar y editar sus preferencias de canales de notificación.",
29
+ "notifications.preferences.admin.pageTitle": "Preferencias de notificaciones de usuarios",
30
+ "notifications.preferences.admin.searchPlaceholder": "Buscar usuarios por nombre o correo electrónico...",
31
+ "notifications.preferences.admin.searching": "Buscando...",
32
+ "notifications.preferences.channelDisabledHint": "Este canal está desactivado para esta notificación por tu administrador.",
33
+ "notifications.preferences.channels.email": "Correo electrónico",
34
+ "notifications.preferences.channels.emailHint": "Enviado a la dirección de correo de tu cuenta.",
35
+ "notifications.preferences.channels.inApp": "En la aplicación",
36
+ "notifications.preferences.channels.inAppHint": "Centro de notificaciones y campana.",
37
+ "notifications.preferences.channels.push": "Push",
38
+ "notifications.preferences.channels.pushHint": "Push móvil (activo cuando se conecta un canal push).",
39
+ "notifications.preferences.columns.type": "Tipo de notificación",
40
+ "notifications.preferences.empty": "Aún no hay tipos de notificación registrados.",
41
+ "notifications.preferences.entityNamePlural": "tipos de notificación",
42
+ "notifications.preferences.filters.category": "Categoría",
43
+ "notifications.preferences.filters.categoryPlaceholder": "Buscar categorías",
44
+ "notifications.preferences.loadError": "No se pudieron cargar las preferencias de notificaciones",
45
+ "notifications.preferences.loading": "Cargando preferencias de notificaciones...",
46
+ "notifications.preferences.pageDescription": "Elige qué canales entregan cada tipo de notificación. Las opciones sin definir permanecen activadas de forma predeterminada.",
47
+ "notifications.preferences.pageTitle": "Preferencias de notificaciones",
48
+ "notifications.preferences.profileGroup": "Perfil",
49
+ "notifications.preferences.requiredHint": "Esta notificación es obligatoria y no se puede desactivar.",
50
+ "notifications.preferences.save": "Guardar preferencias",
51
+ "notifications.preferences.saveError": "No se pudieron guardar las preferencias de notificaciones",
52
+ "notifications.preferences.saveSuccess": "Preferencias de notificaciones guardadas",
53
+ "notifications.preferences.saving": "Guardando...",
54
+ "notifications.preferences.userNotFound": "Usuario no encontrado",
26
55
  "notifications.settings.core.appUrl": "URL de la aplicación",
27
56
  "notifications.settings.core.appUrlHint": "Se usa para construir enlaces absolutos en notificaciones por email.",
28
57
  "notifications.settings.core.databaseHint": "Guarda las notificaciones en la base de datos para el panel y la campana.",
@@ -46,10 +75,24 @@
46
75
  "notifications.settings.saveError": "No se pudieron guardar los ajustes de notificaciones",
47
76
  "notifications.settings.saveSuccess": "Ajustes de notificaciones guardados",
48
77
  "notifications.settings.saving": "Guardando...",
78
+ "notifications.settings.types.description": "Canales de entrega por tipo de notificación. Apagar un canal lo desactiva por completo para ese tipo en tu tenant: nunca se entrega y los usuarios no pueden activarlo en sus preferencias. Un canal encendido permite a los usuarios decidir por tipo; los tipos obligatorios (sin exclusión) siempre se entregan en los canales activos. Tu configuración anula el valor predeterminado del módulo.",
79
+ "notifications.settings.types.empty": "Aún no hay tipos de notificación registrados.",
80
+ "notifications.settings.types.lastChannelRestored": "Un tipo de notificación debe conservar al menos un canal, por lo que se restauró el valor predeterminado del módulo.",
81
+ "notifications.settings.types.loadError": "No se pudieron cargar los tipos de notificación",
82
+ "notifications.settings.types.requiredColumn": "Obligatoria",
83
+ "notifications.settings.types.requiredHint": "Los usuarios no pueden desactivarla cuando está activada.",
84
+ "notifications.settings.types.saveError": "No se pudieron guardar los ajustes del tipo de notificación",
85
+ "notifications.settings.types.saveSuccess": "Ajustes del tipo de notificación guardados",
86
+ "notifications.settings.types.title": "Canales de entrega por tipo",
87
+ "notifications.settings.types.typeColumn": "Tipo de notificación",
49
88
  "notifications.title": "Notificaciones",
50
89
  "notifications.toast.actionError": "No se pudo ejecutar la acción",
51
90
  "notifications.toast.actionSuccess": "Acción completada correctamente",
52
91
  "notifications.toast.dismissed": "Notificación descartada",
53
92
  "notifications.toast.new": "Nueva notificación",
93
+ "notifications.types.invalidChannels": "Payload de canales no válido",
94
+ "notifications.types.overrideConflict": "Otro operador acaba de guardar este tipo de notificación. Vuelve a cargar e inténtalo de nuevo.",
95
+ "notifications.types.unknownChannel": "Canal de notificación desconocido",
96
+ "notifications.types.unknownType": "Tipo de notificación desconocido",
54
97
  "notifications.unreadSummary": "{count} sin leer"
55
98
  }
@@ -23,6 +23,35 @@
23
23
  "notifications.footer.useHint": "사용",
24
24
  "notifications.markAllRead": "모두 읽음으로 표시",
25
25
  "notifications.nav.title": "알림",
26
+ "notifications.preferences.admin.editingFor": "{user} 님의 환경설정",
27
+ "notifications.preferences.admin.noUsers": "사용자를 찾을 수 없습니다.",
28
+ "notifications.preferences.admin.pageDescription": "사용자를 검색해 해당 사용자의 알림 채널 환경설정을 확인하고 수정하세요.",
29
+ "notifications.preferences.admin.pageTitle": "사용자 알림 환경설정",
30
+ "notifications.preferences.admin.searchPlaceholder": "이름 또는 이메일로 사용자 검색...",
31
+ "notifications.preferences.admin.searching": "검색하는 중...",
32
+ "notifications.preferences.channelDisabledHint": "이 알림에 대해 관리자가 이 채널을 꺼 두었습니다.",
33
+ "notifications.preferences.channels.email": "이메일",
34
+ "notifications.preferences.channels.emailHint": "계정 이메일 주소로 전송됩니다.",
35
+ "notifications.preferences.channels.inApp": "앱 내",
36
+ "notifications.preferences.channels.inAppHint": "알림 센터와 알림 벨에 표시됩니다.",
37
+ "notifications.preferences.channels.push": "푸시",
38
+ "notifications.preferences.channels.pushHint": "모바일 푸시 (푸시 채널이 연결되면 활성화됩니다).",
39
+ "notifications.preferences.columns.type": "알림 유형",
40
+ "notifications.preferences.empty": "아직 등록된 알림 유형이 없습니다.",
41
+ "notifications.preferences.entityNamePlural": "알림 유형",
42
+ "notifications.preferences.filters.category": "카테고리",
43
+ "notifications.preferences.filters.categoryPlaceholder": "카테고리 검색",
44
+ "notifications.preferences.loadError": "알림 환경설정을 불러오지 못했습니다",
45
+ "notifications.preferences.loading": "알림 환경설정을 불러오는 중...",
46
+ "notifications.preferences.pageDescription": "각 알림 유형을 어떤 채널로 받을지 선택하세요. 설정하지 않은 항목은 기본적으로 켜진 상태로 유지됩니다.",
47
+ "notifications.preferences.pageTitle": "알림 환경설정",
48
+ "notifications.preferences.profileGroup": "프로필",
49
+ "notifications.preferences.requiredHint": "이 알림은 필수이므로 끌 수 없습니다.",
50
+ "notifications.preferences.save": "환경설정 저장",
51
+ "notifications.preferences.saveError": "알림 환경설정을 저장하지 못했습니다",
52
+ "notifications.preferences.saveSuccess": "알림 환경설정이 저장되었습니다",
53
+ "notifications.preferences.saving": "저장 중...",
54
+ "notifications.preferences.userNotFound": "사용자를 찾을 수 없습니다",
26
55
  "notifications.settings.core.appUrl": "애플리케이션 URL",
27
56
  "notifications.settings.core.appUrlHint": "이메일 알림에서 절대 링크를 생성하는 데 사용됩니다.",
28
57
  "notifications.settings.core.databaseHint": "패널과 벨 아이콘을 위해 알림을 데이터베이스에 저장합니다.",
@@ -46,10 +75,24 @@
46
75
  "notifications.settings.saveError": "알림 설정 저장에 실패했습니다",
47
76
  "notifications.settings.saveSuccess": "알림 설정이 저장되었습니다",
48
77
  "notifications.settings.saving": "저장 중...",
78
+ "notifications.settings.types.description": "알림 유형별 전송 채널입니다. 채널을 끄면 해당 유형에 대해 테넌트 전체에서 완전히 비활성화되어 전송되지 않으며, 사용자도 환경설정에서 켤 수 없습니다. 채널을 켜면 사용자가 유형별로 수신 여부를 선택할 수 있고, 필수(수신 거부 불가) 유형은 활성화된 채널로 항상 전송됩니다. 이 설정은 모듈 기본값보다 우선합니다.",
79
+ "notifications.settings.types.empty": "아직 등록된 알림 유형이 없습니다.",
80
+ "notifications.settings.types.lastChannelRestored": "알림 유형에는 채널이 하나 이상 있어야 하므로 모듈 기본값이 복원되었습니다.",
81
+ "notifications.settings.types.loadError": "알림 유형을 불러오지 못했습니다",
82
+ "notifications.settings.types.requiredColumn": "필수",
83
+ "notifications.settings.types.requiredHint": "켜져 있으면 사용자가 수신을 거부할 수 없습니다.",
84
+ "notifications.settings.types.saveError": "알림 유형 설정을 저장하지 못했습니다",
85
+ "notifications.settings.types.saveSuccess": "알림 유형 설정이 저장되었습니다",
86
+ "notifications.settings.types.title": "유형별 전송 채널",
87
+ "notifications.settings.types.typeColumn": "알림 유형",
49
88
  "notifications.title": "알림",
50
89
  "notifications.toast.actionError": "작업을 실행하지 못했습니다",
51
90
  "notifications.toast.actionSuccess": "작업이 성공적으로 완료되었습니다",
52
91
  "notifications.toast.dismissed": "알림이 닫혔습니다",
53
92
  "notifications.toast.new": "새 알림",
93
+ "notifications.types.invalidChannels": "잘못된 채널 데이터입니다",
94
+ "notifications.types.overrideConflict": "다른 담당자가 방금 이 알림 유형을 저장했습니다. 새로고침한 뒤 다시 시도하세요.",
95
+ "notifications.types.unknownChannel": "알 수 없는 알림 채널입니다",
96
+ "notifications.types.unknownType": "알 수 없는 알림 유형입니다",
54
97
  "notifications.unreadSummary": "읽지 않음 {count}개"
55
98
  }
@@ -23,6 +23,35 @@
23
23
  "notifications.footer.useHint": "Użyj",
24
24
  "notifications.markAllRead": "Oznacz wszystkie jako przeczytane",
25
25
  "notifications.nav.title": "Powiadomienia",
26
+ "notifications.preferences.admin.editingFor": "Preferencje dla {user}",
27
+ "notifications.preferences.admin.noUsers": "Nie znaleziono użytkowników.",
28
+ "notifications.preferences.admin.pageDescription": "Wyszukaj użytkownika, aby przejrzeć i edytować jego preferencje kanałów powiadomień.",
29
+ "notifications.preferences.admin.pageTitle": "Preferencje powiadomień użytkowników",
30
+ "notifications.preferences.admin.searchPlaceholder": "Szukaj użytkowników według nazwy lub e-maila...",
31
+ "notifications.preferences.admin.searching": "Wyszukiwanie...",
32
+ "notifications.preferences.channelDisabledHint": "Ten kanał został wyłączony dla tego powiadomienia przez administratora.",
33
+ "notifications.preferences.channels.email": "E-mail",
34
+ "notifications.preferences.channels.emailHint": "Wysyłane na adres e-mail Twojego konta.",
35
+ "notifications.preferences.channels.inApp": "W aplikacji",
36
+ "notifications.preferences.channels.inAppHint": "Centrum powiadomień i dzwonek.",
37
+ "notifications.preferences.channels.push": "Push",
38
+ "notifications.preferences.channels.pushHint": "Powiadomienia push (aktywne po podłączeniu kanału push).",
39
+ "notifications.preferences.columns.type": "Typ powiadomienia",
40
+ "notifications.preferences.empty": "Nie zarejestrowano jeszcze żadnych typów powiadomień.",
41
+ "notifications.preferences.entityNamePlural": "typów powiadomień",
42
+ "notifications.preferences.filters.category": "Kategoria",
43
+ "notifications.preferences.filters.categoryPlaceholder": "Szukaj kategorii",
44
+ "notifications.preferences.loadError": "Nie udało się załadować preferencji powiadomień",
45
+ "notifications.preferences.loading": "Ładowanie preferencji powiadomień...",
46
+ "notifications.preferences.pageDescription": "Wybierz, które kanały dostarczają poszczególne typy powiadomień. Nieustawione opcje pozostają domyślnie włączone.",
47
+ "notifications.preferences.pageTitle": "Preferencje powiadomień",
48
+ "notifications.preferences.profileGroup": "Profil",
49
+ "notifications.preferences.requiredHint": "To powiadomienie jest wymagane i nie można go wyłączyć.",
50
+ "notifications.preferences.save": "Zapisz preferencje",
51
+ "notifications.preferences.saveError": "Nie udało się zapisać preferencji powiadomień",
52
+ "notifications.preferences.saveSuccess": "Zapisano preferencje powiadomień",
53
+ "notifications.preferences.saving": "Zapisywanie...",
54
+ "notifications.preferences.userNotFound": "Nie znaleziono użytkownika",
26
55
  "notifications.settings.core.appUrl": "URL aplikacji",
27
56
  "notifications.settings.core.appUrlHint": "Służy do budowania bezwzględnych linków w powiadomieniach e-mail.",
28
57
  "notifications.settings.core.databaseHint": "Zapisuje powiadomienia w bazie danych dla panelu i dzwonka.",
@@ -35,7 +64,7 @@
35
64
  "notifications.settings.email.enabledHint": "Akcje w e-mailu są tylko do odczytu i prowadzą do centrum powiadomień.",
36
65
  "notifications.settings.email.enabledLabel": "Włącz dostarczanie e-mail",
37
66
  "notifications.settings.email.from": "Adres nadawcy",
38
- "notifications.settings.email.replyTo": "Odpowiedz do",
67
+ "notifications.settings.email.replyTo": "Adres zwrotny",
39
68
  "notifications.settings.email.subjectPrefix": "Prefiks tematu",
40
69
  "notifications.settings.email.title": "Strategia e-mail",
41
70
  "notifications.settings.loadError": "Nie udało się załadować ustawień powiadomień",
@@ -46,10 +75,24 @@
46
75
  "notifications.settings.saveError": "Nie udało się zapisać ustawień powiadomień",
47
76
  "notifications.settings.saveSuccess": "Ustawienia powiadomień zapisane",
48
77
  "notifications.settings.saving": "Zapisywanie...",
78
+ "notifications.settings.types.description": "Kanały dostarczania per typ powiadomienia. Wyłączenie kanału całkowicie dezaktywuje go dla tego typu w Twoim tenancie — nigdy nie jest dostarczany, a użytkownicy nie mogą go włączyć w swoich preferencjach. Włączony kanał pozwala użytkownikom decydować per typ; typy wymagane (bez rezygnacji) zawsze dostarczają na włączonych kanałach. Twoje ustawienie nadpisuje domyślne z modułu.",
79
+ "notifications.settings.types.empty": "Nie zarejestrowano jeszcze żadnych typów powiadomień.",
80
+ "notifications.settings.types.lastChannelRestored": "Typ powiadomienia musi mieć co najmniej jeden kanał, więc przywrócono domyślne ustawienie modułu.",
81
+ "notifications.settings.types.loadError": "Nie udało się wczytać typów powiadomień",
82
+ "notifications.settings.types.requiredColumn": "Wymagane",
83
+ "notifications.settings.types.requiredHint": "Użytkownicy nie mogą zrezygnować, gdy włączone.",
84
+ "notifications.settings.types.saveError": "Nie udało się zapisać ustawień typu powiadomienia",
85
+ "notifications.settings.types.saveSuccess": "Zapisano ustawienia typu powiadomienia",
86
+ "notifications.settings.types.title": "Kanały dostarczania per typ",
87
+ "notifications.settings.types.typeColumn": "Typ powiadomienia",
49
88
  "notifications.title": "Powiadomienia",
50
89
  "notifications.toast.actionError": "Nie udało się wykonać akcji",
51
90
  "notifications.toast.actionSuccess": "Akcja wykonana pomyślnie",
52
91
  "notifications.toast.dismissed": "Powiadomienie odrzucone",
53
92
  "notifications.toast.new": "Nowe powiadomienie",
93
+ "notifications.types.invalidChannels": "Nieprawidłowe dane kanałów",
94
+ "notifications.types.overrideConflict": "Inny operator właśnie zapisał ten typ powiadomienia. Odśwież i spróbuj ponownie.",
95
+ "notifications.types.unknownChannel": "Nieznany kanał powiadomień",
96
+ "notifications.types.unknownType": "Nieznany typ powiadomienia",
54
97
  "notifications.unreadSummary": "{count} nieprzeczytanych"
55
98
  }
@@ -0,0 +1,30 @@
1
+ import {
2
+ getNotificationDeliveryStrategies,
3
+ registerNotificationDeliveryStrategy,
4
+ type NotificationDeliveryStrategy,
5
+ } from './deliveryStrategies'
6
+
7
+ export type NotificationDeliveryStrategyEntry = {
8
+ moduleId: string
9
+ strategies: unknown[]
10
+ }
11
+
12
+ /**
13
+ * Bootstrap-time registration of module-contributed notification delivery strategies.
14
+ *
15
+ * Fed from the generated `notifications-delivery-strategies.generated.ts` aggregate (see
16
+ * `notifications/generators.ts`) via `runBootstrapRegistrations()`, mirroring how the security
17
+ * module registers its MFA providers. Idempotent: a strategy whose `id` is already registered is
18
+ * skipped, so a repeated bootstrap (HMR / test re-import) never double-registers.
19
+ */
20
+ export function registerNotificationDeliveryStrategyEntries(entries: NotificationDeliveryStrategyEntry[]): void {
21
+ const registered = new Set(getNotificationDeliveryStrategies().map((strategy) => strategy.id))
22
+ for (const entry of entries) {
23
+ for (const strategy of entry.strategies ?? []) {
24
+ const candidate = strategy as NotificationDeliveryStrategy
25
+ if (!candidate?.id || registered.has(candidate.id)) continue
26
+ registerNotificationDeliveryStrategy(candidate)
27
+ registered.add(candidate.id)
28
+ }
29
+ }
30
+ }
@@ -11,24 +11,60 @@ export type NotificationDeliveryRecipient = {
11
11
  name?: string | null
12
12
  }
13
13
 
14
- export type NotificationDeliveryContext = {
14
+ /**
15
+ * Channel-agnostic delivery context. Every strategy can rely on these fields regardless of channel.
16
+ */
17
+ export type NotificationDeliveryContextCore = {
15
18
  notification: Notification
16
19
  recipient: NotificationDeliveryRecipient
17
20
  title: string
18
21
  body: string | null
19
- panelUrl: string | null
20
- panelLink: string | null
21
- actionLinks: Array<{ id: string; label: string; href: string }>
22
22
  deliveryConfig: NotificationDeliveryConfig
23
23
  config: NotificationDeliveryStrategyConfig
24
24
  resolve: <T = unknown>(name: string) => T
25
25
  t: (key: string, fallback?: string, variables?: Record<string, string>) => string
26
26
  }
27
27
 
28
+ /**
29
+ * Email-shaped extras carried on every context for backward compatibility. Only the `email` strategy
30
+ * should read these — they encode one channel's assumptions (a panel deep-link and pre-rendered
31
+ * action hyperlinks). New channel strategies MUST derive whatever they need from `notification`
32
+ * instead.
33
+ *
34
+ * @deprecated These fields are email-specific and will move behind an email-scoped accessor in a
35
+ * future major version. Do not depend on them from a non-email strategy.
36
+ */
37
+ export type EmailDeliveryExtras = {
38
+ /** @deprecated Email-specific. Absolute panel URL (no notification id). */
39
+ panelUrl: string | null
40
+ /** @deprecated Email-specific. Absolute deep link to the notification in the panel. */
41
+ panelLink: string | null
42
+ /** @deprecated Email-specific. Pre-resolved absolute action hyperlinks for the email template. */
43
+ actionLinks: Array<{ id: string; label: string; href: string }>
44
+ }
45
+
46
+ /**
47
+ * Full delivery context handed to `strategy.deliver`. Kept as the flat intersection of the
48
+ * channel-agnostic core and the email extras so existing strategies compile unchanged; the split
49
+ * documents which fields are channel-neutral vs. email-only (see `EmailDeliveryExtras`).
50
+ */
51
+ export type NotificationDeliveryContext = NotificationDeliveryContextCore & EmailDeliveryExtras
52
+
28
53
  export type NotificationDeliveryStrategy = {
29
54
  id: string
30
55
  label?: string
31
56
  defaultEnabled?: boolean
57
+ /**
58
+ * Optional technical-deliverability gate evaluated by the dispatcher before `deliver`. Return
59
+ * `false` to skip this channel for the current context (e.g. email disabled by tenant config).
60
+ * This is NOT for per-user opt-out — that is enforced once at create time via `shouldDeliver`.
61
+ */
62
+ isConfigured?: (ctx: NotificationDeliveryContext) => boolean | Promise<boolean>
63
+ /**
64
+ * Optional per-notification applicability check. Return `false` to skip this strategy entirely for
65
+ * the given notification (e.g. a channel that only handles a certain notification shape).
66
+ */
67
+ supports?: (notification: Notification) => boolean
32
68
  deliver: (ctx: NotificationDeliveryContext) => Promise<void> | void
33
69
  }
34
70
 
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Default grouping key for a notification type when the declaring module does not
3
+ * provide an explicit `category`. Uses the prefix before the first dot (e.g.
4
+ * `sales.order.created` → `sales`), or the whole id when there is no dot.
5
+ *
6
+ * This intentionally has NO knowledge of specific notification types — modules
7
+ * that want a non-default grouping declare `category` on their notification type.
8
+ *
9
+ * Applied once, in `syncNotificationTypes`, so the mirrored row always carries a
10
+ * resolved category and read paths never need a fallback branch.
11
+ */
12
+ export function deriveCategory(type: string): string {
13
+ const dot = type.indexOf('.')
14
+ return dot === -1 ? type : type.slice(0, dot)
15
+ }
@@ -0,0 +1,59 @@
1
+ import type { NotificationChannelDefinition } from '@open-mercato/shared/modules/notifications/types'
2
+
3
+ const registry = new Map<string, NotificationChannelDefinition>()
4
+
5
+ export type RegisterNotificationChannelsOptions = {
6
+ replace?: boolean
7
+ }
8
+
9
+ /**
10
+ * In-memory catalogue of module-contributed delivery channels. Fed at app bootstrap from the
11
+ * generated aggregate (see `notifications/generators.ts` → `channelsPlugin`), mirroring the
12
+ * notification-type registry. Provides labels/metadata for the preferences UI and the
13
+ * `GET /api/notifications/channels` endpoint; the delivery-strategy registry remains the
14
+ * behavior layer (both are keyed by the same channel id).
15
+ */
16
+ export function registerNotificationChannels(
17
+ channels: NotificationChannelDefinition[],
18
+ options: RegisterNotificationChannelsOptions = {},
19
+ ): void {
20
+ if (options.replace) registry.clear()
21
+ for (const channel of channels) {
22
+ if (!channel?.id) continue
23
+ registry.set(channel.id, channel)
24
+ }
25
+ }
26
+
27
+ export function getNotificationChannel(id: string): NotificationChannelDefinition | undefined {
28
+ return registry.get(id)
29
+ }
30
+
31
+ export function getNotificationChannels(): NotificationChannelDefinition[] {
32
+ return Array.from(registry.values()).sort((a, b) => {
33
+ const orderA = a.order ?? Number.MAX_SAFE_INTEGER
34
+ const orderB = b.order ?? Number.MAX_SAFE_INTEGER
35
+ if (orderA !== orderB) return orderA - orderB
36
+ return a.id.localeCompare(b.id)
37
+ })
38
+ }
39
+
40
+ export type NotificationChannelEntry = {
41
+ moduleId: string
42
+ channels: unknown[]
43
+ }
44
+
45
+ /**
46
+ * Bootstrap-time registration of module-contributed channels, fed from the generated
47
+ * `notification-channels.generated.ts` aggregate via `runBootstrapRegistrations()`. Idempotent:
48
+ * a channel whose `id` is already registered is skipped, so a repeated bootstrap (HMR / test
49
+ * re-import) never double-registers.
50
+ */
51
+ export function registerNotificationChannelEntries(entries: NotificationChannelEntry[]): void {
52
+ for (const entry of entries) {
53
+ for (const channel of entry.channels ?? []) {
54
+ const candidate = channel as NotificationChannelDefinition
55
+ if (!candidate?.id || registry.has(candidate.id)) continue
56
+ registry.set(candidate.id, candidate)
57
+ }
58
+ }
59
+ }