import { Injectable, Logger } from '@nestjs/common'; import { InjectQueue } from '@nestjs/bullmq'; import { Queue } from 'bullmq'; import { NotificationQueueJob } from '../interfaces/notification-queue.interface'; import { NotificationChannel } from '../entities/notification.entity'; @Injectable() export class NotificationQueueService { private readonly logger = new Logger(NotificationQueueService.name); constructor(@InjectQueue('notification-queue') private readonly notificationQueue: Queue) {} async addNotification(job: NotificationQueueJob): Promise { try { const jobId = job.idempotencyKey || `${job.restaurantId}-${job.notificationType}-${job.channel}-${Date.now()}`; await this.notificationQueue.add('send-notification', job, { jobId, attempts: 3, backoff: { type: 'exponential', delay: 2000, }, removeOnComplete: { age: 24 * 3600, // Keep completed jobs for 24 hours count: 1000, }, removeOnFail: { age: 7 * 24 * 3600, // Keep failed jobs for 7 days }, }); this.logger.log(`Notification job added to queue: ${jobId}`); } catch (error) { this.logger.error(`Failed to add notification to queue:`, error); throw error; } } async addBulkNotifications(jobs: NotificationQueueJob[]): Promise { try { const queueJobs = jobs.map(job => ({ name: 'send-notification', data: job, opts: { jobId: job.idempotencyKey || `${job.restaurantId}-${job.notificationType}-${job.channel}-${Date.now()}`, attempts: 3, backoff: { type: 'exponential', delay: 2000, }, }, })); await this.notificationQueue.addBulk(queueJobs); this.logger.log(`Added ${jobs.length} notification jobs to queue`); } catch (error) { this.logger.error(`Failed to add bulk notifications to queue:`, error); throw error; } } }