@spfn/notification 0.1.0-beta.1

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,683 @@
1
+ export { NotificationConfig, configureNotification, getAppName, getEmailFrom, getEmailReplyTo, getNotificationConfig, getSmsDefaultCountryCode } from './config/index.js';
2
+ import { S as SendEmailParams, a as SendResult, E as EmailProvider, b as SendSMSParams, c as SMSProvider, T as TemplateDefinition, d as TemplateData, N as NotificationChannel$1, R as RenderedTemplate } from './index-D_XTwHmO.js';
3
+ export { e as EmailTemplateContent, g as SlackTemplateContent, f as SmsTemplateContent } from './index-D_XTwHmO.js';
4
+ import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
5
+ import * as _spfn_core_job from '@spfn/core/job';
6
+ import '@spfn/core/env';
7
+
8
+ /**
9
+ * @spfn/notification - Email Channel
10
+ */
11
+
12
+ /**
13
+ * Register custom email provider
14
+ */
15
+ declare function registerEmailProvider(provider: EmailProvider): void;
16
+ /**
17
+ * Send email
18
+ */
19
+ declare function sendEmail(params: SendEmailParams): Promise<SendResult>;
20
+ /**
21
+ * Send bulk emails
22
+ */
23
+ declare function sendEmailBulk(items: SendEmailParams[]): Promise<{
24
+ results: SendResult[];
25
+ successCount: number;
26
+ failureCount: number;
27
+ }>;
28
+
29
+ /**
30
+ * @spfn/notification - SMS Channel
31
+ */
32
+
33
+ /**
34
+ * Register custom SMS provider
35
+ */
36
+ declare function registerSMSProvider(provider: SMSProvider): void;
37
+ /**
38
+ * Send SMS
39
+ */
40
+ declare function sendSMS(params: SendSMSParams): Promise<SendResult>;
41
+ /**
42
+ * Send bulk SMS
43
+ */
44
+ declare function sendSMSBulk(items: SendSMSParams[]): Promise<{
45
+ results: SendResult[];
46
+ successCount: number;
47
+ failureCount: number;
48
+ }>;
49
+
50
+ /**
51
+ * @spfn/notification - Schedule Service
52
+ *
53
+ * Schedule notifications for later delivery
54
+ */
55
+
56
+ /**
57
+ * Schedule options
58
+ */
59
+ interface ScheduleOptions {
60
+ /**
61
+ * When to send
62
+ */
63
+ scheduledAt: Date;
64
+ /**
65
+ * Reference to related entity
66
+ */
67
+ referenceType?: string;
68
+ referenceId?: string;
69
+ }
70
+ /**
71
+ * Result of scheduling
72
+ */
73
+ interface ScheduleResult {
74
+ success: boolean;
75
+ notificationId?: number;
76
+ jobId?: string;
77
+ error?: string;
78
+ }
79
+ /**
80
+ * Schedule email for later delivery
81
+ */
82
+ declare function scheduleEmail(params: SendEmailParams, options: ScheduleOptions): Promise<ScheduleResult>;
83
+ /**
84
+ * Schedule SMS for later delivery
85
+ */
86
+ declare function scheduleSMS(params: SendSMSParams, options: ScheduleOptions): Promise<ScheduleResult>;
87
+
88
+ /**
89
+ * @spfn/notification - Template Registry
90
+ */
91
+
92
+ /**
93
+ * Register a template
94
+ */
95
+ declare function registerTemplate(template: TemplateDefinition): void;
96
+ /**
97
+ * Get template by name
98
+ */
99
+ declare function getTemplate(name: string): TemplateDefinition | undefined;
100
+ /**
101
+ * Check if template exists
102
+ */
103
+ declare function hasTemplate(name: string): boolean;
104
+ /**
105
+ * Render template with data
106
+ */
107
+ declare function renderTemplate(name: string, data: TemplateData, channel?: NotificationChannel$1): RenderedTemplate;
108
+ /**
109
+ * Get all registered template names
110
+ */
111
+ declare function getTemplateNames(): string[];
112
+
113
+ /**
114
+ * @spfn/notification - Template Renderer
115
+ *
116
+ * Simple template engine with variable substitution and filters
117
+ *
118
+ * Syntax:
119
+ * - {{variable}} - Basic substitution
120
+ * - {{variable | filter}} - With filter
121
+ * - {{variable | filter:arg}} - Filter with argument
122
+ */
123
+
124
+ /**
125
+ * Register custom filter
126
+ */
127
+ declare function registerFilter(name: string, fn: (value: unknown, arg?: string) => string): void;
128
+
129
+ /**
130
+ * @spfn/notification - Template System
131
+ */
132
+
133
+ /**
134
+ * Register all built-in templates
135
+ */
136
+ declare function registerBuiltinTemplates(): void;
137
+
138
+ /**
139
+ * @spfn/notification - Notifications Entity
140
+ *
141
+ * Stores notification sending history for tracking and auditing
142
+ */
143
+ /**
144
+ * Notification channel types
145
+ */
146
+ declare const NOTIFICATION_CHANNELS: readonly ["email", "sms", "slack", "push"];
147
+ type NotificationChannel = typeof NOTIFICATION_CHANNELS[number];
148
+ /**
149
+ * Notification status types
150
+ */
151
+ declare const NOTIFICATION_STATUSES: readonly ["scheduled", "pending", "sent", "failed", "cancelled"];
152
+ type NotificationStatus = typeof NOTIFICATION_STATUSES[number];
153
+ /**
154
+ * Notifications table - stores all notification sending history
155
+ */
156
+ declare const notifications: drizzle_orm_pg_core.PgTableWithColumns<{
157
+ name: "history";
158
+ schema: string;
159
+ columns: {
160
+ createdAt: drizzle_orm_pg_core.PgColumn<{
161
+ name: "created_at";
162
+ tableName: "history";
163
+ dataType: "date";
164
+ columnType: "PgTimestamp";
165
+ data: Date;
166
+ driverParam: string;
167
+ notNull: true;
168
+ hasDefault: true;
169
+ isPrimaryKey: false;
170
+ isAutoincrement: false;
171
+ hasRuntimeDefault: false;
172
+ enumValues: undefined;
173
+ baseColumn: never;
174
+ identity: undefined;
175
+ generated: undefined;
176
+ }, {}, {}>;
177
+ updatedAt: drizzle_orm_pg_core.PgColumn<{
178
+ name: "updated_at";
179
+ tableName: "history";
180
+ dataType: "date";
181
+ columnType: "PgTimestamp";
182
+ data: Date;
183
+ driverParam: string;
184
+ notNull: true;
185
+ hasDefault: true;
186
+ isPrimaryKey: false;
187
+ isAutoincrement: false;
188
+ hasRuntimeDefault: false;
189
+ enumValues: undefined;
190
+ baseColumn: never;
191
+ identity: undefined;
192
+ generated: undefined;
193
+ }, {}, {}>;
194
+ id: drizzle_orm_pg_core.PgColumn<{
195
+ name: "id";
196
+ tableName: "history";
197
+ dataType: "number";
198
+ columnType: "PgBigSerial53";
199
+ data: number;
200
+ driverParam: number;
201
+ notNull: true;
202
+ hasDefault: true;
203
+ isPrimaryKey: true;
204
+ isAutoincrement: false;
205
+ hasRuntimeDefault: false;
206
+ enumValues: undefined;
207
+ baseColumn: never;
208
+ identity: undefined;
209
+ generated: undefined;
210
+ }, {}, {}>;
211
+ channel: drizzle_orm_pg_core.PgColumn<{
212
+ name: "channel";
213
+ tableName: "history";
214
+ dataType: "string";
215
+ columnType: "PgText";
216
+ data: "email" | "sms" | "slack" | "push";
217
+ driverParam: string;
218
+ notNull: true;
219
+ hasDefault: false;
220
+ isPrimaryKey: false;
221
+ isAutoincrement: false;
222
+ hasRuntimeDefault: false;
223
+ enumValues: ["email", "sms", "slack", "push"];
224
+ baseColumn: never;
225
+ identity: undefined;
226
+ generated: undefined;
227
+ }, {}, {}>;
228
+ recipient: drizzle_orm_pg_core.PgColumn<{
229
+ name: "recipient";
230
+ tableName: "history";
231
+ dataType: "string";
232
+ columnType: "PgText";
233
+ data: string;
234
+ driverParam: string;
235
+ notNull: true;
236
+ hasDefault: false;
237
+ isPrimaryKey: false;
238
+ isAutoincrement: false;
239
+ hasRuntimeDefault: false;
240
+ enumValues: [string, ...string[]];
241
+ baseColumn: never;
242
+ identity: undefined;
243
+ generated: undefined;
244
+ }, {}, {}>;
245
+ templateName: drizzle_orm_pg_core.PgColumn<{
246
+ name: "template_name";
247
+ tableName: "history";
248
+ dataType: "string";
249
+ columnType: "PgText";
250
+ data: string;
251
+ driverParam: string;
252
+ notNull: false;
253
+ hasDefault: false;
254
+ isPrimaryKey: false;
255
+ isAutoincrement: false;
256
+ hasRuntimeDefault: false;
257
+ enumValues: [string, ...string[]];
258
+ baseColumn: never;
259
+ identity: undefined;
260
+ generated: undefined;
261
+ }, {}, {}>;
262
+ templateData: drizzle_orm_pg_core.PgColumn<{
263
+ name: "template_data";
264
+ tableName: "history";
265
+ dataType: "json";
266
+ columnType: "PgJsonb";
267
+ data: unknown;
268
+ driverParam: unknown;
269
+ notNull: false;
270
+ hasDefault: false;
271
+ isPrimaryKey: false;
272
+ isAutoincrement: false;
273
+ hasRuntimeDefault: false;
274
+ enumValues: undefined;
275
+ baseColumn: never;
276
+ identity: undefined;
277
+ generated: undefined;
278
+ }, {}, {}>;
279
+ subject: drizzle_orm_pg_core.PgColumn<{
280
+ name: "subject";
281
+ tableName: "history";
282
+ dataType: "string";
283
+ columnType: "PgText";
284
+ data: string;
285
+ driverParam: string;
286
+ notNull: false;
287
+ hasDefault: false;
288
+ isPrimaryKey: false;
289
+ isAutoincrement: false;
290
+ hasRuntimeDefault: false;
291
+ enumValues: [string, ...string[]];
292
+ baseColumn: never;
293
+ identity: undefined;
294
+ generated: undefined;
295
+ }, {}, {}>;
296
+ content: drizzle_orm_pg_core.PgColumn<{
297
+ name: "content";
298
+ tableName: "history";
299
+ dataType: "string";
300
+ columnType: "PgText";
301
+ data: string;
302
+ driverParam: string;
303
+ notNull: false;
304
+ hasDefault: false;
305
+ isPrimaryKey: false;
306
+ isAutoincrement: false;
307
+ hasRuntimeDefault: false;
308
+ enumValues: [string, ...string[]];
309
+ baseColumn: never;
310
+ identity: undefined;
311
+ generated: undefined;
312
+ }, {}, {}>;
313
+ status: drizzle_orm_pg_core.PgColumn<{
314
+ name: "status";
315
+ tableName: "history";
316
+ dataType: "string";
317
+ columnType: "PgText";
318
+ data: "scheduled" | "pending" | "sent" | "failed" | "cancelled";
319
+ driverParam: string;
320
+ notNull: true;
321
+ hasDefault: true;
322
+ isPrimaryKey: false;
323
+ isAutoincrement: false;
324
+ hasRuntimeDefault: false;
325
+ enumValues: ["scheduled", "pending", "sent", "failed", "cancelled"];
326
+ baseColumn: never;
327
+ identity: undefined;
328
+ generated: undefined;
329
+ }, {}, {}>;
330
+ providerMessageId: drizzle_orm_pg_core.PgColumn<{
331
+ name: "provider_message_id";
332
+ tableName: "history";
333
+ dataType: "string";
334
+ columnType: "PgText";
335
+ data: string;
336
+ driverParam: string;
337
+ notNull: false;
338
+ hasDefault: false;
339
+ isPrimaryKey: false;
340
+ isAutoincrement: false;
341
+ hasRuntimeDefault: false;
342
+ enumValues: [string, ...string[]];
343
+ baseColumn: never;
344
+ identity: undefined;
345
+ generated: undefined;
346
+ }, {}, {}>;
347
+ providerName: drizzle_orm_pg_core.PgColumn<{
348
+ name: "provider_name";
349
+ tableName: "history";
350
+ dataType: "string";
351
+ columnType: "PgText";
352
+ data: string;
353
+ driverParam: string;
354
+ notNull: false;
355
+ hasDefault: false;
356
+ isPrimaryKey: false;
357
+ isAutoincrement: false;
358
+ hasRuntimeDefault: false;
359
+ enumValues: [string, ...string[]];
360
+ baseColumn: never;
361
+ identity: undefined;
362
+ generated: undefined;
363
+ }, {}, {}>;
364
+ errorMessage: drizzle_orm_pg_core.PgColumn<{
365
+ name: "error_message";
366
+ tableName: "history";
367
+ dataType: "string";
368
+ columnType: "PgText";
369
+ data: string;
370
+ driverParam: string;
371
+ notNull: false;
372
+ hasDefault: false;
373
+ isPrimaryKey: false;
374
+ isAutoincrement: false;
375
+ hasRuntimeDefault: false;
376
+ enumValues: [string, ...string[]];
377
+ baseColumn: never;
378
+ identity: undefined;
379
+ generated: undefined;
380
+ }, {}, {}>;
381
+ scheduledAt: drizzle_orm_pg_core.PgColumn<{
382
+ name: string;
383
+ tableName: "history";
384
+ dataType: "date";
385
+ columnType: "PgTimestamp";
386
+ data: Date;
387
+ driverParam: string;
388
+ notNull: false;
389
+ hasDefault: false;
390
+ isPrimaryKey: false;
391
+ isAutoincrement: false;
392
+ hasRuntimeDefault: false;
393
+ enumValues: undefined;
394
+ baseColumn: never;
395
+ identity: undefined;
396
+ generated: undefined;
397
+ }, {}, {}>;
398
+ sentAt: drizzle_orm_pg_core.PgColumn<{
399
+ name: string;
400
+ tableName: "history";
401
+ dataType: "date";
402
+ columnType: "PgTimestamp";
403
+ data: Date;
404
+ driverParam: string;
405
+ notNull: false;
406
+ hasDefault: false;
407
+ isPrimaryKey: false;
408
+ isAutoincrement: false;
409
+ hasRuntimeDefault: false;
410
+ enumValues: undefined;
411
+ baseColumn: never;
412
+ identity: undefined;
413
+ generated: undefined;
414
+ }, {}, {}>;
415
+ jobId: drizzle_orm_pg_core.PgColumn<{
416
+ name: "job_id";
417
+ tableName: "history";
418
+ dataType: "string";
419
+ columnType: "PgText";
420
+ data: string;
421
+ driverParam: string;
422
+ notNull: false;
423
+ hasDefault: false;
424
+ isPrimaryKey: false;
425
+ isAutoincrement: false;
426
+ hasRuntimeDefault: false;
427
+ enumValues: [string, ...string[]];
428
+ baseColumn: never;
429
+ identity: undefined;
430
+ generated: undefined;
431
+ }, {}, {}>;
432
+ batchId: drizzle_orm_pg_core.PgColumn<{
433
+ name: "batch_id";
434
+ tableName: "history";
435
+ dataType: "string";
436
+ columnType: "PgText";
437
+ data: string;
438
+ driverParam: string;
439
+ notNull: false;
440
+ hasDefault: false;
441
+ isPrimaryKey: false;
442
+ isAutoincrement: false;
443
+ hasRuntimeDefault: false;
444
+ enumValues: [string, ...string[]];
445
+ baseColumn: never;
446
+ identity: undefined;
447
+ generated: undefined;
448
+ }, {}, {}>;
449
+ referenceType: drizzle_orm_pg_core.PgColumn<{
450
+ name: "reference_type";
451
+ tableName: "history";
452
+ dataType: "string";
453
+ columnType: "PgText";
454
+ data: string;
455
+ driverParam: string;
456
+ notNull: false;
457
+ hasDefault: false;
458
+ isPrimaryKey: false;
459
+ isAutoincrement: false;
460
+ hasRuntimeDefault: false;
461
+ enumValues: [string, ...string[]];
462
+ baseColumn: never;
463
+ identity: undefined;
464
+ generated: undefined;
465
+ }, {}, {}>;
466
+ referenceId: drizzle_orm_pg_core.PgColumn<{
467
+ name: "reference_id";
468
+ tableName: "history";
469
+ dataType: "string";
470
+ columnType: "PgText";
471
+ data: string;
472
+ driverParam: string;
473
+ notNull: false;
474
+ hasDefault: false;
475
+ isPrimaryKey: false;
476
+ isAutoincrement: false;
477
+ hasRuntimeDefault: false;
478
+ enumValues: [string, ...string[]];
479
+ baseColumn: never;
480
+ identity: undefined;
481
+ generated: undefined;
482
+ }, {}, {}>;
483
+ };
484
+ dialect: "pg";
485
+ }>;
486
+ /**
487
+ * Type inference
488
+ */
489
+ type Notification = typeof notifications.$inferSelect;
490
+ type NewNotification = typeof notifications.$inferInsert;
491
+
492
+ /**
493
+ * @spfn/notification - Notification Service
494
+ *
495
+ * Core service for tracking notification history
496
+ */
497
+
498
+ /**
499
+ * Create notification record (pending status)
500
+ */
501
+ declare function createNotificationRecord(data: Omit<NewNotification, 'id' | 'createdAt' | 'updatedAt'>): Promise<Notification>;
502
+ /**
503
+ * Create scheduled notification record
504
+ */
505
+ declare function createScheduledNotification(data: Omit<NewNotification, 'id' | 'createdAt' | 'updatedAt' | 'status'> & {
506
+ scheduledAt: Date;
507
+ }): Promise<Notification>;
508
+ /**
509
+ * Update job ID for scheduled notification
510
+ */
511
+ declare function updateNotificationJobId(id: number, jobId: string): Promise<Notification | null>;
512
+ /**
513
+ * Mark notification as sent
514
+ */
515
+ declare function markNotificationSent(id: number, providerMessageId?: string): Promise<Notification | null>;
516
+ /**
517
+ * Mark notification as failed
518
+ */
519
+ declare function markNotificationFailed(id: number, errorMessage: string): Promise<Notification | null>;
520
+ /**
521
+ * Mark scheduled notification as pending (job started)
522
+ */
523
+ declare function markNotificationPending(id: number): Promise<Notification | null>;
524
+ /**
525
+ * Cancel scheduled notification
526
+ */
527
+ declare function cancelScheduledNotification(id: number): Promise<Notification | null>;
528
+ /**
529
+ * Find notification by job ID
530
+ */
531
+ declare function findNotificationByJobId(jobId: string): Promise<Notification | null>;
532
+ /**
533
+ * Query options for finding notifications
534
+ */
535
+ interface FindNotificationsOptions {
536
+ channel?: NotificationChannel;
537
+ status?: NotificationStatus;
538
+ recipient?: string;
539
+ referenceType?: string;
540
+ referenceId?: string;
541
+ from?: Date;
542
+ to?: Date;
543
+ limit?: number;
544
+ offset?: number;
545
+ }
546
+ /**
547
+ * Find notifications with filters
548
+ */
549
+ declare function findNotifications(options?: FindNotificationsOptions): Promise<Notification[]>;
550
+ /**
551
+ * Count notifications with filters
552
+ */
553
+ declare function countNotifications(options?: Omit<FindNotificationsOptions, 'limit' | 'offset'>): Promise<number>;
554
+ /**
555
+ * Get notification statistics
556
+ */
557
+ interface NotificationStats {
558
+ total: number;
559
+ scheduled: number;
560
+ pending: number;
561
+ sent: number;
562
+ failed: number;
563
+ cancelled: number;
564
+ }
565
+ declare function getNotificationStats(options?: {
566
+ channel?: NotificationChannel;
567
+ from?: Date;
568
+ to?: Date;
569
+ }): Promise<NotificationStats>;
570
+ /**
571
+ * Find scheduled notifications (for dashboard)
572
+ */
573
+ declare function findScheduledNotifications(options?: {
574
+ channel?: NotificationChannel;
575
+ from?: Date;
576
+ to?: Date;
577
+ limit?: number;
578
+ offset?: number;
579
+ }): Promise<Notification[]>;
580
+
581
+ /**
582
+ * @spfn/notification - Cancel Service
583
+ *
584
+ * Cancel scheduled notifications
585
+ */
586
+ interface CancelResult {
587
+ success: boolean;
588
+ error?: string;
589
+ }
590
+ /**
591
+ * Cancel a scheduled notification by ID
592
+ */
593
+ declare function cancelNotification(notificationId: number): Promise<CancelResult>;
594
+ /**
595
+ * Cancel all scheduled notifications for a reference
596
+ */
597
+ declare function cancelNotificationsByReference(referenceType: string, referenceId: string): Promise<{
598
+ cancelled: number;
599
+ errors: number;
600
+ }>;
601
+
602
+ /**
603
+ * @spfn/notification - Scheduled Email Job
604
+ */
605
+ /**
606
+ * Scheduled email sending job
607
+ */
608
+ declare const sendScheduledEmailJob: _spfn_core_job.JobDef<{
609
+ subject?: string | undefined;
610
+ html?: string | undefined;
611
+ text?: string | undefined;
612
+ data?: {
613
+ [x: string]: unknown;
614
+ } | undefined;
615
+ from?: string | undefined;
616
+ template?: string | undefined;
617
+ replyTo?: string | undefined;
618
+ to: string | string[];
619
+ notificationId: number;
620
+ }, void>;
621
+
622
+ /**
623
+ * @spfn/notification - Scheduled SMS Job
624
+ */
625
+ /**
626
+ * Scheduled SMS sending job
627
+ */
628
+ declare const sendScheduledSmsJob: _spfn_core_job.JobDef<{
629
+ message?: string | undefined;
630
+ data?: {
631
+ [x: string]: unknown;
632
+ } | undefined;
633
+ template?: string | undefined;
634
+ to: string | string[];
635
+ notificationId: number;
636
+ }, void>;
637
+
638
+ /**
639
+ * @spfn/notification - Job Router
640
+ */
641
+ /**
642
+ * Notification job router
643
+ *
644
+ * Register this with your server config:
645
+ * @example
646
+ * ```typescript
647
+ * import { notificationJobRouter } from '@spfn/notification/server';
648
+ *
649
+ * defineServerConfig()
650
+ * .routes(appRouter)
651
+ * .jobs(defineJobRouter({
652
+ * notification: notificationJobRouter,
653
+ * // ... other jobs
654
+ * }))
655
+ * .build();
656
+ * ```
657
+ */
658
+ declare const notificationJobRouter: _spfn_core_job.JobRouter<{
659
+ sendScheduledEmail: _spfn_core_job.JobDef<{
660
+ subject?: string | undefined;
661
+ html?: string | undefined;
662
+ text?: string | undefined;
663
+ data?: {
664
+ [x: string]: unknown;
665
+ } | undefined;
666
+ from?: string | undefined;
667
+ template?: string | undefined;
668
+ replyTo?: string | undefined;
669
+ to: string | string[];
670
+ notificationId: number;
671
+ }, void>;
672
+ sendScheduledSms: _spfn_core_job.JobDef<{
673
+ message?: string | undefined;
674
+ data?: {
675
+ [x: string]: unknown;
676
+ } | undefined;
677
+ template?: string | undefined;
678
+ to: string | string[];
679
+ notificationId: number;
680
+ }, void>;
681
+ }>;
682
+
683
+ export { type CancelResult, EmailProvider, type FindNotificationsOptions, NOTIFICATION_CHANNELS, NOTIFICATION_STATUSES, type NewNotification, type Notification, NotificationChannel$1 as NotificationChannel, type NotificationStats, type NotificationStatus, SMSProvider, type ScheduleOptions, type ScheduleResult, SendEmailParams, SendResult, SendSMSParams, TemplateData, TemplateDefinition, cancelNotification, cancelNotificationsByReference, cancelScheduledNotification, countNotifications, createNotificationRecord, createScheduledNotification, findNotificationByJobId, findNotifications, findScheduledNotifications, getNotificationStats, getTemplate, getTemplateNames, hasTemplate, markNotificationFailed, markNotificationPending, markNotificationSent, notificationJobRouter, notifications, registerBuiltinTemplates, registerEmailProvider, registerFilter, registerSMSProvider, registerTemplate, renderTemplate, scheduleEmail, scheduleSMS, sendEmail, sendEmailBulk, sendSMS, sendSMSBulk, sendScheduledEmailJob, sendScheduledSmsJob, updateNotificationJobId };