diff --git a/src/modules/notifications/dto/create-preference.dto.ts b/src/modules/notifications/dto/create-preference.dto.ts index 9a97c62..621c96a 100644 --- a/src/modules/notifications/dto/create-preference.dto.ts +++ b/src/modules/notifications/dto/create-preference.dto.ts @@ -1,6 +1,6 @@ import { IsNotEmpty, IsEnum } from 'class-validator'; import { ApiProperty } from '@nestjs/swagger'; -import { NotificationTitleEnum } from '../interfaces/notification.interface'; +import { NotifTitleEnum } from '../interfaces/notification.interface'; import { NotificationType } from '../interfaces/notification.interface'; export class CreatePreferenceDto { @@ -15,10 +15,10 @@ export class CreatePreferenceDto { @ApiProperty({ description: 'Notification title/type (e.g., order.created, review.created)', - enum: NotificationTitleEnum, - example: NotificationTitleEnum.ORDER_CREATED, + enum: NotifTitleEnum, + example: NotifTitleEnum.ORDER_CREATED, }) - @IsEnum(NotificationTitleEnum) + @IsEnum(NotifTitleEnum) @IsNotEmpty() - title!: NotificationTitleEnum; + title!: NotifTitleEnum; } diff --git a/src/modules/notifications/entities/notification-preference.entity.ts b/src/modules/notifications/entities/notification-preference.entity.ts index a74a777..0597523 100644 --- a/src/modules/notifications/entities/notification-preference.entity.ts +++ b/src/modules/notifications/entities/notification-preference.entity.ts @@ -1,8 +1,9 @@ -import { Entity, Property, ManyToOne, Unique, Enum } from '@mikro-orm/core'; +import { Entity, Property, ManyToOne, Unique } from '@mikro-orm/core'; import { BaseEntity } from '../../../common/entities/base.entity'; import { Restaurant } from '../../restaurants/entities/restaurant.entity'; -import { NotificationTitleEnum } from '../interfaces/notification.interface'; -import { NotificationType } from '../interfaces/notification.interface'; +import { NotifTitleEnum } from '../interfaces/notification.interface'; +import { Admin } from 'src/modules/admin/entities/admin.entity'; +import { NotifChannelEnum } from '../interfaces/notification.interface'; @Entity({ tableName: 'notification_preferences' }) @Unique({ properties: ['restaurant', 'title'] }) @@ -10,9 +11,12 @@ export class NotificationPreference extends BaseEntity { @ManyToOne(() => Restaurant) restaurant!: Restaurant; - @Property() - title!: NotificationTitleEnum; + @ManyToOne(() => Admin, { nullable: true }) + admin?: Admin; - @Enum(() => NotificationType) - notificationType!: NotificationType; //sms, push, email + @Property() + title!: NotifTitleEnum; + + @Property({ type: 'json' }) + channels: NotifChannelEnum[] = []; } diff --git a/src/modules/notifications/entities/notification.entity.ts b/src/modules/notifications/entities/notification.entity.ts index 9cf395b..3a6f7e8 100644 --- a/src/modules/notifications/entities/notification.entity.ts +++ b/src/modules/notifications/entities/notification.entity.ts @@ -2,7 +2,8 @@ import { Entity, Property, ManyToOne, Enum } from '@mikro-orm/core'; import { BaseEntity } from '../../../common/entities/base.entity'; import { Restaurant } from '../../restaurants/entities/restaurant.entity'; import { User } from '../../users/entities/user.entity'; -import { NotificationTitleEnum } from '../interfaces/notification.interface'; +import { NotifTitleEnum } from '../interfaces/notification.interface'; +import { Admin } from 'src/modules/admin/entities/admin.entity'; @Entity({ tableName: 'notifications' }) export class Notification extends BaseEntity { @@ -12,8 +13,11 @@ export class Notification extends BaseEntity { @ManyToOne(() => User, { nullable: true }) user?: User; - @Enum(() => NotificationTitleEnum) - title!: NotificationTitleEnum; + @ManyToOne(() => Admin, { nullable: true }) + admin?: Admin; + + @Enum(() => NotifTitleEnum) + title!: NotifTitleEnum; @Property() content!: string; diff --git a/src/modules/notifications/guards/ws-admin-auth.guard.ts b/src/modules/notifications/guards/ws-admin-auth.guard.ts index 2e15939..296e004 100644 --- a/src/modules/notifications/guards/ws-admin-auth.guard.ts +++ b/src/modules/notifications/guards/ws-admin-auth.guard.ts @@ -101,4 +101,25 @@ export class WsAdminAuthGuard implements CanActivate { return undefined; } + + // private extractToken(client: Socket): string | undefined { + // const tryGet = (...values: any[]) => values.find(v => typeof v === 'string' && v.length > 0); + + // let token = tryGet( + // client.handshake.auth?.token, + // client.handshake.auth?.authorization, + // client.handshake.query?.token, + // client.handshake.query?.authorization, + // client.handshake.headers.authorization, + // client.handshake.headers['authorization'], + // ); + + // if (!token) return undefined; + + // if (token.startsWith('Bearer ')) { + // token = token.slice(7); + // } + + // return token; + // } } diff --git a/src/modules/notifications/interfaces/notification-queue.interface.ts b/src/modules/notifications/interfaces/notification-queue.interface.ts index 460f859..1efb012 100644 --- a/src/modules/notifications/interfaces/notification-queue.interface.ts +++ b/src/modules/notifications/interfaces/notification-queue.interface.ts @@ -1,10 +1,10 @@ import type { NotificationType } from './notification.interface'; -import type { NotificationTitleEnum } from './notification.interface'; +import type { NotifTitleEnum } from './notification.interface'; export interface NotificationQueueJob { restaurantId: string; userId?: string; - title: NotificationTitleEnum; + title: NotifTitleEnum; content: string; idempotencyKey?: string; notificationId?: string; // For retries diff --git a/src/modules/notifications/interfaces/notification.interface.ts b/src/modules/notifications/interfaces/notification.interface.ts index 398a4dd..7c98329 100644 --- a/src/modules/notifications/interfaces/notification.interface.ts +++ b/src/modules/notifications/interfaces/notification.interface.ts @@ -1,22 +1,59 @@ -export enum NotificationTitleEnum { +export enum NotifChannelEnum { + IN_APP = 'in-app', + SMS = 'sms', + PUSH = 'push', +} +export enum NotifTypeEnum { + TRANSACTIONAL = 'transactional', + PROMOTIONAL = 'promotional', + SYSTEM = 'system', +} +export enum NotifTitleEnum { ORDER_CREATED = 'order.created', PAYMENT_SUCCESS = 'payment.success', REVIEW_CREATED = 'review.created', ORDER_STATUS_CHANGED = 'order.status.changed', } +export type recipientType = + | { phone: string } + | { email: string } + | { fcmToken: string } + | { userId: string; restaurantId: string }; -export enum NotificationType { - NONE = 'none', - SMS = 'sms', - PUSH = 'push', - Both = 'both', +export interface NotifRequestMessage { + subject: string; + body: string; + smsText: string; + pushNotif: { + title: string; + body: string; + icon: string; + action: { + type: string; //view order + url: string; + }; + }; } + +export interface NotifRequest { + requestId: string; + timestamp: Date; + notifType: NotifTypeEnum; + channels: NotifChannelEnum[]; + recipient: recipientType; + message: NotifRequestMessage; + metadata: { + priority: number; + retries: number; + }; +} +//************************************************ */ interface INotifySmsPayload { [key: string]: string | number | Date; } interface INotifySms { phone: string; - subject: NotificationTitleEnum; + subject: NotifTitleEnum; } // Sub intefaces // 1. Order Created Sms Notify Payload @@ -27,7 +64,7 @@ interface IOrderCreatedSmsNotifyPayload extends INotifySmsPayload { } interface IOrderCreatedSmsNotify extends INotifySms { - subject: NotificationTitleEnum.ORDER_CREATED; + subject: NotifTitleEnum.ORDER_CREATED; payload: IOrderCreatedSmsNotifyPayload; } // 2. Payment Success @@ -37,7 +74,7 @@ interface IPaymentSuccessSmsNotifyPayload extends INotifySmsPayload { } interface IPaymentSuccessSmsNotify extends INotifySms { - subject: NotificationTitleEnum.PAYMENT_SUCCESS; + subject: NotifTitleEnum.PAYMENT_SUCCESS; payload: IPaymentSuccessSmsNotifyPayload; } diff --git a/src/modules/notifications/listeners/notification.listeners.ts b/src/modules/notifications/listeners/notification.listeners.ts index 41e505b..7016411 100644 --- a/src/modules/notifications/listeners/notification.listeners.ts +++ b/src/modules/notifications/listeners/notification.listeners.ts @@ -1,7 +1,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; import { NotificationService } from '../services/notification.service'; -import { NotificationTitleEnum } from '../interfaces/notification.interface'; +import { NotifTitleEnum } from '../interfaces/notification.interface'; import { OrderCreatedEvent, ReviewCreatedEvent, @@ -23,7 +23,7 @@ export class NotificationListeners { await this.notificationService.sendNotification({ restaurantId: event.restaurantId, userId: event.userId, - title: NotificationTitleEnum.ORDER_CREATED, + title: NotifTitleEnum.ORDER_CREATED, content: `Your order #${event.orderNumber} has created successfully`, }); } catch (error) { @@ -41,7 +41,7 @@ export class NotificationListeners { await this.notificationService.sendNotification({ restaurantId: event.restaurantId, userId: event.userId, - title: NotificationTitleEnum.ORDER_CREATED, + title: NotifTitleEnum.ORDER_CREATED, content: `Your Payement for order #${event.orderNumber} has been successful Paid ${event.totalAmount}`, }); } catch (error) { @@ -60,7 +60,7 @@ export class NotificationListeners { await this.notificationService.sendNotification({ restaurantId: event.restaurantId, userId: event.userId, - title: NotificationTitleEnum.REVIEW_CREATED, + title: NotifTitleEnum.REVIEW_CREATED, content: 'Thank you for your review!', }); } catch (error) { @@ -79,7 +79,7 @@ export class NotificationListeners { await this.notificationService.sendNotification({ restaurantId: event.restaurantId, userId: event.userId, - title: NotificationTitleEnum.ORDER_STATUS_CHANGED, + title: NotifTitleEnum.ORDER_STATUS_CHANGED, content: `Your order #${event.orderId} is now ${event.newStatus}`, }); } catch (error) { diff --git a/src/modules/notifications/pager.gateway.ts b/src/modules/notifications/pager.gateway.ts index 91cc04c..78364b1 100644 --- a/src/modules/notifications/pager.gateway.ts +++ b/src/modules/notifications/pager.gateway.ts @@ -1,15 +1,15 @@ import { WebSocketGateway, WebSocketServer, - SubscribeMessage, + // SubscribeMessage, OnGatewayConnection, OnGatewayDisconnect, - MessageBody, - ConnectedSocket, + // MessageBody, + // ConnectedSocket, } from '@nestjs/websockets'; import { Server, Socket } from 'socket.io'; import { Logger, UseGuards, Inject, forwardRef } from '@nestjs/common'; -import { WsRestId } from './decorators/ws-rest-id.decorator'; +// import { WsRestId } from './decorators/ws-rest-id.decorator'; import { NotificationService } from './services/notification.service'; import { WsAdminAuthGuard, type AuthenticatedSocket } from './guards/ws-admin-auth.guard'; @@ -21,6 +21,7 @@ import { WsAdminAuthGuard, type AuthenticatedSocket } from './guards/ws-admin-au connectionGuard: WsAdminAuthGuard, }, namespace: '/notifications', + transports: ['websocket', 'polling'], }) export class NotificationGateway implements OnGatewayConnection, OnGatewayDisconnect { @WebSocketServer() @@ -33,7 +34,8 @@ export class NotificationGateway implements OnGatewayConnection, OnGatewayDiscon private readonly notificationService: NotificationService, ) {} - handleConnection(client: Socket) { + handleConnection(client: AuthenticatedSocket) { + console.log(client); this.logger.log(`Client connected: ${client.id}`); } @@ -41,147 +43,155 @@ export class NotificationGateway implements OnGatewayConnection, OnGatewayDiscon this.logger.log(`Client disconnected: ${client.id}`); } + sendAdminNotification(client: AuthenticatedSocket, event: string, data: any) { + const room = this.getRoom(client); + this.server.to(room).emit(event, data); + } + + private getRoom(client: AuthenticatedSocket) { + return `restaurant:${client.restId}-admin:${client.adminId}`; + } /** * Join a room for a specific restaurant (admin/staff) * Requires admin authentication via JWT token * Restaurant ID is extracted from the authenticated admin's token * Room format: `restaurant:${restId}` */ - @UseGuards(WsAdminAuthGuard) - @SubscribeMessage('join:restaurant') - handleJoinRestaurant(@ConnectedSocket() client: AuthenticatedSocket, @WsRestId() restId: string) { - const room = `restaurant:${restId}`; - void client.join(room); - this.logger.log(`Admin ${client.adminId} (Client ${client.id}) joined room: ${room}`); - void client.emit('joined', { room, message: 'Successfully joined restaurant room' }); - } + // @UseGuards(WsAdminAuthGuard) + // @SubscribeMessage('join:restaurant') + // handleJoinRestaurant(@ConnectedSocket() client: AuthenticatedSocket, @WsRestId() restId: string) { + // const room = `restaurant:${restId}`; + // void client.join(room); + // this.logger.log(`Admin ${client.adminId} (Client ${client.id}) joined room: ${room}`); + // void client.emit('joined', { room, message: 'Successfully joined restaurant room' }); + // } /** * Join a room for a specific cookie/session (public user) * Room format: `cookie:${cookieId}` */ - @SubscribeMessage('join:session') - handleJoinSession(@ConnectedSocket() client: Socket, @MessageBody() data: { cookieId: string }) { - if (!data.cookieId) { - void client.emit('error', { message: 'Cookie ID is required' }); - return; - } + // @SubscribeMessage('join:session') + // handleJoinSession(@ConnectedSocket() client: Socket, @MessageBody() data: { cookieId: string }) { + // if (!data.cookieId) { + // void client.emit('error', { message: 'Cookie ID is required' }); + // return; + // } - const room = `cookie:${data.cookieId}`; - void client.join(room); - this.logger.log(`Client ${client.id} joined room: ${room}`); - void client.emit('joined', { room, message: 'Successfully joined session room' }); - } + // const room = `cookie:${data.cookieId}`; + // void client.join(room); + // this.logger.log(`Client ${client.id} joined room: ${room}`); + // void client.emit('joined', { room, message: 'Successfully joined session room' }); + // } /** * Leave a room */ - @SubscribeMessage('leave:room') - handleLeaveRoom(@ConnectedSocket() client: Socket, @MessageBody() data: { room: string }) { - if (data.room) { - void client.leave(data.room); - this.logger.log(`Client ${client.id} left room: ${data.room}`); - void client.emit('left', { room: data.room, message: 'Successfully left room' }); - } - } + // @SubscribeMessage('leave:room') + // handleLeaveRoom(@ConnectedSocket() client: Socket, @MessageBody() data: { room: string }) { + // if (data.room) { + // void client.leave(data.room); + // this.logger.log(`Client ${client.id} left room: ${data.room}`); + // void client.emit('left', { room: data.room, message: 'Successfully left room' }); + // } + // } /** * Get list of pagers for the restaurant (admin only) * Requires admin authentication via JWT token * Restaurant ID is extracted from the authenticated admin's token */ - @UseGuards(WsAdminAuthGuard) - @SubscribeMessage('get:pagers') - async handleGetPagers(@ConnectedSocket() client: AuthenticatedSocket, @WsRestId() restId: string) { - try { - const pagers = await this.pagerService.findAllByRestaurantId(restId); + // @UseGuards(WsAdminAuthGuard) + // @SubscribeMessage('get:pagers') + // async handleGetPagers(@ConnectedSocket() client: AuthenticatedSocket, @WsRestId() restId: string) { + // try { + // const pagers = await this.pagerService.findAllByRestaurantId(restId); - const pagersData = pagers.map(pager => ({ - id: pager.id, - tableNumber: pager.tableNumber, - message: pager.message, - status: pager.status, - cookieId: pager.cookieId, - createdAt: pager.createdAt, - updatedAt: pager.updatedAt, - user: pager.user - ? { - id: pager.user.id, - firstName: pager.user.firstName, - lastName: pager.user.lastName, - } - : null, - staff: pager.staff - ? { - id: pager.staff.id, - firstName: pager.staff.firstName, - lastName: pager.staff.lastName, - } - : null, - })); + // const pagersData = pagers.map(pager => ({ + // id: pager.id, + // tableNumber: pager.tableNumber, + // message: pager.message, + // status: pager.status, + // cookieId: pager.cookieId, + // createdAt: pager.createdAt, + // updatedAt: pager.updatedAt, + // user: pager.user + // ? { + // id: pager.user.id, + // firstName: pager.user.firstName, + // lastName: pager.user.lastName, + // } + // : null, + // staff: pager.staff + // ? { + // id: pager.staff.id, + // firstName: pager.staff.firstName, + // lastName: pager.staff.lastName, + // } + // : null, + // })); - void client.emit('pagers:list', { pagers: pagersData }); - this.logger.log(`Admin ${client.adminId} requested pagers list for restaurant ${restId}`); - } catch (error) { - this.logger.error(`Error getting pagers list: ${error instanceof Error ? error.message : 'Unknown error'}`); - void client.emit('error', { - message: 'Failed to get pagers list', - code: 'GET_PAGERS_ERROR', - details: error instanceof Error ? error.message : 'Unknown error', - }); - } - } + // void client.emit('pagers:list', { pagers: pagersData }); + // this.logger.log(`Admin ${client.adminId} requested pagers list for restaurant ${restId}`); + // } catch (error) { + // this.logger.error(`Error getting pagers list: ${error instanceof Error ? error.message : 'Unknown error'}`); + // void client.emit('error', { + // message: 'Failed to get pagers list', + // code: 'GET_PAGERS_ERROR', + // details: error instanceof Error ? error.message : 'Unknown error', + // }); + // } + // } /** * Update pager status (admin only) * Requires admin authentication via JWT token * Restaurant ID and Admin ID are extracted from the authenticated admin's token */ - @UseGuards(WsAdminAuthGuard) - @SubscribeMessage('update:pager:status') - async handleUpdatePagerStatus( - @ConnectedSocket() client: AuthenticatedSocket, - @WsRestId() restId: string, - @WsAdminId() adminId: string, - @MessageBody() data: { pagerId: string; status: PagerStatus }, - ) { - try { - if (!data.pagerId || !data.status) { - void client.emit('error', { - message: 'Pager ID and status are required', - code: 'INVALID_PAYLOAD', - }); - return; - } + // @UseGuards(WsAdminAuthGuard) + // @SubscribeMessage('update:pager:status') + // async handleUpdatePagerStatus( + // @ConnectedSocket() client: AuthenticatedSocket, + // @WsRestId() restId: string, + // @WsAdminId() adminId: string, + // @MessageBody() data: { pagerId: string; status: PagerStatus }, + // ) { + // try { + // if (!data.pagerId || !data.status) { + // void client.emit('error', { + // message: 'Pager ID and status are required', + // code: 'INVALID_PAYLOAD', + // }); + // return; + // } - const pager = await this.pagerService.updateStatus(data.pagerId, restId, adminId, data.status); + // const pager = await this.pagerService.updateStatus(data.pagerId, restId, adminId, data.status); - const pagerData = { - id: pager.id, - tableNumber: pager.tableNumber, - message: pager.message, - status: pager.status, - updatedAt: pager.updatedAt, - staff: pager.staff - ? { - id: pager.staff.id, - firstName: pager.staff.firstName, - lastName: pager.staff.lastName, - } - : null, - }; + // const pagerData = { + // id: pager.id, + // tableNumber: pager.tableNumber, + // message: pager.message, + // status: pager.status, + // updatedAt: pager.updatedAt, + // staff: pager.staff + // ? { + // id: pager.staff.id, + // firstName: pager.staff.firstName, + // lastName: pager.staff.lastName, + // } + // : null, + // }; - void client.emit('pager:status:updated:response', { pager: pagerData }); - this.logger.log(`Admin ${adminId} updated pager ${data.pagerId} status to ${data.status}`); - } catch (error) { - this.logger.error(`Error updating pager status: ${error instanceof Error ? error.message : 'Unknown error'}`); - void client.emit('error', { - message: error instanceof Error ? error.message : 'Failed to update pager status', - code: 'UPDATE_PAGER_STATUS_ERROR', - details: error instanceof Error ? error.message : 'Unknown error', - }); - } - } + // void client.emit('pager:status:updated:response', { pager: pagerData }); + // this.logger.log(`Admin ${adminId} updated pager ${data.pagerId} status to ${data.status}`); + // } catch (error) { + // this.logger.error(`Error updating pager status: ${error instanceof Error ? error.message : 'Unknown error'}`); + // void client.emit('error', { + // message: error instanceof Error ? error.message : 'Failed to update pager status', + // code: 'UPDATE_PAGER_STATUS_ERROR', + // details: error instanceof Error ? error.message : 'Unknown error', + // }); + // } + // } // /** // * Emit pager created event to restaurant room diff --git a/src/modules/notifications/processors/sms.processor.ts b/src/modules/notifications/processors/sms.processor.ts index dd733fb..cecbb75 100644 --- a/src/modules/notifications/processors/sms.processor.ts +++ b/src/modules/notifications/processors/sms.processor.ts @@ -8,7 +8,7 @@ import { NotificationQueueJob, NotificationQueueJobResult } from '../interfaces/ import { User } from '../../users/entities/user.entity'; import { NotificationQueueNameEnum } from '../constants/queue'; import { SmsAdaptorService } from '../services/sms.adaptor'; -import { NotificationTitleEnum } from '../interfaces/notification.interface'; +import { NotifTitleEnum } from '../interfaces/notification.interface'; import { ISmsResponse } from '../../utils/interface/sms'; @Processor(NotificationQueueNameEnum.SMS) @@ -38,16 +38,16 @@ export class SmsProcessor extends WorkerHost { } // Check if the notification type is supported for SMS - if (title !== NotificationTitleEnum.ORDER_CREATED && title !== NotificationTitleEnum.PAYMENT_SUCCESS) { + if (title !== NotifTitleEnum.ORDER_CREATED && title !== NotifTitleEnum.PAYMENT_SUCCESS) { throw new Error(`SMS notification type ${title} is not supported`); } // Send SMS notification let smsResult: ISmsResponse; - if (title === NotificationTitleEnum.ORDER_CREATED) { + if (title === NotifTitleEnum.ORDER_CREATED) { smsResult = await this.smsAdaptorService.sendNotifySms({ phone: user.phone, - subject: NotificationTitleEnum.ORDER_CREATED, + subject: NotifTitleEnum.ORDER_CREATED, payload: { orderNumber: '1234567890', orderAmount: 100000, @@ -57,7 +57,7 @@ export class SmsProcessor extends WorkerHost { } else { smsResult = await this.smsAdaptorService.sendNotifySms({ phone: user.phone, - subject: NotificationTitleEnum.PAYMENT_SUCCESS, + subject: NotifTitleEnum.PAYMENT_SUCCESS, payload: { amount: 100000, date: new Date(), diff --git a/src/modules/notifications/services/notification-preference.service.ts b/src/modules/notifications/services/notification-preference.service.ts index dc5a81e..3256328 100644 --- a/src/modules/notifications/services/notification-preference.service.ts +++ b/src/modules/notifications/services/notification-preference.service.ts @@ -4,7 +4,7 @@ import { NotificationPreference } from '../entities/notification-preference.enti import { Restaurant } from '../../restaurants/entities/restaurant.entity'; import { CreatePreferenceDto } from '../dto/create-preference.dto'; import { UpdatePreferenceDto } from '../dto/update-preference.dto'; -import { NotificationTitleEnum } from '../interfaces/notification.interface'; +import { NotifTitleEnum } from '../interfaces/notification.interface'; @Injectable() export class NotificationPreferenceService { @@ -32,10 +32,7 @@ export class NotificationPreferenceService { }); } - async findByRestaurantAndType( - restaurantId: string, - title: NotificationTitleEnum, - ): Promise { + async findByRestaurantAndType(restaurantId: string, title: NotifTitleEnum): Promise { return this.em.findOne(NotificationPreference, { restaurant: { id: restaurantId }, title, diff --git a/src/modules/notifications/services/notification.service.ts b/src/modules/notifications/services/notification.service.ts index 3e80ac1..efffea3 100644 --- a/src/modules/notifications/services/notification.service.ts +++ b/src/modules/notifications/services/notification.service.ts @@ -7,12 +7,12 @@ import { NotificationQueueJob } from '../interfaces/notification-queue.interface import { Restaurant } from '../../restaurants/entities/restaurant.entity'; import { User } from '../../users/entities/user.entity'; import { NotificationType } from '../interfaces/notification.interface'; -import { NotificationTitleEnum } from '../interfaces/notification.interface'; +import { NotifTitleEnum } from '../interfaces/notification.interface'; export interface SendNotificationParams { restaurantId: string; userId?: string; - title: NotificationTitleEnum; + title: NotifTitleEnum; content: string; idempotencyKey?: string; } @@ -45,7 +45,7 @@ export class NotificationService { } // Generate idempotency key if not provided - const finalIdempotencyKey = idempotencyKey || `${restaurantId}-${title}-${Date.now()}`; + // const finalIdempotencyKey = idempotencyKey || `${restaurantId}-${title}-${Date.now()}`; // Create notification record const user = userId ? await this.em.findOne(User, { id: userId }) : undefined; @@ -69,7 +69,7 @@ export class NotificationService { userId, title, content, - idempotencyKey: finalIdempotencyKey, + // idempotencyKey: finalIdempotencyKey, notificationId: notification.id, notificationType: preference.notificationType, }; @@ -126,11 +126,7 @@ export class NotificationService { await this.em.removeAndFlush(notification as any); } - async findByRestaurantAndType( - restaurantId: string, - title: NotificationTitleEnum, - limit = 50, - ): Promise { + async findByRestaurantAndType(restaurantId: string, title: NotifTitleEnum, limit = 50): Promise { return this.em.find( Notification, { diff --git a/src/modules/notifications/services/sms.adaptor.ts b/src/modules/notifications/services/sms.adaptor.ts index c5829b7..2885fe1 100644 --- a/src/modules/notifications/services/sms.adaptor.ts +++ b/src/modules/notifications/services/sms.adaptor.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { SmsService } from 'src/modules/utils/sms.service'; import { ISmsNotifyPayload } from '../interfaces/notification.interface'; -import { NotificationTitleEnum } from '../interfaces/notification.interface'; +import { NotifTitleEnum } from '../interfaces/notification.interface'; @Injectable() export class SmsAdaptorService { @@ -20,10 +20,10 @@ export class SmsAdaptorService { const { phone, subject, payload } = params; let templateId!: string; switch (subject) { - case NotificationTitleEnum.ORDER_CREATED: + case NotifTitleEnum.ORDER_CREATED: templateId = this.smsPatternOrderCreated; break; - case NotificationTitleEnum.PAYMENT_SUCCESS: + case NotifTitleEnum.PAYMENT_SUCCESS: templateId = this.smsPatternPaymentSuccess; break; } diff --git a/src/seeders/data/notification-preferences.data.ts b/src/seeders/data/notification-preferences.data.ts index 6568603..6490cd6 100644 --- a/src/seeders/data/notification-preferences.data.ts +++ b/src/seeders/data/notification-preferences.data.ts @@ -1,26 +1,26 @@ -import { NotificationTitleEnum } from '../../modules/notifications/interfaces/notification.interface'; +import { NotifTitleEnum } from '../../modules/notifications/interfaces/notification.interface'; import { NotificationType } from '../../modules/notifications/interfaces/notification.interface'; export interface NotificationPreferenceData { - title: NotificationTitleEnum; + title: NotifTitleEnum; notificationType: NotificationType; } export const notificationPreferencesData: NotificationPreferenceData[] = [ { - title: NotificationTitleEnum.ORDER_CREATED, + title: NotifTitleEnum.ORDER_CREATED, notificationType: NotificationType.SMS, }, { - title: NotificationTitleEnum.PAYMENT_SUCCESS, + title: NotifTitleEnum.PAYMENT_SUCCESS, notificationType: NotificationType.SMS, }, { - title: NotificationTitleEnum.REVIEW_CREATED, + title: NotifTitleEnum.REVIEW_CREATED, notificationType: NotificationType.PUSH, }, { - title: NotificationTitleEnum.ORDER_STATUS_CHANGED, + title: NotifTitleEnum.ORDER_STATUS_CHANGED, notificationType: NotificationType.Both, }, ];