@open-mercato/core 0.4.2-canary-07dbc98202 → 0.4.2-canary-11e19dfb84

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 (235) hide show
  1. package/dist/generated/entities.ids.generated.js +59 -63
  2. package/dist/generated/entities.ids.generated.js.map +2 -2
  3. package/dist/generated/entity-fields-registry.js +0 -2
  4. package/dist/generated/entity-fields-registry.js.map +2 -2
  5. package/dist/modules/api_docs/frontend/docs/api/page.js +2 -3
  6. package/dist/modules/api_docs/frontend/docs/api/page.js.map +2 -2
  7. package/dist/modules/auth/api/admin/nav.js +3 -4
  8. package/dist/modules/auth/api/admin/nav.js.map +2 -2
  9. package/dist/modules/auth/api/reset/confirm.js +2 -25
  10. package/dist/modules/auth/api/reset/confirm.js.map +2 -2
  11. package/dist/modules/auth/api/reset.js +0 -23
  12. package/dist/modules/auth/api/reset.js.map +2 -2
  13. package/dist/modules/auth/api/sidebar/preferences/route.js +9 -14
  14. package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
  15. package/dist/modules/auth/commands/users.js +0 -55
  16. package/dist/modules/auth/commands/users.js.map +2 -2
  17. package/dist/modules/auth/lib/setup-app.js +0 -1
  18. package/dist/modules/auth/lib/setup-app.js.map +2 -2
  19. package/dist/modules/auth/services/authService.js +3 -3
  20. package/dist/modules/auth/services/authService.js.map +2 -2
  21. package/dist/modules/configs/cli.js +0 -6
  22. package/dist/modules/configs/cli.js.map +2 -2
  23. package/dist/modules/customers/commands/deals.js +0 -31
  24. package/dist/modules/customers/commands/deals.js.map +2 -2
  25. package/dist/modules/sales/commands/documents.js +0 -53
  26. package/dist/modules/sales/commands/documents.js.map +2 -2
  27. package/dist/modules/sales/commands/payments.js +0 -26
  28. package/dist/modules/sales/commands/payments.js.map +2 -2
  29. package/dist/modules/staff/commands/leave-requests.js +0 -79
  30. package/dist/modules/staff/commands/leave-requests.js.map +2 -2
  31. package/generated/entities.ids.generated.ts +59 -63
  32. package/generated/entity-fields-registry.ts +0 -2
  33. package/package.json +2 -2
  34. package/src/modules/api_docs/frontend/docs/api/page.tsx +2 -3
  35. package/src/modules/auth/api/admin/nav.ts +6 -10
  36. package/src/modules/auth/api/reset/confirm.ts +2 -25
  37. package/src/modules/auth/api/reset.ts +0 -23
  38. package/src/modules/auth/api/sidebar/preferences/route.ts +12 -21
  39. package/src/modules/auth/commands/users.ts +0 -68
  40. package/src/modules/auth/i18n/de.json +1 -29
  41. package/src/modules/auth/i18n/en.json +1 -29
  42. package/src/modules/auth/i18n/es.json +1 -29
  43. package/src/modules/auth/i18n/pl.json +1 -29
  44. package/src/modules/auth/lib/setup-app.ts +0 -1
  45. package/src/modules/auth/services/authService.ts +4 -4
  46. package/src/modules/business_rules/i18n/en.json +1 -3
  47. package/src/modules/catalog/i18n/en.json +1 -3
  48. package/src/modules/configs/cli.ts +0 -6
  49. package/src/modules/customers/commands/deals.ts +0 -39
  50. package/src/modules/customers/i18n/en.json +1 -5
  51. package/src/modules/sales/commands/documents.ts +0 -65
  52. package/src/modules/sales/commands/payments.ts +0 -33
  53. package/src/modules/sales/i18n/de.json +0 -20
  54. package/src/modules/sales/i18n/en.json +1 -25
  55. package/src/modules/sales/i18n/es.json +0 -20
  56. package/src/modules/sales/i18n/pl.json +0 -20
  57. package/src/modules/staff/commands/leave-requests.ts +0 -94
  58. package/src/modules/staff/i18n/de.json +0 -4
  59. package/src/modules/staff/i18n/en.json +1 -9
  60. package/src/modules/staff/i18n/es.json +0 -4
  61. package/src/modules/staff/i18n/pl.json +0 -4
  62. package/src/modules/workflows/i18n/en.json +1 -3
  63. package/dist/generated/entities/notification/index.js +0 -57
  64. package/dist/generated/entities/notification/index.js.map +0 -7
  65. package/dist/modules/auth/api/profile/route.js +0 -155
  66. package/dist/modules/auth/api/profile/route.js.map +0 -7
  67. package/dist/modules/auth/backend/auth/profile/page.js +0 -99
  68. package/dist/modules/auth/backend/auth/profile/page.js.map +0 -7
  69. package/dist/modules/auth/backend/auth/profile/page.meta.js +0 -12
  70. package/dist/modules/auth/backend/auth/profile/page.meta.js.map +0 -7
  71. package/dist/modules/auth/notifications.js +0 -112
  72. package/dist/modules/auth/notifications.js.map +0 -7
  73. package/dist/modules/business_rules/notifications.js +0 -28
  74. package/dist/modules/business_rules/notifications.js.map +0 -7
  75. package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js +0 -37
  76. package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js.map +0 -7
  77. package/dist/modules/catalog/notifications.js +0 -28
  78. package/dist/modules/catalog/notifications.js.map +0 -7
  79. package/dist/modules/catalog/subscribers/low-stock-notification.js +0 -38
  80. package/dist/modules/catalog/subscribers/low-stock-notification.js.map +0 -7
  81. package/dist/modules/customers/notifications.js +0 -48
  82. package/dist/modules/customers/notifications.js.map +0 -7
  83. package/dist/modules/notifications/acl.js +0 -11
  84. package/dist/modules/notifications/acl.js.map +0 -7
  85. package/dist/modules/notifications/api/[id]/action/route.js +0 -74
  86. package/dist/modules/notifications/api/[id]/action/route.js.map +0 -7
  87. package/dist/modules/notifications/api/[id]/dismiss/route.js +0 -15
  88. package/dist/modules/notifications/api/[id]/dismiss/route.js.map +0 -7
  89. package/dist/modules/notifications/api/[id]/read/route.js +0 -15
  90. package/dist/modules/notifications/api/[id]/read/route.js.map +0 -7
  91. package/dist/modules/notifications/api/[id]/restore/route.js +0 -53
  92. package/dist/modules/notifications/api/[id]/restore/route.js.map +0 -7
  93. package/dist/modules/notifications/api/batch/route.js +0 -17
  94. package/dist/modules/notifications/api/batch/route.js.map +0 -7
  95. package/dist/modules/notifications/api/feature/route.js +0 -17
  96. package/dist/modules/notifications/api/feature/route.js.map +0 -7
  97. package/dist/modules/notifications/api/mark-all-read/route.js +0 -35
  98. package/dist/modules/notifications/api/mark-all-read/route.js.map +0 -7
  99. package/dist/modules/notifications/api/openapi.js +0 -76
  100. package/dist/modules/notifications/api/openapi.js.map +0 -7
  101. package/dist/modules/notifications/api/role/route.js +0 -17
  102. package/dist/modules/notifications/api/role/route.js.map +0 -7
  103. package/dist/modules/notifications/api/route.js +0 -85
  104. package/dist/modules/notifications/api/route.js.map +0 -7
  105. package/dist/modules/notifications/api/settings/route.js +0 -155
  106. package/dist/modules/notifications/api/settings/route.js.map +0 -7
  107. package/dist/modules/notifications/api/unread-count/route.js +0 -38
  108. package/dist/modules/notifications/api/unread-count/route.js.map +0 -7
  109. package/dist/modules/notifications/backend/config/notifications/page.js +0 -10
  110. package/dist/modules/notifications/backend/config/notifications/page.js.map +0 -7
  111. package/dist/modules/notifications/backend/config/notifications/page.meta.js +0 -24
  112. package/dist/modules/notifications/backend/config/notifications/page.meta.js.map +0 -7
  113. package/dist/modules/notifications/cli.js +0 -16
  114. package/dist/modules/notifications/cli.js.map +0 -7
  115. package/dist/modules/notifications/data/entities.js +0 -112
  116. package/dist/modules/notifications/data/entities.js.map +0 -7
  117. package/dist/modules/notifications/data/validators.js +0 -94
  118. package/dist/modules/notifications/data/validators.js.map +0 -7
  119. package/dist/modules/notifications/di.js +0 -13
  120. package/dist/modules/notifications/di.js.map +0 -7
  121. package/dist/modules/notifications/emails/NotificationEmail.js +0 -58
  122. package/dist/modules/notifications/emails/NotificationEmail.js.map +0 -7
  123. package/dist/modules/notifications/frontend/NotificationInboxPageClient.js +0 -44
  124. package/dist/modules/notifications/frontend/NotificationInboxPageClient.js.map +0 -7
  125. package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js +0 -219
  126. package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js.map +0 -7
  127. package/dist/modules/notifications/index.js +0 -14
  128. package/dist/modules/notifications/index.js.map +0 -7
  129. package/dist/modules/notifications/lib/deliveryConfig.js +0 -105
  130. package/dist/modules/notifications/lib/deliveryConfig.js.map +0 -7
  131. package/dist/modules/notifications/lib/events.js +0 -12
  132. package/dist/modules/notifications/lib/events.js.map +0 -7
  133. package/dist/modules/notifications/lib/notificationBuilder.js +0 -66
  134. package/dist/modules/notifications/lib/notificationBuilder.js.map +0 -7
  135. package/dist/modules/notifications/lib/notificationFactory.js +0 -54
  136. package/dist/modules/notifications/lib/notificationFactory.js.map +0 -7
  137. package/dist/modules/notifications/lib/notificationMapper.js +0 -34
  138. package/dist/modules/notifications/lib/notificationMapper.js.map +0 -7
  139. package/dist/modules/notifications/lib/notificationRecipients.js +0 -35
  140. package/dist/modules/notifications/lib/notificationRecipients.js.map +0 -7
  141. package/dist/modules/notifications/lib/notificationService.js +0 -279
  142. package/dist/modules/notifications/lib/notificationService.js.map +0 -7
  143. package/dist/modules/notifications/lib/routeHelpers.js +0 -101
  144. package/dist/modules/notifications/lib/routeHelpers.js.map +0 -7
  145. package/dist/modules/notifications/lib/safeHref.js +0 -24
  146. package/dist/modules/notifications/lib/safeHref.js.map +0 -7
  147. package/dist/modules/notifications/migrations/Migration20260123000001.js +0 -70
  148. package/dist/modules/notifications/migrations/Migration20260123000001.js.map +0 -7
  149. package/dist/modules/notifications/migrations/Migration20260126150000.js +0 -37
  150. package/dist/modules/notifications/migrations/Migration20260126150000.js.map +0 -7
  151. package/dist/modules/notifications/subscribers/deliver-notification.js +0 -139
  152. package/dist/modules/notifications/subscribers/deliver-notification.js.map +0 -7
  153. package/dist/modules/notifications/workers/create-notification.worker.js +0 -70
  154. package/dist/modules/notifications/workers/create-notification.worker.js.map +0 -7
  155. package/dist/modules/sales/notifications.client.js +0 -51
  156. package/dist/modules/sales/notifications.client.js.map +0 -7
  157. package/dist/modules/sales/notifications.js +0 -88
  158. package/dist/modules/sales/notifications.js.map +0 -7
  159. package/dist/modules/sales/subscribers/quote-expiring-notification.js +0 -38
  160. package/dist/modules/sales/subscribers/quote-expiring-notification.js.map +0 -7
  161. package/dist/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.js +0 -137
  162. package/dist/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.js.map +0 -7
  163. package/dist/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.js +0 -137
  164. package/dist/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.js.map +0 -7
  165. package/dist/modules/sales/widgets/notifications/index.js +0 -7
  166. package/dist/modules/sales/widgets/notifications/index.js.map +0 -7
  167. package/dist/modules/sales/widgets/notifications/useSalesDocumentTotals.js +0 -60
  168. package/dist/modules/sales/widgets/notifications/useSalesDocumentTotals.js.map +0 -7
  169. package/dist/modules/staff/notifications.js +0 -75
  170. package/dist/modules/staff/notifications.js.map +0 -7
  171. package/dist/modules/workflows/notifications.js +0 -28
  172. package/dist/modules/workflows/notifications.js.map +0 -7
  173. package/dist/modules/workflows/subscribers/task-assigned-notification.js +0 -38
  174. package/dist/modules/workflows/subscribers/task-assigned-notification.js.map +0 -7
  175. package/generated/entities/notification/index.ts +0 -27
  176. package/src/modules/auth/api/profile/route.ts +0 -160
  177. package/src/modules/auth/backend/auth/profile/page.meta.ts +0 -8
  178. package/src/modules/auth/backend/auth/profile/page.tsx +0 -127
  179. package/src/modules/auth/notifications.ts +0 -109
  180. package/src/modules/business_rules/notifications.ts +0 -25
  181. package/src/modules/business_rules/subscribers/rule-execution-failed-notification.ts +0 -50
  182. package/src/modules/catalog/notifications.ts +0 -25
  183. package/src/modules/catalog/subscribers/low-stock-notification.ts +0 -52
  184. package/src/modules/customers/notifications.ts +0 -44
  185. package/src/modules/notifications/acl.ts +0 -7
  186. package/src/modules/notifications/api/[id]/action/route.ts +0 -75
  187. package/src/modules/notifications/api/[id]/dismiss/route.ts +0 -12
  188. package/src/modules/notifications/api/[id]/read/route.ts +0 -12
  189. package/src/modules/notifications/api/[id]/restore/route.ts +0 -53
  190. package/src/modules/notifications/api/batch/route.ts +0 -14
  191. package/src/modules/notifications/api/feature/route.ts +0 -14
  192. package/src/modules/notifications/api/mark-all-read/route.ts +0 -34
  193. package/src/modules/notifications/api/openapi.ts +0 -76
  194. package/src/modules/notifications/api/role/route.ts +0 -14
  195. package/src/modules/notifications/api/route.ts +0 -92
  196. package/src/modules/notifications/api/settings/route.ts +0 -157
  197. package/src/modules/notifications/api/unread-count/route.ts +0 -38
  198. package/src/modules/notifications/backend/config/notifications/page.meta.ts +0 -22
  199. package/src/modules/notifications/backend/config/notifications/page.tsx +0 -12
  200. package/src/modules/notifications/cli.ts +0 -18
  201. package/src/modules/notifications/data/entities.ts +0 -99
  202. package/src/modules/notifications/data/validators.ts +0 -110
  203. package/src/modules/notifications/di.ts +0 -11
  204. package/src/modules/notifications/emails/NotificationEmail.tsx +0 -98
  205. package/src/modules/notifications/frontend/NotificationInboxPageClient.tsx +0 -42
  206. package/src/modules/notifications/frontend/NotificationSettingsPageClient.tsx +0 -231
  207. package/src/modules/notifications/i18n/de.json +0 -50
  208. package/src/modules/notifications/i18n/en.json +0 -50
  209. package/src/modules/notifications/i18n/es.json +0 -50
  210. package/src/modules/notifications/i18n/pl.json +0 -50
  211. package/src/modules/notifications/index.ts +0 -12
  212. package/src/modules/notifications/lib/deliveryConfig.ts +0 -145
  213. package/src/modules/notifications/lib/events.ts +0 -48
  214. package/src/modules/notifications/lib/notificationBuilder.ts +0 -121
  215. package/src/modules/notifications/lib/notificationFactory.ts +0 -76
  216. package/src/modules/notifications/lib/notificationMapper.ts +0 -33
  217. package/src/modules/notifications/lib/notificationRecipients.ts +0 -83
  218. package/src/modules/notifications/lib/notificationService.ts +0 -414
  219. package/src/modules/notifications/lib/routeHelpers.ts +0 -151
  220. package/src/modules/notifications/lib/safeHref.ts +0 -29
  221. package/src/modules/notifications/migrations/.snapshot-open-mercato.json +0 -300
  222. package/src/modules/notifications/migrations/Migration20260123000001.ts +0 -73
  223. package/src/modules/notifications/migrations/Migration20260126150000.ts +0 -39
  224. package/src/modules/notifications/subscribers/deliver-notification.ts +0 -175
  225. package/src/modules/notifications/workers/create-notification.worker.ts +0 -122
  226. package/src/modules/sales/notifications.client.ts +0 -65
  227. package/src/modules/sales/notifications.ts +0 -82
  228. package/src/modules/sales/subscribers/quote-expiring-notification.ts +0 -53
  229. package/src/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.tsx +0 -156
  230. package/src/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.tsx +0 -156
  231. package/src/modules/sales/widgets/notifications/index.ts +0 -2
  232. package/src/modules/sales/widgets/notifications/useSalesDocumentTotals.ts +0 -81
  233. package/src/modules/staff/notifications.ts +0 -71
  234. package/src/modules/workflows/notifications.ts +0 -25
  235. package/src/modules/workflows/subscribers/task-assigned-notification.ts +0 -53
