vintasend-prisma 0.2.3 → 0.3.0

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.
@@ -0,0 +1,2 @@
1
+ export { PrismaNotificationBackendFactory } from './prisma-notification-backend';
2
+ export type { PrismaNotificationBackend } from './prisma-notification-backend';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PrismaNotificationBackendFactory = void 0;
4
+ var prisma_notification_backend_1 = require("./prisma-notification-backend");
5
+ Object.defineProperty(exports, "PrismaNotificationBackendFactory", { enumerable: true, get: function () { return prisma_notification_backend_1.PrismaNotificationBackendFactory; } });
@@ -0,0 +1,190 @@
1
+ import type { BaseNotificationBackend } from '../../../services/notification-backends/base-notification-backend';
2
+ import type { InputJsonValue, JsonValue } from 'vintasend/dist/types/json-values';
3
+ import type { DatabaseNotification, Notification, NotificationInput } from 'vintasend/dist/types/notification';
4
+ import type { DatabaseOneOffNotification, OneOffNotificationInput, AnyDatabaseNotification } from '../../../types/notification';
5
+ import type { NotificationStatus } from 'vintasend/dist/types/notification-status';
6
+ import type { NotificationType } from 'vintasend/dist/types/notification-type';
7
+ import type { BaseNotificationTypeConfig } from 'vintasend/dist/types/notification-type-config';
8
+ export declare const NotificationStatusEnum: {
9
+ readonly PENDING_SEND: "PENDING_SEND";
10
+ readonly SENT: "SENT";
11
+ readonly FAILED: "FAILED";
12
+ readonly READ: "READ";
13
+ readonly CANCELLED: "CANCELLED";
14
+ };
15
+ export declare const NotificationTypeEnum: {
16
+ readonly EMAIL: "EMAIL";
17
+ readonly PUSH: "PUSH";
18
+ readonly SMS: "SMS";
19
+ readonly IN_APP: "IN_APP";
20
+ };
21
+ export interface PrismaNotificationModel<IdType, UserId> {
22
+ id: IdType;
23
+ userId: UserId | null;
24
+ emailOrPhone: string | null;
25
+ firstName: string | null;
26
+ lastName: string | null;
27
+ notificationType: NotificationType;
28
+ title: string | null;
29
+ bodyTemplate: string;
30
+ contextName: string;
31
+ contextParameters: JsonValue;
32
+ sendAfter: Date | null;
33
+ subjectTemplate: string | null;
34
+ status: NotificationStatus;
35
+ contextUsed: JsonValue | null;
36
+ extraParams: JsonValue | null;
37
+ adapterUsed: string | null;
38
+ sentAt: Date | null;
39
+ readAt: Date | null;
40
+ createdAt: Date;
41
+ updatedAt: Date;
42
+ user?: {
43
+ email: string;
44
+ };
45
+ }
46
+ export interface NotificationPrismaClientInterface<NotificationIdType, UserIdType> {
47
+ notification: {
48
+ findMany(args: {
49
+ where?: {
50
+ status?: NotificationStatus | {
51
+ not: NotificationStatus;
52
+ };
53
+ sendAfter?: {
54
+ lte: Date;
55
+ } | null;
56
+ userId?: UserIdType | null;
57
+ readAt?: null;
58
+ emailOrPhone?: string | {
59
+ not: null;
60
+ };
61
+ };
62
+ skip?: number;
63
+ take?: number;
64
+ include?: {
65
+ user?: boolean;
66
+ };
67
+ }): Promise<PrismaNotificationModel<NotificationIdType, UserIdType>[]>;
68
+ create(args: {
69
+ data: BaseNotificationCreateInput<UserIdType>;
70
+ include?: {
71
+ user?: boolean;
72
+ };
73
+ }): Promise<PrismaNotificationModel<NotificationIdType, UserIdType>>;
74
+ createMany(args: {
75
+ data: BaseNotificationCreateInput<UserIdType>[];
76
+ }): Promise<NotificationIdType[]>;
77
+ update(args: {
78
+ where: {
79
+ id: NotificationIdType;
80
+ };
81
+ data: Partial<BaseNotificationUpdateInput<UserIdType>>;
82
+ include?: {
83
+ user?: boolean;
84
+ };
85
+ }): Promise<PrismaNotificationModel<NotificationIdType, UserIdType>>;
86
+ findUnique(args: {
87
+ where: {
88
+ id: NotificationIdType;
89
+ };
90
+ include?: {
91
+ user?: boolean;
92
+ };
93
+ }): Promise<PrismaNotificationModel<NotificationIdType, UserIdType> | null>;
94
+ };
95
+ }
96
+ type NoExpand<T> = T extends unknown ? T : never;
97
+ type AtLeast<O extends object, K extends string> = NoExpand<O extends unknown ? (K extends keyof O ? {
98
+ [P in K]: O[P];
99
+ } & O : O) | ({
100
+ [P in keyof O as P extends K ? K : never]-?: O[P];
101
+ } & O) : never>;
102
+ export interface BaseNotificationCreateInput<UserIdType> {
103
+ user?: {
104
+ connect?: AtLeast<{
105
+ id?: UserIdType;
106
+ email?: string;
107
+ }, 'id' | 'email'>;
108
+ };
109
+ userId?: UserIdType | null;
110
+ emailOrPhone?: string | null;
111
+ firstName?: string | null;
112
+ lastName?: string | null;
113
+ notificationType: NotificationType;
114
+ title?: string | null;
115
+ bodyTemplate: string;
116
+ contextName: string;
117
+ contextParameters: InputJsonValue;
118
+ sendAfter?: Date | null;
119
+ subjectTemplate?: string | null;
120
+ status?: NotificationStatus;
121
+ contextUsed?: InputJsonValue;
122
+ extraParams?: InputJsonValue;
123
+ adapterUsed?: string | null;
124
+ sentAt?: Date | null;
125
+ readAt?: Date | null;
126
+ }
127
+ export interface BaseNotificationUpdateInput<UserIdType> {
128
+ user?: {
129
+ connect?: AtLeast<{
130
+ id?: UserIdType;
131
+ email?: string;
132
+ }, 'id' | 'email'>;
133
+ };
134
+ emailOrPhone?: string | null;
135
+ firstName?: string | null;
136
+ lastName?: string | null;
137
+ notificationType?: NotificationType;
138
+ title?: string | null;
139
+ bodyTemplate?: string;
140
+ contextName?: string;
141
+ contextParameters?: InputJsonValue;
142
+ sendAfter?: Date | null;
143
+ subjectTemplate?: string | null;
144
+ status?: NotificationStatus;
145
+ contextUsed?: InputJsonValue;
146
+ extraParams?: InputJsonValue;
147
+ adapterUsed?: string | null;
148
+ sentAt?: Date | null;
149
+ readAt?: Date | null;
150
+ }
151
+ export declare class PrismaNotificationBackend<Client extends NotificationPrismaClientInterface<Config['NotificationIdType'], Config['UserIdType']>, Config extends BaseNotificationTypeConfig> implements BaseNotificationBackend<Config> {
152
+ private prismaClient;
153
+ constructor(prismaClient: Client);
154
+ /**
155
+ * Serialize a Prisma notification model to either DatabaseNotification or DatabaseOneOffNotification
156
+ * based on whether it has a userId or not
157
+ */
158
+ serializeNotification(notification: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>): AnyDatabaseNotification<Config>;
159
+ deserializeNotification(notification: NotificationInput<Config>): BaseNotificationCreateInput<Config['UserIdType']>;
160
+ deserializeNotificationForUpdate(notification: Partial<Notification<Config>>): Partial<Parameters<typeof this.prismaClient.notification.update>[0]['data']>;
161
+ getAllPendingNotifications(): Promise<AnyDatabaseNotification<Config>[]>;
162
+ getPendingNotifications(page?: number, pageSize?: number): Promise<AnyDatabaseNotification<Config>[]>;
163
+ getAllFutureNotifications(): Promise<AnyDatabaseNotification<Config>[]>;
164
+ getFutureNotifications(page?: number, pageSize?: number): Promise<AnyDatabaseNotification<Config>[]>;
165
+ getAllFutureNotificationsFromUser(userId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['userId']): Promise<DatabaseNotification<Config>[]>;
166
+ getFutureNotificationsFromUser(userId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['userId'], page: number, pageSize: number): Promise<DatabaseNotification<Config>[]>;
167
+ getAllNotifications(): Promise<AnyDatabaseNotification<Config>[]>;
168
+ getNotifications(page: number, pageSize: number): Promise<AnyDatabaseNotification<Config>[]>;
169
+ persistNotification(notification: NotificationInput<Config>): Promise<DatabaseNotification<Config>>;
170
+ persistNotificationUpdate(notificationId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['id'], notification: Partial<Omit<DatabaseNotification<Config>, 'id'>>): Promise<DatabaseNotification<Config>>;
171
+ persistOneOffNotification(notification: OneOffNotificationInput<Config>): Promise<DatabaseOneOffNotification<Config>>;
172
+ persistOneOffNotificationUpdate(notificationId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['id'], notification: Partial<Omit<DatabaseOneOffNotification<Config>, 'id'>>): Promise<DatabaseOneOffNotification<Config>>;
173
+ getOneOffNotification(notificationId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['id'], _forUpdate: boolean): Promise<DatabaseOneOffNotification<Config> | null>;
174
+ getAllOneOffNotifications(): Promise<DatabaseOneOffNotification<Config>[]>;
175
+ getOneOffNotifications(page: number, pageSize: number): Promise<DatabaseOneOffNotification<Config>[]>;
176
+ markAsSent(notificationId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['id'], checkIsPending?: boolean): Promise<AnyDatabaseNotification<Config>>;
177
+ markAsFailed(notificationId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['id'], checkIsPending?: boolean): Promise<AnyDatabaseNotification<Config>>;
178
+ markAsRead(notificationId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['id'], checkIsSent?: boolean): Promise<DatabaseNotification<Config>>;
179
+ cancelNotification(notificationId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['id']): Promise<void>;
180
+ getNotification(notificationId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['id'], _forUpdate: boolean): Promise<AnyDatabaseNotification<Config> | null>;
181
+ filterAllInAppUnreadNotifications(userId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['userId']): Promise<DatabaseNotification<Config>[]>;
182
+ filterInAppUnreadNotifications(userId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['userId'], page: number, pageSize: number): Promise<DatabaseNotification<Config>[]>;
183
+ getUserEmailFromNotification(notificationId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['id']): Promise<string | undefined>;
184
+ storeContextUsed(notificationId: NonNullable<Awaited<ReturnType<typeof this.prismaClient.notification.findUnique>>>['id'], context: InputJsonValue): Promise<void>;
185
+ bulkPersistNotifications(notifications: Omit<Notification<Config>, 'id'>[]): Promise<Config['NotificationIdType'][]>;
186
+ }
187
+ export declare class PrismaNotificationBackendFactory<Config extends BaseNotificationTypeConfig> {
188
+ create<Client extends NotificationPrismaClientInterface<Config['NotificationIdType'], Config['UserIdType']>>(prismaClient: Client): PrismaNotificationBackend<Client, Config>;
189
+ }
190
+ export {};
@@ -0,0 +1,399 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PrismaNotificationBackendFactory = exports.PrismaNotificationBackend = exports.NotificationTypeEnum = exports.NotificationStatusEnum = void 0;
4
+ exports.NotificationStatusEnum = {
5
+ PENDING_SEND: 'PENDING_SEND',
6
+ SENT: 'SENT',
7
+ FAILED: 'FAILED',
8
+ READ: 'READ',
9
+ CANCELLED: 'CANCELLED',
10
+ };
11
+ exports.NotificationTypeEnum = {
12
+ EMAIL: 'EMAIL',
13
+ PUSH: 'PUSH',
14
+ SMS: 'SMS',
15
+ IN_APP: 'IN_APP',
16
+ };
17
+ function convertJsonValueToRecord(jsonValue) {
18
+ if (typeof jsonValue === 'object' && !Array.isArray(jsonValue)) {
19
+ return jsonValue;
20
+ }
21
+ throw new Error('Invalid JSON value. It should be an object.');
22
+ }
23
+ class PrismaNotificationBackend {
24
+ constructor(prismaClient) {
25
+ this.prismaClient = prismaClient;
26
+ }
27
+ /**
28
+ * Serialize a Prisma notification model to either DatabaseNotification or DatabaseOneOffNotification
29
+ * based on whether it has a userId or not
30
+ */
31
+ serializeNotification(notification) {
32
+ const baseData = {
33
+ id: notification.id,
34
+ notificationType: notification.notificationType,
35
+ title: notification.title,
36
+ bodyTemplate: notification.bodyTemplate,
37
+ contextName: notification.contextName,
38
+ contextParameters: notification.contextParameters
39
+ ? notification.contextParameters
40
+ : {},
41
+ sendAfter: notification.sendAfter,
42
+ subjectTemplate: notification.subjectTemplate,
43
+ status: notification.status,
44
+ contextUsed: notification.contextUsed,
45
+ extraParams: notification.extraParams
46
+ ? convertJsonValueToRecord(notification.extraParams)
47
+ : null,
48
+ adapterUsed: notification.adapterUsed,
49
+ sentAt: notification.sentAt,
50
+ readAt: notification.readAt,
51
+ createdAt: notification.createdAt,
52
+ updatedAt: notification.updatedAt,
53
+ };
54
+ // Check if this is a one-off notification (has emailOrPhone but no userId)
55
+ if (notification.emailOrPhone && !notification.userId) {
56
+ return {
57
+ ...baseData,
58
+ emailOrPhone: notification.emailOrPhone,
59
+ firstName: notification.firstName || '',
60
+ lastName: notification.lastName || '',
61
+ };
62
+ }
63
+ // Regular notification with userId
64
+ return {
65
+ ...baseData,
66
+ userId: notification.userId,
67
+ };
68
+ }
69
+ deserializeNotification(notification) {
70
+ return {
71
+ user: {
72
+ connect: {
73
+ id: notification.userId,
74
+ },
75
+ },
76
+ notificationType: notification.notificationType,
77
+ title: notification.title,
78
+ bodyTemplate: notification.bodyTemplate,
79
+ contextName: notification.contextName,
80
+ contextParameters: notification.contextParameters,
81
+ sendAfter: notification.sendAfter,
82
+ subjectTemplate: notification.subjectTemplate,
83
+ extraParams: notification.extraParams,
84
+ };
85
+ }
86
+ deserializeNotificationForUpdate(notification) {
87
+ return {
88
+ ...(notification.userId ? { user: { connect: { id: notification.userId } } } : {}),
89
+ ...(notification.notificationType
90
+ ? {
91
+ notificationType: exports.NotificationTypeEnum[notification.notificationType],
92
+ }
93
+ : {}),
94
+ ...(notification.title ? { title: notification.title } : {}),
95
+ ...(notification.bodyTemplate ? { bodyTemplate: notification.bodyTemplate } : {}),
96
+ ...(notification.contextName ? { contextName: notification.contextName } : {}),
97
+ ...(notification.contextParameters
98
+ ? {
99
+ contextParameters: notification.contextParameters ? notification.contextParameters : {},
100
+ }
101
+ : {}),
102
+ ...(notification.sendAfter ? { sendAfter: notification.sendAfter } : {}),
103
+ ...(notification.subjectTemplate ? { subjectTemplate: notification.subjectTemplate } : {}),
104
+ };
105
+ }
106
+ async getAllPendingNotifications() {
107
+ const notifications = await this.prismaClient.notification.findMany({
108
+ where: { status: exports.NotificationStatusEnum.PENDING_SEND },
109
+ });
110
+ return notifications.map((n) => this.serializeNotification(n));
111
+ }
112
+ async getPendingNotifications(page = 0, pageSize = 100) {
113
+ const notifications = await this.prismaClient.notification.findMany({
114
+ where: {
115
+ status: exports.NotificationStatusEnum.PENDING_SEND,
116
+ sendAfter: null,
117
+ },
118
+ skip: page * pageSize,
119
+ take: pageSize,
120
+ });
121
+ return notifications.map((n) => this.serializeNotification(n));
122
+ }
123
+ async getAllFutureNotifications() {
124
+ const notifications = await this.prismaClient.notification.findMany({
125
+ where: {
126
+ status: { not: exports.NotificationStatusEnum.PENDING_SEND },
127
+ sendAfter: { lte: new Date() },
128
+ },
129
+ });
130
+ return notifications.map((n) => this.serializeNotification(n));
131
+ }
132
+ async getFutureNotifications(page = 0, pageSize = 100) {
133
+ const notifications = await this.prismaClient.notification.findMany({
134
+ where: {
135
+ status: { not: exports.NotificationStatusEnum.PENDING_SEND },
136
+ sendAfter: { lte: new Date() },
137
+ },
138
+ skip: page * pageSize,
139
+ take: pageSize,
140
+ });
141
+ return notifications.map((n) => this.serializeNotification(n));
142
+ }
143
+ async getAllFutureNotificationsFromUser(userId) {
144
+ const notifications = await this.prismaClient.notification.findMany({
145
+ where: {
146
+ userId,
147
+ status: {
148
+ not: exports.NotificationStatusEnum.PENDING_SEND,
149
+ },
150
+ sendAfter: {
151
+ lte: new Date(),
152
+ },
153
+ },
154
+ });
155
+ // These are guaranteed to be regular notifications (not one-off) since we're filtering by userId
156
+ return notifications.map((n) => this.serializeNotification(n));
157
+ }
158
+ async getFutureNotificationsFromUser(userId, page, pageSize) {
159
+ const notifications = await this.prismaClient.notification.findMany({
160
+ where: {
161
+ userId,
162
+ status: {
163
+ not: exports.NotificationStatusEnum.PENDING_SEND,
164
+ },
165
+ sendAfter: {
166
+ lte: new Date(),
167
+ },
168
+ },
169
+ skip: page * pageSize,
170
+ take: pageSize,
171
+ });
172
+ // These are guaranteed to be regular notifications (not one-off) since we're filtering by userId
173
+ return notifications.map((n) => this.serializeNotification(n));
174
+ }
175
+ async getAllNotifications() {
176
+ const notifications = await this.prismaClient.notification.findMany({});
177
+ return notifications.map((n) => this.serializeNotification(n));
178
+ }
179
+ async getNotifications(page, pageSize) {
180
+ const notifications = await this.prismaClient.notification.findMany({
181
+ skip: page * pageSize,
182
+ take: pageSize,
183
+ });
184
+ return notifications.map((n) => this.serializeNotification(n));
185
+ }
186
+ async persistNotification(notification) {
187
+ const created = await this.prismaClient.notification.create({
188
+ data: this.deserializeNotification(notification),
189
+ });
190
+ // persistNotification takes NotificationInput which always has userId, so this is always a regular notification
191
+ return this.serializeNotification(created);
192
+ }
193
+ async persistNotificationUpdate(notificationId, notification) {
194
+ const updated = await this.prismaClient.notification.update({
195
+ where: {
196
+ id: notificationId,
197
+ },
198
+ data: this.deserializeNotificationForUpdate(notification),
199
+ });
200
+ // persistNotificationUpdate takes Partial<DatabaseNotification> which has userId, so this is always a regular notification
201
+ return this.serializeNotification(updated);
202
+ }
203
+ /* One-off notification persistence and query methods */
204
+ async persistOneOffNotification(notification) {
205
+ const created = await this.prismaClient.notification.create({
206
+ data: {
207
+ userId: null, // One-off notifications don't have a userId
208
+ emailOrPhone: notification.emailOrPhone,
209
+ firstName: notification.firstName,
210
+ lastName: notification.lastName,
211
+ notificationType: notification.notificationType,
212
+ title: notification.title,
213
+ bodyTemplate: notification.bodyTemplate,
214
+ contextName: notification.contextName,
215
+ contextParameters: notification.contextParameters,
216
+ sendAfter: notification.sendAfter,
217
+ subjectTemplate: notification.subjectTemplate,
218
+ extraParams: notification.extraParams,
219
+ status: exports.NotificationStatusEnum.PENDING_SEND,
220
+ },
221
+ });
222
+ return this.serializeNotification(created);
223
+ }
224
+ async persistOneOffNotificationUpdate(notificationId, notification) {
225
+ const data = {
226
+ ...(notification.emailOrPhone !== undefined ? { emailOrPhone: notification.emailOrPhone } : {}),
227
+ ...(notification.firstName !== undefined ? { firstName: notification.firstName } : {}),
228
+ ...(notification.lastName !== undefined ? { lastName: notification.lastName } : {}),
229
+ ...(notification.notificationType ? { notificationType: notification.notificationType } : {}),
230
+ ...(notification.title ? { title: notification.title } : {}),
231
+ ...(notification.bodyTemplate ? { bodyTemplate: notification.bodyTemplate } : {}),
232
+ ...(notification.contextName ? { contextName: notification.contextName } : {}),
233
+ ...(notification.contextParameters ? { contextParameters: notification.contextParameters } : {}),
234
+ ...(notification.sendAfter ? { sendAfter: notification.sendAfter } : {}),
235
+ ...(notification.subjectTemplate ? { subjectTemplate: notification.subjectTemplate } : {}),
236
+ };
237
+ const updated = await this.prismaClient.notification.update({
238
+ where: { id: notificationId },
239
+ data,
240
+ });
241
+ return this.serializeNotification(updated);
242
+ }
243
+ async getOneOffNotification(notificationId, _forUpdate) {
244
+ const notification = await this.prismaClient.notification.findUnique({
245
+ where: {
246
+ id: notificationId,
247
+ },
248
+ });
249
+ if (!notification || !notification.emailOrPhone || notification.userId !== null) {
250
+ return null;
251
+ }
252
+ return this.serializeNotification(notification);
253
+ }
254
+ async getAllOneOffNotifications() {
255
+ const notifications = await this.prismaClient.notification.findMany({
256
+ where: {
257
+ userId: null,
258
+ emailOrPhone: { not: null },
259
+ },
260
+ });
261
+ return notifications
262
+ .filter((n) => n.emailOrPhone !== null)
263
+ .map((n) => this.serializeNotification(n));
264
+ }
265
+ async getOneOffNotifications(page, pageSize) {
266
+ const notifications = await this.prismaClient.notification.findMany({
267
+ where: {
268
+ userId: null,
269
+ emailOrPhone: { not: null },
270
+ },
271
+ skip: page * pageSize,
272
+ take: pageSize,
273
+ });
274
+ return notifications
275
+ .filter((n) => n.emailOrPhone !== null)
276
+ .map((n) => this.serializeNotification(n));
277
+ }
278
+ async markAsSent(notificationId, checkIsPending = true) {
279
+ const whereClause = {
280
+ id: notificationId,
281
+ };
282
+ if (checkIsPending) {
283
+ whereClause.status = exports.NotificationStatusEnum.PENDING_SEND;
284
+ }
285
+ const updated = await this.prismaClient.notification.update({
286
+ where: whereClause,
287
+ data: {
288
+ status: exports.NotificationStatusEnum.SENT,
289
+ sentAt: new Date(),
290
+ },
291
+ });
292
+ return this.serializeNotification(updated);
293
+ }
294
+ async markAsFailed(notificationId, checkIsPending = true) {
295
+ const whereClause = {
296
+ id: notificationId,
297
+ };
298
+ if (checkIsPending) {
299
+ whereClause.status = exports.NotificationStatusEnum.PENDING_SEND;
300
+ }
301
+ const updated = await this.prismaClient.notification.update({
302
+ where: whereClause,
303
+ data: {
304
+ status: exports.NotificationStatusEnum.FAILED,
305
+ sentAt: new Date(),
306
+ },
307
+ });
308
+ return this.serializeNotification(updated);
309
+ }
310
+ async markAsRead(notificationId, checkIsSent = true) {
311
+ const whereClause = {
312
+ id: notificationId,
313
+ };
314
+ if (checkIsSent) {
315
+ whereClause.status = exports.NotificationStatusEnum.SENT;
316
+ }
317
+ const updated = await this.prismaClient.notification.update({
318
+ where: whereClause,
319
+ data: {
320
+ status: 'READ',
321
+ readAt: new Date(),
322
+ },
323
+ });
324
+ // markAsRead is only for in-app notifications (which are always regular notifications with userId)
325
+ return this.serializeNotification(updated);
326
+ }
327
+ async cancelNotification(notificationId) {
328
+ await this.prismaClient.notification.update({
329
+ where: {
330
+ id: notificationId,
331
+ },
332
+ data: {
333
+ status: exports.NotificationStatusEnum.CANCELLED,
334
+ },
335
+ });
336
+ }
337
+ async getNotification(notificationId, _forUpdate) {
338
+ const notification = await this.prismaClient.notification.findUnique({
339
+ where: { id: notificationId },
340
+ });
341
+ if (!notification)
342
+ return null;
343
+ return this.serializeNotification(notification);
344
+ }
345
+ async filterAllInAppUnreadNotifications(userId) {
346
+ const notifications = await this.prismaClient.notification.findMany({
347
+ where: {
348
+ userId,
349
+ status: 'SENT',
350
+ readAt: null,
351
+ },
352
+ });
353
+ // These are guaranteed to be regular notifications (not one-off) since we're filtering by userId
354
+ return notifications.map((n) => this.serializeNotification(n));
355
+ }
356
+ async filterInAppUnreadNotifications(userId, page, pageSize) {
357
+ const notifications = await this.prismaClient.notification.findMany({
358
+ where: {
359
+ userId,
360
+ status: 'SENT',
361
+ readAt: null,
362
+ },
363
+ skip: page * pageSize,
364
+ take: pageSize,
365
+ });
366
+ // These are guaranteed to be regular notifications (not one-off) since we're filtering by userId
367
+ return notifications.map((n) => this.serializeNotification(n));
368
+ }
369
+ async getUserEmailFromNotification(notificationId) {
370
+ var _a;
371
+ const notification = await this.prismaClient.notification.findUnique({
372
+ where: {
373
+ id: notificationId,
374
+ },
375
+ include: {
376
+ user: true,
377
+ },
378
+ });
379
+ return (_a = notification === null || notification === void 0 ? void 0 : notification.user) === null || _a === void 0 ? void 0 : _a.email;
380
+ }
381
+ async storeContextUsed(notificationId, context) {
382
+ await this.prismaClient.notification.update({
383
+ where: { id: notificationId },
384
+ data: { contextUsed: context }
385
+ });
386
+ }
387
+ async bulkPersistNotifications(notifications) {
388
+ return this.prismaClient.notification.createMany({
389
+ data: notifications.map((notification) => this.deserializeNotification(notification)),
390
+ });
391
+ }
392
+ }
393
+ exports.PrismaNotificationBackend = PrismaNotificationBackend;
394
+ class PrismaNotificationBackendFactory {
395
+ create(prismaClient) {
396
+ return new PrismaNotificationBackend(prismaClient);
397
+ }
398
+ }
399
+ exports.PrismaNotificationBackendFactory = PrismaNotificationBackendFactory;