@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,111 @@
1
+ import { OptionalProps } from '@mikro-orm/core'
2
+ import { Entity, Index, PrimaryKey, Property } from '@mikro-orm/decorators/legacy'
3
+
4
+ export type PushDeliveryStatus = 'pending' | 'sending' | 'sent' | 'failed' | 'skipped' | 'expired'
5
+
6
+ /**
7
+ * Append-only delivery log for a single push notification attempt against one device.
8
+ *
9
+ * One row per (notification, device). The strategy inserts rows `pending`; the `send-push` worker
10
+ * atomically claims a row (`pending` → `sending`, so a redelivered job is processed once) and then
11
+ * transitions it to `sent`/`failed`/`skipped`, or `expired` once retries are exhausted. This is a
12
+ * background-job/log row, so it is intentionally EXEMPT from optimistic locking
13
+ * (status transitions are server-driven, never concurrently user-edited) and is
14
+ * NOT added to the curated `optimistic-lock-editable-entities` list.
15
+ *
16
+ * `push_token` is a secret: the full token is never persisted here — only
17
+ * `token_snapshot` (last 8 chars, for debugging across token rotation) plus the
18
+ * `provider` snapshot so the audit trail survives token rotation and device deletion.
19
+ */
20
+ @Entity({ tableName: 'push_notification_deliveries' })
21
+ @Index({ name: 'push_notification_deliveries_tenant_status_idx', properties: ['tenantId', 'status', 'createdAt'] })
22
+ @Index({ name: 'push_notification_deliveries_notification_idx', properties: ['notificationId'] })
23
+ // Idempotency guard for the fan-out: the `push` strategy runs inside the at-least-once persistent
24
+ // `notifications:deliver` subscriber, so a redelivered event would otherwise insert a second set of
25
+ // rows for the same (notification, device) → a duplicate push. A partial unique index (only where
26
+ // notification_id is set — direct/silent pushes without a notification are out of scope) lets the
27
+ // strategy insert-on-conflict-do-nothing, making a re-run a no-op.
28
+ @Index({
29
+ name: 'push_notification_deliveries_notif_device_unique',
30
+ expression:
31
+ 'create unique index "push_notification_deliveries_notif_device_unique" on "push_notification_deliveries" ("notification_id", "user_device_id") where "notification_id" is not null',
32
+ })
33
+ export class PushNotificationDelivery {
34
+ [OptionalProps]?:
35
+ | 'organizationId'
36
+ | 'notificationId'
37
+ | 'status'
38
+ | 'attempts'
39
+ | 'lastError'
40
+ | 'providerResponse'
41
+ | 'silent'
42
+ | 'createdAt'
43
+ | 'sentAt'
44
+ | 'nextRetryAt'
45
+ | 'updatedAt'
46
+
47
+ @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
48
+ id!: string
49
+
50
+ @Property({ name: 'tenant_id', type: 'uuid' })
51
+ tenantId!: string
52
+
53
+ @Property({ name: 'organization_id', type: 'uuid', nullable: true })
54
+ organizationId?: string | null
55
+
56
+ // Soft FK -> notifications.notifications (nullable: a push can be dispatched without an in-app row).
57
+ @Property({ name: 'notification_id', type: 'uuid', nullable: true })
58
+ notificationId?: string | null
59
+
60
+ @Property({ name: 'notification_type_id', type: 'text' })
61
+ notificationTypeId!: string
62
+
63
+ // Soft FK -> devices.user_devices (link declared in data/extensions.ts).
64
+ @Property({ name: 'user_device_id', type: 'uuid' })
65
+ userDeviceId!: string
66
+
67
+ @Property({ name: 'user_id', type: 'uuid' })
68
+ userId!: string
69
+
70
+ // Snapshot of the push CommunicationChannel providerKey used at send time.
71
+ @Property({ name: 'provider', type: 'text' })
72
+ provider!: string
73
+
74
+ // Last 8 chars of the device push token only — never the full secret.
75
+ @Property({ name: 'token_snapshot', type: 'text' })
76
+ tokenSnapshot!: string
77
+
78
+ // Snapshot of whether this was a silent / content-available wake-up (derived from the
79
+ // notification type's `silent` flag at fan-out time) so the log distinguishes silent deliveries.
80
+ @Property({ name: 'silent', type: 'boolean', default: false })
81
+ silent: boolean = false
82
+
83
+ @Property({ name: 'status', type: 'text', default: 'pending' })
84
+ status: PushDeliveryStatus = 'pending'
85
+
86
+ @Property({ name: 'attempts', type: 'int', default: 0 })
87
+ attempts: number = 0
88
+
89
+ @Property({ name: 'last_error', type: 'text', nullable: true })
90
+ lastError?: string | null
91
+
92
+ @Property({ name: 'payload', type: 'json' })
93
+ payload!: Record<string, unknown>
94
+
95
+ @Property({ name: 'provider_response', type: 'json', nullable: true })
96
+ providerResponse?: Record<string, unknown> | null
97
+
98
+ @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })
99
+ createdAt: Date = new Date()
100
+
101
+ @Property({ name: 'sent_at', type: Date, nullable: true })
102
+ sentAt?: Date | null
103
+
104
+ // Set when a retryable failure re-enqueues the job (observability for the admin delivery log);
105
+ // cleared once the delivery reaches a terminal state.
106
+ @Property({ name: 'next_retry_at', type: Date, nullable: true })
107
+ nextRetryAt?: Date | null
108
+
109
+ @Property({ name: 'updated_at', type: Date, onCreate: () => new Date(), onUpdate: () => new Date() })
110
+ updatedAt: Date = new Date()
111
+ }
@@ -0,0 +1,29 @@
1
+ import type { EntityExtension } from '@open-mercato/shared/modules/entities'
2
+
3
+ /**
4
+ * Cross-module entity links declared by the push_notifications module.
5
+ *
6
+ * Per root AGENTS.md, modules do NOT form direct ORM relationships across
7
+ * boundaries. `PushNotificationDelivery` carries plain UUID columns that
8
+ * reference rows owned by other modules; the links are declared here so the
9
+ * data engine + UI tooling can traverse them.
10
+ */
11
+ const entityExtensions: EntityExtension[] = [
12
+ {
13
+ base: 'push_notifications:push_notification_delivery',
14
+ extension: 'devices:user_device',
15
+ join: { baseKey: 'user_device_id', extensionKey: 'id' },
16
+ cardinality: 'many-to-one',
17
+ description: 'Links a push delivery row to the target user device it was sent to',
18
+ },
19
+ {
20
+ base: 'push_notifications:push_notification_delivery',
21
+ extension: 'notifications:notification',
22
+ join: { baseKey: 'notification_id', extensionKey: 'id' },
23
+ cardinality: 'many-to-one',
24
+ description: 'Links a push delivery row to the in-app notification that triggered it',
25
+ },
26
+ ]
27
+
28
+ export const extensions = entityExtensions
29
+ export default entityExtensions
@@ -0,0 +1,102 @@
1
+ import { z } from 'zod'
2
+ import { pushOptionsSchema } from '@open-mercato/core/modules/notifications/data/validators'
3
+
4
+ export const PUSH_DELIVERY_STATUSES = ['pending', 'sending', 'sent', 'failed', 'skipped', 'expired'] as const
5
+
6
+ // A `created_at` range bound: an ISO-8601 date (`2026-07-01`) or datetime (`2026-07-01T00:00:00Z`).
7
+ // Validated here so a malformed value fails with a 400 instead of reaching the query engine / Postgres.
8
+ const rangeDateFilter = z.union([z.string().datetime({ offset: true }), z.string().date()])
9
+
10
+ // POST /api/push_notifications/custom-send — admin composes a one-off visible push to a single user.
11
+ // title/body are literal free text (not i18n keys). data/pushOptions reuse the notifications contract.
12
+ export const customSendSchema = z
13
+ .object({
14
+ recipientUserId: z.string().uuid(),
15
+ // Optional: target one of the recipient's devices; omit to send to all their devices.
16
+ deviceId: z.string().uuid().optional(),
17
+ title: z.string().trim().min(1).max(500),
18
+ body: z.string().trim().max(2000).nullish(),
19
+ data: z.record(z.string(), z.string()).optional(),
20
+ pushOptions: pushOptionsSchema.optional(),
21
+ // When true, deliver a silent data-only wake-up instead of a visible banner.
22
+ silent: z.boolean().optional(),
23
+ })
24
+ .strict()
25
+ export type CustomSendInput = z.infer<typeof customSendSchema>
26
+
27
+ // Machine-readable warning surfaced when a well-formed send resolved no deliverable device in scope
28
+ // (no push channel configured, no in-scope devices, or none whose provider matches an active channel).
29
+ // The caller gets `enqueued: 0` plus this code + a human `message` instead of a misleading silent success.
30
+ export const CUSTOM_SEND_NO_DEVICES_WARNING = 'no_matching_devices_in_scope'
31
+
32
+ export const customSendResponseSchema = z.object({
33
+ enqueued: z.number(),
34
+ warning: z.literal(CUSTOM_SEND_NO_DEVICES_WARNING).optional(),
35
+ message: z.string().optional(),
36
+ })
37
+
38
+ // Read-only delivery-log list contract (admin observability). No full push token is ever exposed —
39
+ // only `token_snapshot` (last 8 chars) and the `provider` snapshot.
40
+ export const deliveryListSchema = z
41
+ .object({
42
+ page: z.coerce.number().min(1).default(1),
43
+ pageSize: z.coerce.number().min(1).max(100).default(50),
44
+ status: z.enum(PUSH_DELIVERY_STATUSES).optional(),
45
+ userId: z.string().uuid().optional(),
46
+ from: rangeDateFilter.optional(),
47
+ to: rangeDateFilter.optional(),
48
+ sortField: z.string().optional(),
49
+ sortDir: z.enum(['asc', 'desc']).optional(),
50
+ })
51
+ .passthrough()
52
+
53
+ export const deliveryListFields: string[] = [
54
+ 'id',
55
+ 'tenant_id',
56
+ 'organization_id',
57
+ 'notification_id',
58
+ 'notification_type_id',
59
+ 'user_device_id',
60
+ 'user_id',
61
+ 'provider',
62
+ 'token_snapshot',
63
+ 'status',
64
+ 'attempts',
65
+ 'last_error',
66
+ 'created_at',
67
+ 'sent_at',
68
+ 'next_retry_at',
69
+ 'updated_at',
70
+ ]
71
+
72
+ export const deliveryListSortFieldMap: Record<string, string> = {
73
+ createdAt: 'created_at',
74
+ sentAt: 'sent_at',
75
+ updatedAt: 'updated_at',
76
+ status: 'status',
77
+ }
78
+
79
+ export const deliveryListItemSchema = z.object({
80
+ id: z.string().uuid(),
81
+ tenant_id: z.string().uuid(),
82
+ organization_id: z.string().uuid().nullable().optional(),
83
+ notification_id: z.string().uuid().nullable().optional(),
84
+ notification_type_id: z.string(),
85
+ user_device_id: z.string().uuid(),
86
+ user_id: z.string().uuid(),
87
+ provider: z.string(),
88
+ token_snapshot: z.string(),
89
+ status: z.enum(PUSH_DELIVERY_STATUSES),
90
+ attempts: z.number(),
91
+ last_error: z.string().nullable().optional(),
92
+ created_at: z.string().nullable().optional(),
93
+ sent_at: z.string().nullable().optional(),
94
+ next_retry_at: z.string().nullable().optional(),
95
+ updated_at: z.string().nullable().optional(),
96
+ })
97
+
98
+ // Detail adds the JSON payload + provider response (still no full token).
99
+ export const deliveryDetailItemSchema = deliveryListItemSchema.extend({
100
+ payload: z.record(z.string(), z.unknown()).nullable().optional(),
101
+ provider_response: z.record(z.string(), z.unknown()).nullable().optional(),
102
+ })
@@ -0,0 +1,20 @@
1
+ import { asValue } from 'awilix'
2
+ import type { AppContainer } from '@open-mercato/shared/lib/di/container'
3
+ import { PushNotificationDelivery } from './data/entities'
4
+ import { ensurePushStubAdapterRegistered } from './lib/push-stub-adapter'
5
+ import { pushNotificationService } from './lib/send-custom-push'
6
+
7
+ export function register(container: AppContainer) {
8
+ // Test-only: register the network-free `push_stub` channel adapter when
9
+ // `OM_ENABLE_PUSH_STUB_ADAPTER` is set (no-op in production). Lets the integration harness drive
10
+ // the strategy → delivery-row → worker → sendMessage chain without a real provider. Mirrors the
11
+ // communication_channels test-seed adapter registration. See lib/push-stub-adapter.ts.
12
+ ensurePushStubAdapterRegistered()
13
+
14
+ container.register({
15
+ PushNotificationDelivery: asValue(PushNotificationDelivery),
16
+ // Stateless service backing the admin custom-send push (decoupled via DI). The caller passes
17
+ // its own scoped `resolve` in the call args.
18
+ pushNotificationService: asValue(pushNotificationService),
19
+ })
20
+ }
@@ -0,0 +1,21 @@
1
+ import { createModuleEvents } from '@open-mercato/shared/modules/events'
2
+
3
+ const events = [
4
+ { id: 'push_notifications.delivery.sent', label: 'Push Delivery Sent', entity: 'delivery', category: 'lifecycle' },
5
+ {
6
+ id: 'push_notifications.delivery.failed',
7
+ label: 'Push Delivery Failed',
8
+ entity: 'delivery',
9
+ category: 'lifecycle',
10
+ // Fires on every failed send attempt for a delivery, not only the terminal one. A retryable
11
+ // failure that will be re-attempted carries `willRetry: true`; the final give-up (and terminal
12
+ // errors like channel_unavailable / no_adapter) omit it. Subscribers that count "deliveries that
13
+ // ultimately failed" MUST filter to `willRetry !== true` to avoid double-counting retries.
14
+ description: 'A push delivery attempt failed. Carries willRetry:true when another attempt is scheduled.',
15
+ },
16
+ ] as const
17
+
18
+ export const eventsConfig = createModuleEvents({ moduleId: 'push_notifications', events })
19
+ export const emitPushNotificationsEvent = eventsConfig.emit
20
+ export type PushNotificationsEventId = typeof events[number]['id']
21
+ export default eventsConfig
@@ -0,0 +1,79 @@
1
+ {
2
+ "push_notifications.deliveries.columns.attempts": "Versuche",
3
+ "push_notifications.deliveries.columns.created": "Erstellt",
4
+ "push_notifications.deliveries.columns.provider": "Anbieter",
5
+ "push_notifications.deliveries.columns.sent": "Gesendet",
6
+ "push_notifications.deliveries.columns.status": "Status",
7
+ "push_notifications.deliveries.columns.type": "Typ",
8
+ "push_notifications.deliveries.columns.user": "Benutzer",
9
+ "push_notifications.deliveries.detail.device": "Gerät",
10
+ "push_notifications.deliveries.detail.lastError": "Letzter Fehler",
11
+ "push_notifications.deliveries.detail.loading": "Zustellung wird geladen…",
12
+ "push_notifications.deliveries.detail.nextRetry": "Nächster Versuch",
13
+ "push_notifications.deliveries.detail.pageTitle": "Push-Zustellung",
14
+ "push_notifications.deliveries.detail.payload": "Nutzdaten",
15
+ "push_notifications.deliveries.detail.providerResponse": "Anbieter-Antwort",
16
+ "push_notifications.deliveries.detail.tokenSnapshot": "Token (letzte 8)",
17
+ "push_notifications.deliveries.empty": "Noch keine Push-Zustellungen",
18
+ "push_notifications.deliveries.error.loadFailed": "Push-Zustellungen konnten nicht geladen werden",
19
+ "push_notifications.deliveries.filters.created": "Erstellt",
20
+ "push_notifications.deliveries.filters.from": "Von",
21
+ "push_notifications.deliveries.filters.to": "Bis",
22
+ "push_notifications.deliveries.noValue": "—",
23
+ "push_notifications.deliveries.pageTitle": "Push-Zustellungen",
24
+ "push_notifications.deliveries.status.expired": "Abgelaufen",
25
+ "push_notifications.deliveries.status.failed": "Fehlgeschlagen",
26
+ "push_notifications.deliveries.status.pending": "Ausstehend",
27
+ "push_notifications.deliveries.status.sending": "Wird gesendet",
28
+ "push_notifications.deliveries.status.sent": "Gesendet",
29
+ "push_notifications.deliveries.status.skipped": "Übersprungen",
30
+ "push_notifications.deliveries.title": "Push-Zustellungen",
31
+ "push_notifications.errors.forbidden": "Zugriff verweigert",
32
+ "push_notifications.errors.invalid_id": "Ungültige Zustellungs-ID",
33
+ "push_notifications.errors.invalid_payload": "Ungültige Anfrage",
34
+ "push_notifications.errors.not_found": "Zustellung nicht gefunden",
35
+ "push_notifications.errors.send_failed": "Push-Benachrichtigung konnte nicht gesendet werden",
36
+ "push_notifications.errors.server_error": "Etwas ist schief gelaufen",
37
+ "push_notifications.errors.unauthorized": "Nicht autorisiert",
38
+ "push_notifications.send.badge": "Badge-Zähler",
39
+ "push_notifications.send.body": "Text",
40
+ "push_notifications.send.channelId": "Android-Kanal-ID",
41
+ "push_notifications.send.data": "Daten (eigene Schlüssel/Werte)",
42
+ "push_notifications.send.dataAdd": "Feld hinzufügen",
43
+ "push_notifications.send.dataEmpty": "Noch keine eigenen Daten.",
44
+ "push_notifications.send.dataHint": "Wird in der Push-Nutzlast geliefert — deine App liest sie. Bei einem stillen Push ist dies die gesamte Nutzlast.",
45
+ "push_notifications.send.dataKey": "Schlüssel",
46
+ "push_notifications.send.dataRemove": "Feld entfernen",
47
+ "push_notifications.send.dataValue": "Wert",
48
+ "push_notifications.send.device": "Gerät",
49
+ "push_notifications.send.deviceAll": "Alle Geräte",
50
+ "push_notifications.send.deviceHint": "An dieses bestimmte Gerät oder an alle Geräte des Empfängers senden.",
51
+ "push_notifications.send.deviceNone": "Dieser Empfänger hat keine push-fähigen Geräte",
52
+ "push_notifications.send.deviceSelectUserFirst": "Zuerst einen Empfänger auswählen",
53
+ "push_notifications.send.image": "Bild-URL",
54
+ "push_notifications.send.message": "Nachricht",
55
+ "push_notifications.send.mode": "Zustellung",
56
+ "push_notifications.send.modeHint": "Sichtbar zeigt ein Banner; still ist ein reines Daten-Update im Hintergrund.",
57
+ "push_notifications.send.modeSilent": "Still (Hintergrund)",
58
+ "push_notifications.send.modeVisible": "Sichtbar",
59
+ "push_notifications.send.options": "Push-Optionen",
60
+ "push_notifications.send.optionsHint": "Optionale Anbieter-Anpassung. Ton/Badge/Bild gelten für sichtbare Pushes.",
61
+ "push_notifications.send.pageTitle": "Push senden",
62
+ "push_notifications.send.priority": "Priorität",
63
+ "push_notifications.send.priorityDefault": "Standard",
64
+ "push_notifications.send.priorityHigh": "Hoch",
65
+ "push_notifications.send.priorityNormal": "Normal",
66
+ "push_notifications.send.sound": "Ton",
67
+ "push_notifications.send.submit": "Push senden",
68
+ "push_notifications.send.success": "Push zum Versand eingereiht",
69
+ "push_notifications.send.title": "Titel",
70
+ "push_notifications.send.userId": "Empfänger",
71
+ "push_notifications.send.userIdHint": "Nach Name oder E-Mail suchen — die Geräte dieses Benutzers erhalten den Push.",
72
+ "push_notifications.types.admin_custom_message.body": "Sie haben eine neue Nachricht.",
73
+ "push_notifications.types.admin_custom_message.label": "Admin-Nachricht",
74
+ "push_notifications.types.admin_custom_message.title": "Admin-Nachricht",
75
+ "push_notifications.types.admin_custom_silent.body": "Hintergrund-Update.",
76
+ "push_notifications.types.admin_custom_silent.label": "Stille Admin-Nachricht",
77
+ "push_notifications.types.admin_custom_silent.title": "Stille Nachricht",
78
+ "push_notifications.warnings.no_matching_devices_in_scope": "Kein push-fähiges Gerät dieses Empfängers passte zum ausgewählten Bereich, daher wurde nichts gesendet."
79
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "push_notifications.deliveries.columns.attempts": "Attempts",
3
+ "push_notifications.deliveries.columns.created": "Created",
4
+ "push_notifications.deliveries.columns.provider": "Provider",
5
+ "push_notifications.deliveries.columns.sent": "Sent",
6
+ "push_notifications.deliveries.columns.status": "Status",
7
+ "push_notifications.deliveries.columns.type": "Type",
8
+ "push_notifications.deliveries.columns.user": "User",
9
+ "push_notifications.deliveries.detail.device": "Device",
10
+ "push_notifications.deliveries.detail.lastError": "Last error",
11
+ "push_notifications.deliveries.detail.loading": "Loading delivery…",
12
+ "push_notifications.deliveries.detail.nextRetry": "Next retry",
13
+ "push_notifications.deliveries.detail.pageTitle": "Push delivery",
14
+ "push_notifications.deliveries.detail.payload": "Payload",
15
+ "push_notifications.deliveries.detail.providerResponse": "Provider response",
16
+ "push_notifications.deliveries.detail.tokenSnapshot": "Token (last 8)",
17
+ "push_notifications.deliveries.empty": "No push deliveries yet",
18
+ "push_notifications.deliveries.error.loadFailed": "Failed to load push deliveries",
19
+ "push_notifications.deliveries.filters.created": "Created",
20
+ "push_notifications.deliveries.filters.from": "From",
21
+ "push_notifications.deliveries.filters.to": "To",
22
+ "push_notifications.deliveries.noValue": "—",
23
+ "push_notifications.deliveries.pageTitle": "Push Deliveries",
24
+ "push_notifications.deliveries.status.expired": "Expired",
25
+ "push_notifications.deliveries.status.failed": "Failed",
26
+ "push_notifications.deliveries.status.pending": "Pending",
27
+ "push_notifications.deliveries.status.sending": "Sending",
28
+ "push_notifications.deliveries.status.sent": "Sent",
29
+ "push_notifications.deliveries.status.skipped": "Skipped",
30
+ "push_notifications.deliveries.title": "Push deliveries",
31
+ "push_notifications.errors.forbidden": "Access denied",
32
+ "push_notifications.errors.invalid_id": "Invalid delivery id",
33
+ "push_notifications.errors.invalid_payload": "Invalid request",
34
+ "push_notifications.errors.not_found": "Delivery not found",
35
+ "push_notifications.errors.send_failed": "Failed to send push notification",
36
+ "push_notifications.errors.server_error": "Something went wrong",
37
+ "push_notifications.errors.unauthorized": "Unauthorized",
38
+ "push_notifications.send.badge": "Badge count",
39
+ "push_notifications.send.body": "Body",
40
+ "push_notifications.send.channelId": "Android channel ID",
41
+ "push_notifications.send.data": "Data (custom key/values)",
42
+ "push_notifications.send.dataAdd": "Add field",
43
+ "push_notifications.send.dataEmpty": "No custom data yet.",
44
+ "push_notifications.send.dataHint": "Delivered inside the push payload — your app reads these. For a silent push this is the whole payload.",
45
+ "push_notifications.send.dataKey": "key",
46
+ "push_notifications.send.dataRemove": "Remove field",
47
+ "push_notifications.send.dataValue": "value",
48
+ "push_notifications.send.device": "Device",
49
+ "push_notifications.send.deviceAll": "All devices",
50
+ "push_notifications.send.deviceHint": "Send to this specific device, or all of the recipient's devices.",
51
+ "push_notifications.send.deviceNone": "This recipient has no push-capable devices",
52
+ "push_notifications.send.deviceSelectUserFirst": "Select a recipient first",
53
+ "push_notifications.send.image": "Image URL",
54
+ "push_notifications.send.message": "Message",
55
+ "push_notifications.send.mode": "Delivery",
56
+ "push_notifications.send.modeHint": "Visible shows a banner; silent is a data-only background wake-up.",
57
+ "push_notifications.send.modeSilent": "Silent (background)",
58
+ "push_notifications.send.modeVisible": "Visible",
59
+ "push_notifications.send.options": "Push options",
60
+ "push_notifications.send.optionsHint": "Optional per-provider customization. Sound/badge/image apply to visible pushes.",
61
+ "push_notifications.send.pageTitle": "Send Push",
62
+ "push_notifications.send.priority": "Priority",
63
+ "push_notifications.send.priorityDefault": "Default",
64
+ "push_notifications.send.priorityHigh": "High",
65
+ "push_notifications.send.priorityNormal": "Normal",
66
+ "push_notifications.send.sound": "Sound",
67
+ "push_notifications.send.submit": "Send push",
68
+ "push_notifications.send.success": "Push queued for delivery",
69
+ "push_notifications.send.title": "Title",
70
+ "push_notifications.send.userId": "Recipient",
71
+ "push_notifications.send.userIdHint": "Search by name or email — their devices receive this push.",
72
+ "push_notifications.types.admin_custom_message.body": "You have a new message.",
73
+ "push_notifications.types.admin_custom_message.label": "Admin message",
74
+ "push_notifications.types.admin_custom_message.title": "Admin message",
75
+ "push_notifications.types.admin_custom_silent.body": "Background update.",
76
+ "push_notifications.types.admin_custom_silent.label": "Admin silent message",
77
+ "push_notifications.types.admin_custom_silent.title": "Silent message",
78
+ "push_notifications.warnings.no_matching_devices_in_scope": "No push-capable devices matched this recipient in the selected scope, so nothing was sent."
79
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "push_notifications.deliveries.columns.attempts": "Intentos",
3
+ "push_notifications.deliveries.columns.created": "Creado",
4
+ "push_notifications.deliveries.columns.provider": "Proveedor",
5
+ "push_notifications.deliveries.columns.sent": "Enviado",
6
+ "push_notifications.deliveries.columns.status": "Estado",
7
+ "push_notifications.deliveries.columns.type": "Tipo",
8
+ "push_notifications.deliveries.columns.user": "Usuario",
9
+ "push_notifications.deliveries.detail.device": "Dispositivo",
10
+ "push_notifications.deliveries.detail.lastError": "Último error",
11
+ "push_notifications.deliveries.detail.loading": "Cargando envío…",
12
+ "push_notifications.deliveries.detail.nextRetry": "Próximo reintento",
13
+ "push_notifications.deliveries.detail.pageTitle": "Envío push",
14
+ "push_notifications.deliveries.detail.payload": "Carga útil",
15
+ "push_notifications.deliveries.detail.providerResponse": "Respuesta del proveedor",
16
+ "push_notifications.deliveries.detail.tokenSnapshot": "Token (últimos 8)",
17
+ "push_notifications.deliveries.empty": "Aún no hay envíos push",
18
+ "push_notifications.deliveries.error.loadFailed": "No se pudieron cargar los envíos push",
19
+ "push_notifications.deliveries.filters.created": "Creado",
20
+ "push_notifications.deliveries.filters.from": "Desde",
21
+ "push_notifications.deliveries.filters.to": "Hasta",
22
+ "push_notifications.deliveries.noValue": "—",
23
+ "push_notifications.deliveries.pageTitle": "Envíos push",
24
+ "push_notifications.deliveries.status.expired": "Expirado",
25
+ "push_notifications.deliveries.status.failed": "Fallido",
26
+ "push_notifications.deliveries.status.pending": "Pendiente",
27
+ "push_notifications.deliveries.status.sending": "Enviando",
28
+ "push_notifications.deliveries.status.sent": "Enviado",
29
+ "push_notifications.deliveries.status.skipped": "Omitido",
30
+ "push_notifications.deliveries.title": "Envíos push",
31
+ "push_notifications.errors.forbidden": "Acceso denegado",
32
+ "push_notifications.errors.invalid_id": "ID de envío no válido",
33
+ "push_notifications.errors.invalid_payload": "Solicitud no válida",
34
+ "push_notifications.errors.not_found": "Envío no encontrado",
35
+ "push_notifications.errors.send_failed": "No se pudo enviar la notificación push",
36
+ "push_notifications.errors.server_error": "Algo salió mal",
37
+ "push_notifications.errors.unauthorized": "No autorizado",
38
+ "push_notifications.send.badge": "Contador de insignia",
39
+ "push_notifications.send.body": "Cuerpo",
40
+ "push_notifications.send.channelId": "ID de canal Android",
41
+ "push_notifications.send.data": "Datos (clave/valor personalizados)",
42
+ "push_notifications.send.dataAdd": "Añadir campo",
43
+ "push_notifications.send.dataEmpty": "Aún no hay datos personalizados.",
44
+ "push_notifications.send.dataHint": "Se entrega dentro del payload del push — tu app los lee. Para un push silencioso es todo el payload.",
45
+ "push_notifications.send.dataKey": "clave",
46
+ "push_notifications.send.dataRemove": "Eliminar campo",
47
+ "push_notifications.send.dataValue": "valor",
48
+ "push_notifications.send.device": "Dispositivo",
49
+ "push_notifications.send.deviceAll": "Todos los dispositivos",
50
+ "push_notifications.send.deviceHint": "Enviar a este dispositivo específico o a todos los dispositivos del destinatario.",
51
+ "push_notifications.send.deviceNone": "Este destinatario no tiene dispositivos compatibles con push",
52
+ "push_notifications.send.deviceSelectUserFirst": "Selecciona primero un destinatario",
53
+ "push_notifications.send.image": "URL de imagen",
54
+ "push_notifications.send.message": "Mensaje",
55
+ "push_notifications.send.mode": "Entrega",
56
+ "push_notifications.send.modeHint": "Visible muestra un banner; silencioso es una actualización de datos en segundo plano.",
57
+ "push_notifications.send.modeSilent": "Silencioso (segundo plano)",
58
+ "push_notifications.send.modeVisible": "Visible",
59
+ "push_notifications.send.options": "Opciones de push",
60
+ "push_notifications.send.optionsHint": "Personalización opcional por proveedor. Sonido/insignia/imagen aplican a pushes visibles.",
61
+ "push_notifications.send.pageTitle": "Enviar push",
62
+ "push_notifications.send.priority": "Prioridad",
63
+ "push_notifications.send.priorityDefault": "Predeterminado",
64
+ "push_notifications.send.priorityHigh": "Alta",
65
+ "push_notifications.send.priorityNormal": "Normal",
66
+ "push_notifications.send.sound": "Sonido",
67
+ "push_notifications.send.submit": "Enviar push",
68
+ "push_notifications.send.success": "Push en cola para envío",
69
+ "push_notifications.send.title": "Título",
70
+ "push_notifications.send.userId": "Destinatario",
71
+ "push_notifications.send.userIdHint": "Busca por nombre o correo — sus dispositivos reciben este push.",
72
+ "push_notifications.types.admin_custom_message.body": "Tienes un mensaje nuevo.",
73
+ "push_notifications.types.admin_custom_message.label": "Mensaje de administrador",
74
+ "push_notifications.types.admin_custom_message.title": "Mensaje de administrador",
75
+ "push_notifications.types.admin_custom_silent.body": "Actualización en segundo plano.",
76
+ "push_notifications.types.admin_custom_silent.label": "Mensaje silencioso de administrador",
77
+ "push_notifications.types.admin_custom_silent.title": "Mensaje silencioso",
78
+ "push_notifications.warnings.no_matching_devices_in_scope": "Ningún dispositivo con capacidad de push de este destinatario coincidió con el ámbito seleccionado, por lo que no se envió nada."
79
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "push_notifications.deliveries.columns.attempts": "시도 횟수",
3
+ "push_notifications.deliveries.columns.created": "생성됨",
4
+ "push_notifications.deliveries.columns.provider": "제공업체",
5
+ "push_notifications.deliveries.columns.sent": "전송됨",
6
+ "push_notifications.deliveries.columns.status": "상태",
7
+ "push_notifications.deliveries.columns.type": "유형",
8
+ "push_notifications.deliveries.columns.user": "사용자",
9
+ "push_notifications.deliveries.detail.device": "기기",
10
+ "push_notifications.deliveries.detail.lastError": "마지막 오류",
11
+ "push_notifications.deliveries.detail.loading": "전송 내역을 불러오는 중…",
12
+ "push_notifications.deliveries.detail.nextRetry": "다음 재시도",
13
+ "push_notifications.deliveries.detail.pageTitle": "푸시 전송",
14
+ "push_notifications.deliveries.detail.payload": "페이로드",
15
+ "push_notifications.deliveries.detail.providerResponse": "제공자 응답",
16
+ "push_notifications.deliveries.detail.tokenSnapshot": "토큰 (마지막 8자리)",
17
+ "push_notifications.deliveries.empty": "아직 푸시 전송 내역이 없습니다",
18
+ "push_notifications.deliveries.error.loadFailed": "푸시 전송 내역을 불러오지 못했습니다",
19
+ "push_notifications.deliveries.filters.created": "생성됨",
20
+ "push_notifications.deliveries.filters.from": "시작일",
21
+ "push_notifications.deliveries.filters.to": "종료일",
22
+ "push_notifications.deliveries.noValue": "—",
23
+ "push_notifications.deliveries.pageTitle": "푸시 전송 내역",
24
+ "push_notifications.deliveries.status.expired": "만료됨",
25
+ "push_notifications.deliveries.status.failed": "실패",
26
+ "push_notifications.deliveries.status.pending": "대기 중",
27
+ "push_notifications.deliveries.status.sending": "전송 중",
28
+ "push_notifications.deliveries.status.sent": "전송됨",
29
+ "push_notifications.deliveries.status.skipped": "건너뜀",
30
+ "push_notifications.deliveries.title": "푸시 전송 내역",
31
+ "push_notifications.errors.forbidden": "접근이 거부되었습니다",
32
+ "push_notifications.errors.invalid_id": "잘못된 전송 ID입니다",
33
+ "push_notifications.errors.invalid_payload": "잘못된 요청입니다",
34
+ "push_notifications.errors.not_found": "전송 내역을 찾을 수 없습니다",
35
+ "push_notifications.errors.send_failed": "푸시 알림을 전송하지 못했습니다",
36
+ "push_notifications.errors.server_error": "문제가 발생했습니다",
37
+ "push_notifications.errors.unauthorized": "권한이 없습니다",
38
+ "push_notifications.send.badge": "배지 숫자",
39
+ "push_notifications.send.body": "본문",
40
+ "push_notifications.send.channelId": "Android 채널 ID",
41
+ "push_notifications.send.data": "데이터 (사용자 지정 키/값)",
42
+ "push_notifications.send.dataAdd": "필드 추가",
43
+ "push_notifications.send.dataEmpty": "아직 사용자 지정 데이터가 없습니다.",
44
+ "push_notifications.send.dataHint": "푸시 페이로드에 담겨 전달되며 앱에서 이 값을 읽습니다. 무음 푸시에서는 이 데이터가 페이로드 전체가 됩니다.",
45
+ "push_notifications.send.dataKey": "키",
46
+ "push_notifications.send.dataRemove": "필드 삭제",
47
+ "push_notifications.send.dataValue": "값",
48
+ "push_notifications.send.device": "기기",
49
+ "push_notifications.send.deviceAll": "모든 기기",
50
+ "push_notifications.send.deviceHint": "이 특정 기기로 보내거나, 수신자의 모든 기기로 보냅니다.",
51
+ "push_notifications.send.deviceNone": "이 수신자에게는 푸시를 받을 수 있는 기기가 없습니다",
52
+ "push_notifications.send.deviceSelectUserFirst": "먼저 수신자를 선택하세요",
53
+ "push_notifications.send.image": "이미지 URL",
54
+ "push_notifications.send.message": "메시지",
55
+ "push_notifications.send.mode": "전송 방식",
56
+ "push_notifications.send.modeHint": "표시 푸시는 배너를 보여 주고, 무음 푸시는 데이터만 전달해 백그라운드에서 앱을 깨웁니다.",
57
+ "push_notifications.send.modeSilent": "무음 (백그라운드)",
58
+ "push_notifications.send.modeVisible": "표시",
59
+ "push_notifications.send.options": "푸시 옵션",
60
+ "push_notifications.send.optionsHint": "제공자별 선택 설정입니다. 소리/배지/이미지는 표시 푸시에만 적용됩니다.",
61
+ "push_notifications.send.pageTitle": "푸시 보내기",
62
+ "push_notifications.send.priority": "우선순위",
63
+ "push_notifications.send.priorityDefault": "기본값",
64
+ "push_notifications.send.priorityHigh": "높음",
65
+ "push_notifications.send.priorityNormal": "보통",
66
+ "push_notifications.send.sound": "소리",
67
+ "push_notifications.send.submit": "푸시 보내기",
68
+ "push_notifications.send.success": "푸시가 전송 대기열에 추가되었습니다",
69
+ "push_notifications.send.title": "제목",
70
+ "push_notifications.send.userId": "수신자",
71
+ "push_notifications.send.userIdHint": "이름 또는 이메일로 검색하세요 — 해당 사용자의 기기로 이 푸시가 전송됩니다.",
72
+ "push_notifications.types.admin_custom_message.body": "새 메시지가 도착했습니다.",
73
+ "push_notifications.types.admin_custom_message.label": "관리자 메시지",
74
+ "push_notifications.types.admin_custom_message.title": "관리자 메시지",
75
+ "push_notifications.types.admin_custom_silent.body": "백그라운드 업데이트입니다.",
76
+ "push_notifications.types.admin_custom_silent.label": "관리자 무음 메시지",
77
+ "push_notifications.types.admin_custom_silent.title": "무음 메시지",
78
+ "push_notifications.warnings.no_matching_devices_in_scope": "선택한 범위에서 이 수신자와 일치하는 푸시 가능 기기가 없어 아무것도 전송되지 않았습니다."
79
+ }