@@ -1,300 +0,0 @@
1
- {
2
- "namespaces": [
3
- "public"
4
- ],
5
- "name": "public",
6
- "tables": [
7
- {
8
- "columns": {
9
- "id": {
10
- "name": "id",
11
- "type": "uuid",
12
- "unsigned": false,
13
- "autoincrement": false,
14
- "primary": false,
15
- "nullable": false,
16
- "default": "gen_random_uuid()",
17
- "mappedType": "uuid"
18
- },
19
- "recipient_user_id": {
20
- "name": "recipient_user_id",
21
- "type": "uuid",
22
- "unsigned": false,
23
- "autoincrement": false,
24
- "primary": false,
25
- "nullable": false,
26
- "mappedType": "uuid"
27
- },
28
- "type": {
29
- "name": "type",
30
- "type": "text",
31
- "unsigned": false,
32
- "autoincrement": false,
33
- "primary": false,
34
- "nullable": false,
35
- "mappedType": "text"
36
- },
37
- "title": {
38
- "name": "title",
39
- "type": "text",
40
- "unsigned": false,
41
- "autoincrement": false,
42
- "primary": false,
43
- "nullable": false,
44
- "mappedType": "text"
45
- },
46
- "body": {
47
- "name": "body",
48
- "type": "text",
49
- "unsigned": false,
50
- "autoincrement": false,
51
- "primary": false,
52
- "nullable": true,
53
- "mappedType": "text"
54
- },
55
- "icon": {
56
- "name": "icon",
57
- "type": "text",
58
- "unsigned": false,
59
- "autoincrement": false,
60
- "primary": false,
61
- "nullable": true,
62
- "mappedType": "text"
63
- },
64
- "severity": {
65
- "name": "severity",
66
- "type": "text",
67
- "unsigned": false,
68
- "autoincrement": false,
69
- "primary": false,
70
- "nullable": false,
71
- "default": "'info'",
72
- "mappedType": "text"
73
- },
74
- "status": {
75
- "name": "status",
76
- "type": "text",
77
- "unsigned": false,
78
- "autoincrement": false,
79
- "primary": false,
80
- "nullable": false,
81
- "default": "'unread'",
82
- "mappedType": "text"
83
- },
84
- "action_data": {
85
- "name": "action_data",
86
- "type": "jsonb",
87
- "unsigned": false,
88
- "autoincrement": false,
89
- "primary": false,
90
- "nullable": true,
91
- "mappedType": "json"
92
- },
93
- "action_result": {
94
- "name": "action_result",
95
- "type": "jsonb",
96
- "unsigned": false,
97
- "autoincrement": false,
98
- "primary": false,
99
- "nullable": true,
100
- "mappedType": "json"
101
- },
102
- "action_taken": {
103
- "name": "action_taken",
104
- "type": "text",
105
- "unsigned": false,
106
- "autoincrement": false,
107
- "primary": false,
108
- "nullable": true,
109
- "mappedType": "text"
110
- },
111
- "source_module": {
112
- "name": "source_module",
113
- "type": "text",
114
- "unsigned": false,
115
- "autoincrement": false,
116
- "primary": false,
117
- "nullable": true,
118
- "mappedType": "text"
119
- },
120
- "source_entity_type": {
121
- "name": "source_entity_type",
122
- "type": "text",
123
- "unsigned": false,
124
- "autoincrement": false,
125
- "primary": false,
126
- "nullable": true,
127
- "mappedType": "text"
128
- },
129
- "source_entity_id": {
130
- "name": "source_entity_id",
131
- "type": "uuid",
132
- "unsigned": false,
133
- "autoincrement": false,
134
- "primary": false,
135
- "nullable": true,
136
- "mappedType": "uuid"
137
- },
138
- "link_href": {
139
- "name": "link_href",
140
- "type": "text",
141
- "unsigned": false,
142
- "autoincrement": false,
143
- "primary": false,
144
- "nullable": true,
145
- "mappedType": "text"
146
- },
147
- "group_key": {
148
- "name": "group_key",
149
- "type": "text",
150
- "unsigned": false,
151
- "autoincrement": false,
152
- "primary": false,
153
- "nullable": true,
154
- "mappedType": "text"
155
- },
156
- "created_at": {
157
- "name": "created_at",
158
- "type": "timestamptz",
159
- "unsigned": false,
160
- "autoincrement": false,
161
- "primary": false,
162
- "nullable": false,
163
- "length": 6,
164
- "mappedType": "datetime"
165
- },
166
- "read_at": {
167
- "name": "read_at",
168
- "type": "timestamptz",
169
- "unsigned": false,
170
- "autoincrement": false,
171
- "primary": false,
172
- "nullable": true,
173
- "length": 6,
174
- "mappedType": "datetime"
175
- },
176
- "actioned_at": {
177
- "name": "actioned_at",
178
- "type": "timestamptz",
179
- "unsigned": false,
180
- "autoincrement": false,
181
- "primary": false,
182
- "nullable": true,
183
- "length": 6,
184
- "mappedType": "datetime"
185
- },
186
- "dismissed_at": {
187
- "name": "dismissed_at",
188
- "type": "timestamptz",
189
- "unsigned": false,
190
- "autoincrement": false,
191
- "primary": false,
192
- "nullable": true,
193
- "length": 6,
194
- "mappedType": "datetime"
195
- },
196
- "expires_at": {
197
- "name": "expires_at",
198
- "type": "timestamptz",
199
- "unsigned": false,
200
- "autoincrement": false,
201
- "primary": false,
202
- "nullable": true,
203
- "length": 6,
204
- "mappedType": "datetime"
205
- },
206
- "tenant_id": {
207
- "name": "tenant_id",
208
- "type": "uuid",
209
- "unsigned": false,
210
- "autoincrement": false,
211
- "primary": false,
212
- "nullable": false,
213
- "mappedType": "uuid"
214
- },
215
- "organization_id": {
216
- "name": "organization_id",
217
- "type": "uuid",
218
- "unsigned": false,
219
- "autoincrement": false,
220
- "primary": false,
221
- "nullable": true,
222
- "mappedType": "uuid"
223
- }
224
- },
225
- "name": "notifications",
226
- "schema": "public",
227
- "indexes": [
228
- {
229
- "keyName": "notifications_group_idx",
230
- "columnNames": [
231
- "group_key",
232
- "recipient_user_id"
233
- ],
234
- "composite": true,
235
- "constraint": false,
236
- "primary": false,
237
- "unique": false
238
- },
239
- {
240
- "keyName": "notifications_expires_idx",
241
- "columnNames": [
242
- "expires_at"
243
- ],
244
- "composite": false,
245
- "constraint": false,
246
- "primary": false,
247
- "unique": false
248
- },
249
- {
250
- "keyName": "notifications_tenant_idx",
251
- "columnNames": [
252
- "tenant_id",
253
- "organization_id"
254
- ],
255
- "composite": true,
256
- "constraint": false,
257
- "primary": false,
258
- "unique": false
259
- },
260
- {
261
- "keyName": "notifications_source_idx",
262
- "columnNames": [
263
- "source_entity_type",
264
- "source_entity_id"
265
- ],
266
- "composite": true,
267
- "constraint": false,
268
- "primary": false,
269
- "unique": false
270
- },
271
- {
272
- "keyName": "notifications_recipient_status_idx",
273
- "columnNames": [
274
- "recipient_user_id",
275
- "status",
276
- "created_at"
277
- ],
278
- "composite": true,
279
- "constraint": false,
280
- "primary": false,
281
- "unique": false
282
- },
283
- {
284
- "keyName": "notifications_pkey",
285
- "columnNames": [
286
- "id"
287
- ],
288
- "composite": false,
289
- "constraint": true,
290
- "primary": true,
291
- "unique": true
292
- }
293
- ],
294
- "checks": [],
295
- "foreignKeys": {},
296
- "nativeEnums": {}
297
- }
298
- ],
299
- "nativeEnums": {}
300
- }
@@ -1,73 +0,0 @@
1
- import { Migration } from '@mikro-orm/migrations'
2
-
3
- export class Migration20260123000001 extends Migration {
4
- async up(): Promise<void> {
5
- this.addSql(`
6
- CREATE TABLE notifications (
7
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
8
-
9
- recipient_user_id UUID NOT NULL,
10
-
11
- type TEXT NOT NULL,
12
- title TEXT NOT NULL,
13
- body TEXT,
14
- icon TEXT,
15
- severity TEXT NOT NULL DEFAULT 'info',
16
-
17
- status TEXT NOT NULL DEFAULT 'unread',
18
-
19
- action_data JSONB,
20
- action_result JSONB,
21
- action_taken TEXT,
22
-
23
- source_module TEXT,
24
- source_entity_type TEXT,
25
- source_entity_id UUID,
26
- link_href TEXT,
27
-
28
- group_key TEXT,
29
-
30
- created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
31
- read_at TIMESTAMPTZ,
32
- actioned_at TIMESTAMPTZ,
33
- dismissed_at TIMESTAMPTZ,
34
- expires_at TIMESTAMPTZ,
35
-
36
- tenant_id UUID NOT NULL,
37
- organization_id UUID
38
- );
39
- `)
40
-
41
- this.addSql(`
42
- CREATE INDEX notifications_recipient_status_idx
43
- ON notifications(recipient_user_id, status, created_at DESC);
44
- `)
45
-
46
- this.addSql(`
47
- CREATE INDEX notifications_source_idx
48
- ON notifications(source_entity_type, source_entity_id)
49
- WHERE source_entity_id IS NOT NULL;
50
- `)
51
-
52
- this.addSql(`
53
- CREATE INDEX notifications_tenant_idx
54
- ON notifications(tenant_id, organization_id);
55
- `)
56
-
57
- this.addSql(`
58
- CREATE INDEX notifications_expires_idx
59
- ON notifications(expires_at)
60
- WHERE expires_at IS NOT NULL AND status NOT IN ('actioned', 'dismissed');
61
- `)
62
-
63
- this.addSql(`
64
- CREATE INDEX notifications_group_idx
65
- ON notifications(group_key, recipient_user_id)
66
- WHERE group_key IS NOT NULL;
67
- `)
68
- }
69
-
70
- async down(): Promise<void> {
71
- this.addSql('DROP TABLE IF EXISTS notifications CASCADE;')
72
- }
73
- }
@@ -1,39 +0,0 @@
1
- import { Migration } from '@mikro-orm/migrations'
2
-
3
- export class Migration20260126150000 extends Migration {
4
- async up(): Promise<void> {
5
- // Add i18n support fields to notifications table
6
- this.addSql(`
7
- alter table "notifications"
8
- add column if not exists "title_key" text,
9
- add column if not exists "body_key" text,
10
- add column if not exists "title_variables" jsonb,
11
- add column if not exists "body_variables" jsonb;
12
- `)
13
-
14
- // Add comments for clarity
15
- this.addSql(`
16
- comment on column "notifications"."title_key" is 'i18n key for notification title';
17
- `)
18
- this.addSql(`
19
- comment on column "notifications"."body_key" is 'i18n key for notification body';
20
- `)
21
- this.addSql(`
22
- comment on column "notifications"."title_variables" is 'Variables for i18n interpolation in title';
23
- `)
24
- this.addSql(`
25
- comment on column "notifications"."body_variables" is 'Variables for i18n interpolation in body';
26
- `)
27
- }
28
-
29
- async down(): Promise<void> {
30
- // Remove i18n support fields
31
- this.addSql(`
32
- alter table "notifications"
33
- drop column if exists "title_key",
34
- drop column if exists "body_key",
35
- drop column if exists "title_variables",
36
- drop column if exists "body_variables";
37
- `)
38
- }
39
- }
@@ -1,175 +0,0 @@
1
- import type { EntityManager } from '@mikro-orm/postgresql'
2
- import { Notification } from '../data/entities'
3
- import { NOTIFICATION_EVENTS } from '../lib/events'
4
- import { DEFAULT_NOTIFICATION_DELIVERY_CONFIG, resolveNotificationDeliveryConfig, resolveNotificationPanelUrl } from '../lib/deliveryConfig'
5
- import { sendEmail } from '@open-mercato/shared/lib/email/send'
6
- import NotificationEmail from '../emails/NotificationEmail'
7
- import { loadDictionary } from '@open-mercato/shared/lib/i18n/server'
8
- import { createFallbackTranslator } from '@open-mercato/shared/lib/i18n/translate'
9
- import { defaultLocale } from '@open-mercato/shared/lib/i18n/config'
10
- import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
11
- import { User } from '../../auth/data/entities'
12
- import type { TenantDataEncryptionService } from '@open-mercato/shared/lib/encryption/tenantDataEncryptionService'
13
-
14
- export const metadata = {
15
- event: NOTIFICATION_EVENTS.CREATED,
16
- persistent: true,
17
- id: 'notifications:deliver',
18
- }
19
-
20
- const DEBUG = process.env.NOTIFICATIONS_DEBUG === 'true'
21
-
22
- function debug(...args: unknown[]): void {
23
- if (DEBUG) {
24
- console.log('[notifications]', ...args)
25
- }
26
- }
27
-
28
- type NotificationCreatedPayload = {
29
- notificationId: string
30
- recipientUserId: string
31
- tenantId: string
32
- organizationId?: string | null
33
- }
34
-
35
- type ResolverContext = {
36
- resolve: <T = unknown>(name: string) => T
37
- }
38
-
39
- const buildPanelLink = (panelUrl: string, notificationId: string) => {
40
- if (panelUrl.startsWith('http://') || panelUrl.startsWith('https://')) {
41
- const url = new URL(panelUrl)
42
- url.searchParams.set('notificationId', notificationId)
43
- return url.toString()
44
- }
45
- const separator = panelUrl.includes('?') ? '&' : '?'
46
- return `${panelUrl}${separator}notificationId=${encodeURIComponent(notificationId)}`
47
- }
48
-
49
- const resolveNotificationCopy = async (
50
- notification: Notification
51
- ) => {
52
- const dict = await loadDictionary(defaultLocale)
53
- const t = createFallbackTranslator(dict)
54
-
55
- const title = notification.titleKey
56
- ? t(notification.titleKey, notification.title ?? notification.titleKey, notification.titleVariables ?? undefined)
57
- : notification.title
58
-
59
- const body = notification.bodyKey
60
- ? t(notification.bodyKey, notification.body ?? notification.bodyKey ?? '', notification.bodyVariables ?? undefined)
61
- : notification.body ?? null
62
-
63
- return { title, body, t }
64
- }
65
-
66
- const resolveRecipient = async (
67
- em: EntityManager,
68
- notification: Notification,
69
- encryptionService?: TenantDataEncryptionService | null,
70
- ) => {
71
- const where: Partial<User> & { deletedAt?: null } = {
72
- id: notification.recipientUserId,
73
- tenantId: notification.tenantId,
74
- deletedAt: null,
75
- }
76
- if (notification.organizationId) {
77
- where.organizationId = notification.organizationId
78
- }
79
- const record = await findOneWithDecryption(
80
- em,
81
- User,
82
- where,
83
- undefined,
84
- {
85
- tenantId: notification.tenantId,
86
- organizationId: notification.organizationId ?? null,
87
- encryptionService: encryptionService ?? null,
88
- },
89
- )
90
- if (!record) return null
91
- return {
92
- email: typeof record.email === 'string' ? record.email : null,
93
- name: typeof record.name === 'string' ? record.name : null,
94
- }
95
- }
96
-
97
-
98
- export default async function handle(payload: NotificationCreatedPayload, ctx: ResolverContext) {
99
- debug('deliver notification event', payload)
100
- const deliveryConfig = await resolveNotificationDeliveryConfig(ctx, { defaultValue: DEFAULT_NOTIFICATION_DELIVERY_CONFIG })
101
- if (!deliveryConfig.strategies.email.enabled) {
102
- debug('email delivery disabled')
103
- return
104
- }
105
-
106
- const em = ctx.resolve('em') as EntityManager
107
- const notification = await em.findOne(Notification, {
108
- id: payload.notificationId,
109
- tenantId: payload.tenantId,
110
- organizationId: payload.organizationId ?? null,
111
- })
112
- if (!notification) {
113
- debug('notification not found', payload.notificationId)
114
- return
115
- }
116
-
117
- let encryptionService: TenantDataEncryptionService | null = null
118
- try {
119
- encryptionService = ctx.resolve<TenantDataEncryptionService>('tenantEncryptionService')
120
- } catch {
121
- encryptionService = null
122
- }
123
-
124
- const recipient = await resolveRecipient(em, notification, encryptionService)
125
- if (!recipient?.email) {
126
- debug('recipient has no email', notification.recipientUserId)
127
- }
128
- const { title, body, t } = await resolveNotificationCopy(notification)
129
- const panelUrl = resolveNotificationPanelUrl(deliveryConfig)
130
- if (!panelUrl) {
131
- debug('missing panelUrl; check appUrl/panelPath settings')
132
- return
133
- }
134
-
135
- const panelLink = buildPanelLink(panelUrl, notification.id)
136
- const actionLinks = (notification.actionData?.actions ?? []).map((action) => ({
137
- id: action.id,
138
- label: action.labelKey ? t(action.labelKey, action.label) : action.label,
139
- href: panelLink,
140
- }))
141
-
142
- if (deliveryConfig.strategies.email.enabled && recipient?.email) {
143
- const subjectPrefix = deliveryConfig.strategies.email.subjectPrefix?.trim()
144
- const subject = subjectPrefix ? `${subjectPrefix} ${title}` : title
145
- const copy = {
146
- preview: t('notifications.delivery.email.preview', 'New notification'),
147
- heading: t('notifications.delivery.email.heading', 'You have a new notification'),
148
- bodyIntro: t('notifications.delivery.email.bodyIntro', 'Review the notification details and take any required actions.'),
149
- actionNotice: t('notifications.delivery.email.actionNotice', 'Actions are available in Open Mercato and are read-only in this email.'),
150
- openCta: t('notifications.delivery.email.openCta', 'Open notification center'),
151
- footer: t('notifications.delivery.email.footer', 'Open Mercato notifications'),
152
- }
153
-
154
- try {
155
- debug('sending email', { to: recipient.email, from: deliveryConfig.strategies.email.from, subject })
156
- await sendEmail({
157
- to: recipient.email,
158
- subject,
159
- from: deliveryConfig.strategies.email.from,
160
- replyTo: deliveryConfig.strategies.email.replyTo,
161
- react: NotificationEmail({
162
- title,
163
- body,
164
- actions: actionLinks,
165
- panelUrl: panelLink,
166
- copy,
167
- }),
168
- })
169
- } catch (error) {
170
- console.error('[notifications] email delivery failed', error)
171
- }
172
- }
173
-
174
- return
175
- }