@@ -32,6 +32,7 @@ import {
3232import * as crypto from 'crypto' ;
3333import type { ConnectionOptions } from 'bullmq' ;
3434
35+ import { PrismaService } from '../prisma/prisma.service' ;
3536import {
3637 NotificationRetryJobData ,
3738 NotificationRetryBackoff ,
@@ -98,6 +99,7 @@ export class NotificationRetryQueueService
9899
99100 constructor (
100101 @Optional ( ) options ?: CommonOptions ,
102+ @Optional ( ) private readonly prisma ?: PrismaService ,
101103 ) {
102104 if ( options ?. backoff ) this . options . backoff = options . backoff ;
103105 this . options . deadLetterSink = options ?. deadLetterSink ;
@@ -156,9 +158,29 @@ export class NotificationRetryQueueService
156158 for ( let attempt = 1 ; attempt <= attempts ; attempt ++ ) {
157159 try {
158160 await dispatcher . dispatch ( job ) ;
161+ if ( job . notificationId && this . prisma ) {
162+ await this . prisma . notification . update ( {
163+ where : { id : job . notificationId } ,
164+ data : {
165+ status : 'SENT' ,
166+ sentAt : new Date ( ) ,
167+ retryCount : attempt - 1 ,
168+ } ,
169+ } ) . catch ( err => this . logger . error ( 'Failed to update notification status to SENT' , err ) ) ;
170+ }
159171 return ;
160172 } catch ( err ) {
161173 lastError = err ;
174+ if ( job . notificationId && this . prisma ) {
175+ await this . prisma . notification . update ( {
176+ where : { id : job . notificationId } ,
177+ data : {
178+ retryCount : attempt ,
179+ failedAt : new Date ( ) ,
180+ lastError : err instanceof Error ? err . message : String ( err ) ,
181+ } ,
182+ } ) . catch ( dbErr => this . logger . error ( 'Failed to update notification status to FAILED/PENDING' , dbErr ) ) ;
183+ }
162184 if ( attempt >= attempts ) break ;
163185 const delay = computeBackoffDelay ( attempt + 1 , this . options . backoff ) ;
164186 this . logger . warn (
@@ -168,6 +190,14 @@ export class NotificationRetryQueueService
168190 await this . sleep ( delay ) ;
169191 }
170192 }
193+ if ( job . notificationId && this . prisma ) {
194+ await this . prisma . notification . update ( {
195+ where : { id : job . notificationId } ,
196+ data : {
197+ status : 'FAILED' ,
198+ } ,
199+ } ) . catch ( err => this . logger . error ( 'Failed to update notification status to FAILED' , err ) ) ;
200+ }
171201 await this . recordDeadLetter ( job , attempts , lastError ) ;
172202 }
173203
@@ -242,17 +272,48 @@ export class NotificationRetryQueueService
242272 `No dispatcher registered for channel ${ job . data . channel } ` ,
243273 ) ;
244274 }
245- await dispatcher . dispatch ( job . data ) ;
275+ try {
276+ await dispatcher . dispatch ( job . data ) ;
277+ if ( job . data . notificationId && this . prisma ) {
278+ await this . prisma . notification . update ( {
279+ where : { id : job . data . notificationId } ,
280+ data : {
281+ status : 'SENT' ,
282+ sentAt : new Date ( ) ,
283+ retryCount : job . attemptsMade ,
284+ } ,
285+ } ) . catch ( err => this . logger . error ( 'Failed to update notification status to SENT in worker' , err ) ) ;
286+ }
287+ } catch ( err ) {
288+ if ( job . data . notificationId && this . prisma ) {
289+ await this . prisma . notification . update ( {
290+ where : { id : job . data . notificationId } ,
291+ data : {
292+ retryCount : job . attemptsMade + 1 ,
293+ failedAt : new Date ( ) ,
294+ lastError : err instanceof Error ? err . message : String ( err ) ,
295+ } ,
296+ } ) . catch ( dbErr => this . logger . error ( 'Failed to update notification status on error in worker' , dbErr ) ) ;
297+ }
298+ throw err ;
299+ }
246300 } ,
247301 { connection } ,
248302 ) ;
249303 this . bullWorker . on ( 'failed' , async ( job , error ) => {
250- if (
251- ! job ||
252- job . attemptsMade < ( job . opts . attempts ?? this . options . backoff . attempts )
253- ) {
304+ if ( ! job ) return ;
305+ const attemptsAllowed = job . opts . attempts ?? this . options . backoff . attempts ;
306+ if ( job . attemptsMade < attemptsAllowed ) {
254307 return ;
255308 }
309+ if ( job . data . notificationId && this . prisma ) {
310+ await this . prisma . notification . update ( {
311+ where : { id : job . data . notificationId } ,
312+ data : {
313+ status : 'FAILED' ,
314+ } ,
315+ } ) . catch ( err => this . logger . error ( 'Failed to update notification status to FAILED in worker' , err ) ) ;
316+ }
256317 await this . recordDeadLetter (
257318 job . data ,
258319 job . attemptsMade ,
0 commit comments