@open-mercato/core 0.4.2-canary-07dbc98202 → 0.4.2-canary-1000cb714f

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,127 +0,0 @@
1
- "use client"
2
- import * as React from 'react'
3
- import { useRouter } from 'next/navigation'
4
- import { Page, PageBody } from '@open-mercato/ui/backend/Page'
5
- import { CrudForm, type CrudField } from '@open-mercato/ui/backend/CrudForm'
6
- import { apiCall, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
7
- import { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'
8
- import { flash } from '@open-mercato/ui/backend/FlashMessages'
9
- import { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'
10
- import { useT } from '@open-mercato/shared/lib/i18n/context'
11
-
12
- type ProfileResponse = {
13
- email?: string | null
14
- }
15
-
16
- type ProfileUpdateResponse = {
17
- ok?: boolean
18
- email?: string | null
19
- }
20
-
21
- type ProfileFormValues = {
22
- email: string
23
- password: string
24
- confirmPassword: string
25
- }
26
-
27
- export default function AuthProfilePage() {
28
- const t = useT()
29
- const router = useRouter()
30
- const [loading, setLoading] = React.useState(true)
31
- const [error, setError] = React.useState<string | null>(null)
32
- const [email, setEmail] = React.useState('')
33
- const [formKey, setFormKey] = React.useState(0)
34
-
35
- React.useEffect(() => {
36
- let cancelled = false
37
- async function load() {
38
- setLoading(true)
39
- setError(null)
40
- try {
41
- const { ok, result } = await apiCall<ProfileResponse>('/api/auth/profile')
42
- if (!ok) throw new Error('load_failed')
43
- const resolvedEmail = typeof result?.email === 'string' ? result.email : ''
44
- if (!cancelled) setEmail(resolvedEmail)
45
- } catch (err) {
46
- console.error('Failed to load auth profile', err)
47
- if (!cancelled) setError(t('auth.profile.form.errors.load', 'Failed to load profile.'))
48
- } finally {
49
- if (!cancelled) setLoading(false)
50
- }
51
- }
52
- load()
53
- return () => { cancelled = true }
54
- }, [t])
55
-
56
- const fields = React.useMemo<CrudField[]>(() => [
57
- { id: 'email', label: t('auth.profile.form.email', 'Email'), type: 'text', required: true },
58
- { id: 'password', label: t('auth.profile.form.password', 'New password'), type: 'text' },
59
- { id: 'confirmPassword', label: t('auth.profile.form.confirmPassword', 'Confirm new password'), type: 'text' },
60
- ], [t])
61
-
62
- const handleSubmit = React.useCallback(async (values: ProfileFormValues) => {
63
- const nextEmail = values.email?.trim() ?? ''
64
- const password = values.password?.trim() ?? ''
65
- const confirmPassword = values.confirmPassword?.trim() ?? ''
66
-
67
- if (!nextEmail) {
68
- const message = t('auth.profile.form.errors.emailRequired', 'Email is required.')
69
- throw createCrudFormError(message, { email: message })
70
- }
71
-
72
- if (password || confirmPassword) {
73
- if (password !== confirmPassword) {
74
- const message = t('auth.profile.form.errors.passwordMismatch', 'Passwords do not match.')
75
- throw createCrudFormError(message, { confirmPassword: message })
76
- }
77
- }
78
-
79
- if (!password && nextEmail === email) {
80
- throw createCrudFormError(t('auth.profile.form.errors.noChanges', 'No changes to save.'))
81
- }
82
-
83
- const payload: { email: string; password?: string } = { email: nextEmail }
84
- if (password) payload.password = password
85
-
86
- const result = await readApiResultOrThrow<ProfileUpdateResponse>(
87
- '/api/auth/profile',
88
- {
89
- method: 'PUT',
90
- headers: { 'content-type': 'application/json' },
91
- body: JSON.stringify(payload),
92
- },
93
- { errorMessage: t('auth.profile.form.errors.save', 'Failed to update profile.') },
94
- )
95
-
96
- const resolvedEmail = typeof result?.email === 'string' ? result.email : nextEmail
97
- setEmail(resolvedEmail)
98
- setFormKey((prev) => prev + 1)
99
- flash(t('auth.profile.form.success', 'Profile updated.'), 'success')
100
- router.refresh()
101
- }, [email, router, t])
102
-
103
- return (
104
- <Page>
105
- <PageBody>
106
- {loading ? (
107
- <LoadingMessage label={t('auth.profile.form.loading', 'Loading profile...')} />
108
- ) : error ? (
109
- <ErrorMessage label={error} />
110
- ) : (
111
- <CrudForm<ProfileFormValues>
112
- key={formKey}
113
- title={t('auth.profile.title', 'Profile')}
114
- fields={fields}
115
- initialValues={{
116
- email,
117
- password: '',
118
- confirmPassword: '',
119
- }}
120
- submitLabel={t('auth.profile.form.save', 'Save changes')}
121
- onSubmit={handleSubmit}
122
- />
123
- )}
124
- </PageBody>
125
- </Page>
126
- )
127
- }
@@ -1,109 +0,0 @@
1
- import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
2
-
3
- export const notificationTypes: NotificationTypeDefinition[] = [
4
- {
5
- type: 'auth.password_reset.requested',
6
- module: 'auth',
7
- titleKey: 'auth.notifications.passwordReset.requested.title',
8
- bodyKey: 'auth.notifications.passwordReset.requested.body',
9
- icon: 'key',
10
- severity: 'info',
11
- actions: [
12
- {
13
- id: 'view',
14
- labelKey: 'common.view',
15
- variant: 'outline',
16
- href: '/backend/auth/profile',
17
- icon: 'external-link',
18
- },
19
- ],
20
- linkHref: '/backend/auth/profile',
21
- expiresAfterHours: 24,
22
- },
23
- {
24
- type: 'auth.password_reset.completed',
25
- module: 'auth',
26
- titleKey: 'auth.notifications.passwordReset.completed.title',
27
- bodyKey: 'auth.notifications.passwordReset.completed.body',
28
- icon: 'check-circle',
29
- severity: 'success',
30
- actions: [],
31
- expiresAfterHours: 72,
32
- },
33
- {
34
- type: 'auth.account.locked',
35
- module: 'auth',
36
- titleKey: 'auth.notifications.account.locked.title',
37
- bodyKey: 'auth.notifications.account.locked.body',
38
- icon: 'lock',
39
- severity: 'warning',
40
- actions: [
41
- {
42
- id: 'contact_support',
43
- labelKey: 'auth.actions.contactSupport',
44
- variant: 'default',
45
- href: '/backend/support',
46
- icon: 'mail',
47
- },
48
- ],
49
- linkHref: '/backend/support',
50
- },
51
- {
52
- type: 'auth.login.new_device',
53
- module: 'auth',
54
- titleKey: 'auth.notifications.login.newDevice.title',
55
- bodyKey: 'auth.notifications.login.newDevice.body',
56
- icon: 'smartphone',
57
- severity: 'info',
58
- actions: [
59
- {
60
- id: 'view_sessions',
61
- labelKey: 'auth.actions.viewSessions',
62
- variant: 'outline',
63
- href: '/backend/auth/sessions',
64
- icon: 'list',
65
- },
66
- ],
67
- linkHref: '/backend/auth/sessions',
68
- expiresAfterHours: 168, // 7 days
69
- },
70
- {
71
- type: 'auth.role.assigned',
72
- module: 'auth',
73
- titleKey: 'auth.notifications.role.assigned.title',
74
- bodyKey: 'auth.notifications.role.assigned.body',
75
- icon: 'user-plus',
76
- severity: 'success',
77
- actions: [
78
- {
79
- id: 'view_permissions',
80
- labelKey: 'auth.actions.viewPermissions',
81
- variant: 'outline',
82
- href: '/backend/auth/profile',
83
- icon: 'shield',
84
- },
85
- ],
86
- linkHref: '/backend/auth/profile',
87
- expiresAfterHours: 168,
88
- },
89
- {
90
- type: 'auth.role.revoked',
91
- module: 'auth',
92
- titleKey: 'auth.notifications.role.revoked.title',
93
- bodyKey: 'auth.notifications.role.revoked.body',
94
- icon: 'user-minus',
95
- severity: 'warning',
96
- actions: [
97
- {
98
- id: 'view_profile',
99
- labelKey: 'common.view',
100
- variant: 'outline',
101
- href: '/backend/auth/profile',
102
- },
103
- ],
104
- linkHref: '/backend/auth/profile',
105
- expiresAfterHours: 168,
106
- },
107
- ]
108
-
109
- export default notificationTypes
@@ -1,25 +0,0 @@
1
- import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
2
-
3
- export const notificationTypes: NotificationTypeDefinition[] = [
4
- {
5
- type: 'business_rules.rule.execution_failed',
6
- module: 'business_rules',
7
- titleKey: 'businessRules.notifications.rule.executionFailed.title',
8
- bodyKey: 'businessRules.notifications.rule.executionFailed.body',
9
- icon: 'alert-triangle',
10
- severity: 'error',
11
- actions: [
12
- {
13
- id: 'view',
14
- labelKey: 'common.view',
15
- variant: 'outline',
16
- href: '/backend/business-rules/{sourceEntityId}',
17
- icon: 'external-link',
18
- },
19
- ],
20
- linkHref: '/backend/business-rules/{sourceEntityId}',
21
- expiresAfterHours: 168, // 7 days
22
- },
23
- ]
24
-
25
- export default notificationTypes
@@ -1,50 +0,0 @@
1
- import type { EntityManager } from '@mikro-orm/postgresql'
2
- import { resolveNotificationService } from '../../notifications/lib/notificationService'
3
- import { buildFeatureNotificationFromType } from '../../notifications/lib/notificationBuilder'
4
- import { notificationTypes } from '../notifications'
5
-
6
- export const metadata = {
7
- event: 'business_rules.rule.execution_failed',
8
- persistent: true,
9
- id: 'business_rules:rule-execution-failed-notification',
10
- }
11
-
12
- type RuleExecutionFailedPayload = {
13
- ruleId: string
14
- ruleName: string
15
- entityType?: string | null
16
- errorMessage?: string | null
17
- tenantId: string
18
- organizationId?: string | null
19
- }
20
-
21
- type ResolverContext = {
22
- resolve: <T = unknown>(name: string) => T
23
- }
24
-
25
- export default async function handle(payload: RuleExecutionFailedPayload, ctx: ResolverContext) {
26
- try {
27
- const notificationService = resolveNotificationService(ctx)
28
- const typeDef = notificationTypes.find((type) => type.type === 'business_rules.rule.execution_failed')
29
- if (!typeDef) return
30
-
31
- const notificationInput = buildFeatureNotificationFromType(typeDef, {
32
- requiredFeature: 'business_rules.manage',
33
- bodyVariables: {
34
- ruleName: payload.ruleName,
35
- entityType: payload.entityType ?? '',
36
- errorMessage: payload.errorMessage ?? 'Unknown error',
37
- },
38
- sourceEntityType: 'business_rules:rule',
39
- sourceEntityId: payload.ruleId,
40
- linkHref: `/backend/business-rules/${payload.ruleId}`,
41
- })
42
-
43
- await notificationService.createForFeature(notificationInput, {
44
- tenantId: payload.tenantId,
45
- organizationId: payload.organizationId ?? null,
46
- })
47
- } catch (err) {
48
- console.error('[business_rules:rule-execution-failed-notification] Failed to create notification:', err)
49
- }
50
- }
@@ -1,25 +0,0 @@
1
- import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
2
-
3
- export const notificationTypes: NotificationTypeDefinition[] = [
4
- {
5
- type: 'catalog.product.low_stock',
6
- module: 'catalog',
7
- titleKey: 'catalog.notifications.product.lowStock.title',
8
- bodyKey: 'catalog.notifications.product.lowStock.body',
9
- icon: 'package-x',
10
- severity: 'warning',
11
- actions: [
12
- {
13
- id: 'view',
14
- labelKey: 'common.view',
15
- variant: 'outline',
16
- href: '/backend/catalog/products/{sourceEntityId}',
17
- icon: 'external-link',
18
- },
19
- ],
20
- linkHref: '/backend/catalog/products/{sourceEntityId}',
21
- expiresAfterHours: 72, // 3 days
22
- },
23
- ]
24
-
25
- export default notificationTypes
@@ -1,52 +0,0 @@
1
- import type { EntityManager } from '@mikro-orm/postgresql'
2
- import { resolveNotificationService } from '../../notifications/lib/notificationService'
3
- import { buildFeatureNotificationFromType } from '../../notifications/lib/notificationBuilder'
4
- import { notificationTypes } from '../notifications'
5
-
6
- export const metadata = {
7
- event: 'catalog.product.stock_low',
8
- persistent: true,
9
- id: 'catalog:low-stock-notification',
10
- }
11
-
12
- type LowStockPayload = {
13
- productId: string
14
- productName: string
15
- sku?: string | null
16
- currentStock: number
17
- threshold: number
18
- tenantId: string
19
- organizationId?: string | null
20
- }
21
-
22
- type ResolverContext = {
23
- resolve: <T = unknown>(name: string) => T
24
- }
25
-
26
- export default async function handle(payload: LowStockPayload, ctx: ResolverContext) {
27
- try {
28
- const notificationService = resolveNotificationService(ctx)
29
- const typeDef = notificationTypes.find((type) => type.type === 'catalog.product.low_stock')
30
- if (!typeDef) return
31
-
32
- const notificationInput = buildFeatureNotificationFromType(typeDef, {
33
- requiredFeature: 'catalog.products.manage',
34
- bodyVariables: {
35
- productName: payload.productName,
36
- sku: payload.sku ?? '',
37
- currentStock: String(payload.currentStock),
38
- threshold: String(payload.threshold),
39
- },
40
- sourceEntityType: 'catalog:product',
41
- sourceEntityId: payload.productId,
42
- linkHref: `/backend/catalog/products/${payload.productId}`,
43
- })
44
-
45
- await notificationService.createForFeature(notificationInput, {
46
- tenantId: payload.tenantId,
47
- organizationId: payload.organizationId ?? null,
48
- })
49
- } catch (err) {
50
- console.error('[catalog:low-stock-notification] Failed to create notification:', err)
51
- }
52
- }
@@ -1,44 +0,0 @@
1
- import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
2
-
3
- export const notificationTypes: NotificationTypeDefinition[] = [
4
- {
5
- type: 'customers.deal.won',
6
- module: 'customers',
7
- titleKey: 'customers.notifications.deal.won.title',
8
- bodyKey: 'customers.notifications.deal.won.body',
9
- icon: 'trophy',
10
- severity: 'success',
11
- actions: [
12
- {
13
- id: 'view',
14
- labelKey: 'common.view',
15
- variant: 'outline',
16
- href: '/backend/customers/deals/{sourceEntityId}',
17
- icon: 'external-link',
18
- },
19
- ],
20
- linkHref: '/backend/customers/deals/{sourceEntityId}',
21
- expiresAfterHours: 168, // 7 days
22
- },
23
- {
24
- type: 'customers.deal.lost',
25
- module: 'customers',
26
- titleKey: 'customers.notifications.deal.lost.title',
27
- bodyKey: 'customers.notifications.deal.lost.body',
28
- icon: 'x-circle',
29
- severity: 'warning',
30
- actions: [
31
- {
32
- id: 'view',
33
- labelKey: 'common.view',
34
- variant: 'outline',
35
- href: '/backend/customers/deals/{sourceEntityId}',
36
- icon: 'external-link',
37
- },
38
- ],
39
- linkHref: '/backend/customers/deals/{sourceEntityId}',
40
- expiresAfterHours: 168, // 7 days
41
- },
42
- ]
43
-
44
- export default notificationTypes
@@ -1,7 +0,0 @@
1
- export const features = [
2
- { id: 'notifications.view', title: 'View own notifications', module: 'notifications' },
3
- { id: 'notifications.create', title: 'Create notifications for others', module: 'notifications' },
4
- { id: 'notifications.manage', title: 'Manage all notifications', module: 'notifications' },
5
- ]
6
-
7
- export default features
@@ -1,75 +0,0 @@
1
- import { executeActionSchema } from '../../../data/validators'
2
- import { actionResultResponseSchema, errorResponseSchema } from '../../openapi'
3
- import { resolveNotificationContext } from '../../../lib/routeHelpers'
4
- import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
5
-
6
- export const metadata = {
7
- POST: { requireAuth: true },
8
- }
9
-
10
- export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {
11
- const { id } = await params
12
- const { service, scope } = await resolveNotificationContext(req)
13
-
14
- const body = await req.json().catch(() => ({}))
15
- const input = executeActionSchema.parse(body)
16
-
17
- try {
18
- const { notification, result } = await service.executeAction(id, input, scope)
19
-
20
- const action = notification.actionData?.actions?.find((a) => a.id === input.actionId)
21
- const href = action?.href?.replace('{sourceEntityId}', notification.sourceEntityId ?? '')
22
-
23
- return Response.json({
24
- ok: true,
25
- result,
26
- href,
27
- })
28
- } catch (error) {
29
- const { t } = await resolveTranslations()
30
- const fallback = t('notifications.error.action', 'Failed to execute action')
31
- const message = error instanceof Error && error.message ? error.message : fallback
32
- return Response.json({ error: message }, { status: 400 })
33
- }
34
- }
35
-
36
- export const openApi = {
37
- POST: {
38
- summary: 'Execute notification action',
39
- tags: ['Notifications'],
40
- parameters: [
41
- {
42
- name: 'id',
43
- in: 'path',
44
- required: true,
45
- schema: { type: 'string', format: 'uuid' },
46
- },
47
- ],
48
- requestBody: {
49
- required: true,
50
- content: {
51
- 'application/json': {
52
- schema: executeActionSchema,
53
- },
54
- },
55
- },
56
- responses: {
57
- 200: {
58
- description: 'Action executed successfully',
59
- content: {
60
- 'application/json': {
61
- schema: actionResultResponseSchema,
62
- },
63
- },
64
- },
65
- 400: {
66
- description: 'Action not found or failed',
67
- content: {
68
- 'application/json': {
69
- schema: errorResponseSchema,
70
- },
71
- },
72
- },
73
- },
74
- },
75
- }
@@ -1,12 +0,0 @@
1
- import { createSingleNotificationActionRoute, createSingleNotificationActionOpenApi } from '../../../lib/routeHelpers'
2
-
3
- export const metadata = {
4
- PUT: { requireAuth: true },
5
- }
6
-
7
- export const PUT = createSingleNotificationActionRoute('dismiss')
8
-
9
- export const openApi = createSingleNotificationActionOpenApi(
10
- 'Dismiss notification',
11
- 'Notification dismissed'
12
- )
@@ -1,12 +0,0 @@
1
- import { createSingleNotificationActionRoute, createSingleNotificationActionOpenApi } from '../../../lib/routeHelpers'
2
-
3
- export const metadata = {
4
- PUT: { requireAuth: true },
5
- }
6
-
7
- export const PUT = createSingleNotificationActionRoute('markAsRead')
8
-
9
- export const openApi = createSingleNotificationActionOpenApi(
10
- 'Mark notification as read',
11
- 'Notification marked as read'
12
- )
@@ -1,53 +0,0 @@
1
- import { z } from 'zod'
2
- import { restoreNotificationSchema } from '../../../data/validators'
3
- import { resolveNotificationContext } from '../../../lib/routeHelpers'
4
-
5
- export const metadata = {
6
- PUT: { requireAuth: true },
7
- }
8
-
9
- export async function PUT(req: Request, { params }: { params: Promise<{ id: string }> }) {
10
- const { id } = await params
11
- const { service, scope } = await resolveNotificationContext(req)
12
-
13
- const body = await req.json().catch(() => ({}))
14
- const input = restoreNotificationSchema.parse(body)
15
-
16
- await service.restoreDismissed(id, input.status, scope)
17
-
18
- return Response.json({ ok: true })
19
- }
20
-
21
- export const openApi = {
22
- PUT: {
23
- summary: 'Restore dismissed notification',
24
- description: 'Undo a dismissal and restore a notification to read or unread.',
25
- tags: ['Notifications'],
26
- parameters: [
27
- {
28
- name: 'id',
29
- in: 'path',
30
- required: true,
31
- schema: { type: 'string', format: 'uuid' },
32
- },
33
- ],
34
- requestBody: {
35
- required: false,
36
- content: {
37
- 'application/json': {
38
- schema: restoreNotificationSchema,
39
- },
40
- },
41
- },
42
- responses: {
43
- 200: {
44
- description: 'Notification restored',
45
- content: {
46
- 'application/json': {
47
- schema: z.object({ ok: z.boolean() }),
48
- },
49
- },
50
- },
51
- },
52
- },
53
- }
@@ -1,14 +0,0 @@
1
- import { createBatchNotificationSchema } from '../../data/validators'
2
- import { createBulkNotificationRoute, createBulkNotificationOpenApi } from '../../lib/routeHelpers'
3
-
4
- export const metadata = {
5
- POST: { requireAuth: true, requireFeatures: ['notifications.create'] },
6
- }
7
-
8
- export const POST = createBulkNotificationRoute(createBatchNotificationSchema, 'createBatch')
9
-
10
- export const openApi = createBulkNotificationOpenApi(
11
- createBatchNotificationSchema,
12
- 'Create batch notifications',
13
- 'Send the same notification to multiple users'
14
- )
@@ -1,14 +0,0 @@
1
- import { createFeatureNotificationSchema } from '../../data/validators'
2
- import { createBulkNotificationRoute, createBulkNotificationOpenApi } from '../../lib/routeHelpers'
3
-
4
- export const metadata = {
5
- POST: { requireAuth: true, requireFeatures: ['notifications.create'] },
6
- }
7
-
8
- export const POST = createBulkNotificationRoute(createFeatureNotificationSchema, 'createForFeature')
9
-
10
- export const openApi = createBulkNotificationOpenApi(
11
- createFeatureNotificationSchema,
12
- 'Create notifications for all users with a specific feature/permission',
13
- 'Send the same notification to all users who have the specified feature permission (via role ACL or user ACL). Supports wildcard matching.'
14
- )
@@ -1,34 +0,0 @@
1
- import { z } from 'zod'
2
- import { resolveNotificationContext } from '../../lib/routeHelpers'
3
-
4
- export const metadata = {
5
- PUT: { requireAuth: true },
6
- }
7
-
8
- export async function PUT(req: Request) {
9
- const { service, scope } = await resolveNotificationContext(req)
10
-
11
- const count = await service.markAllAsRead(scope)
12
-
13
- return Response.json({ ok: true, count })
14
- }
15
-
16
- export const openApi = {
17
- PUT: {
18
- summary: 'Mark all notifications as read',
19
- tags: ['Notifications'],
20
- responses: {
21
- 200: {
22
- description: 'All notifications marked as read',
23
- content: {
24
- 'application/json': {
25
- schema: z.object({
26
- ok: z.boolean(),
27
- count: z.number(),
28
- }),
29
- },
30
- },
31
- },
32
- },
33
- },
34
- }