feat(notifications): add multi-channel notification module with Email, FCM, templates, and event listeners

- Domain: NotificationLog/NotificationPreference entities, repositories, channel value object
- Infrastructure: EmailService (nodemailer/SMTP), FcmService (firebase-admin), TemplateService (Handlebars)
- Application: SendNotification CQRS command, UserRegistered + AgentVerified event listeners
- Presentation: NotificationsController with history, preferences, and templates endpoints
- Prisma: NotificationLog and NotificationPreference models with proper indexes
- Templates: Vietnamese notification templates for user.registered, agent.verified, listing.approved, inquiry.received, password.reset

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-08 01:42:17 +07:00
parent 9301f44119
commit 0b29fac35e
42 changed files with 1720 additions and 6 deletions

View File

@@ -0,0 +1,48 @@
import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
// Domain
import { NOTIFICATION_REPOSITORY } from './domain/repositories/notification.repository';
import { NOTIFICATION_PREFERENCE_REPOSITORY } from './domain/repositories/notification-preference.repository';
// Infrastructure
import { PrismaNotificationRepository } from './infrastructure/repositories/prisma-notification.repository';
import { PrismaNotificationPreferenceRepository } from './infrastructure/repositories/prisma-notification-preference.repository';
import { EmailService } from './infrastructure/services/email.service';
import { FcmService } from './infrastructure/services/fcm.service';
import { TemplateService } from './infrastructure/services/template.service';
// Application
import { SendNotificationHandler } from './application/commands/send-notification/send-notification.handler';
import { UserRegisteredListener } from './application/listeners/user-registered.listener';
import { AgentVerifiedListener } from './application/listeners/agent-verified.listener';
// Presentation
import { NotificationsController } from './presentation/controllers/notifications.controller';
const CommandHandlers = [SendNotificationHandler];
const EventListeners = [UserRegisteredListener, AgentVerifiedListener];
@Module({
imports: [CqrsModule],
controllers: [NotificationsController],
providers: [
// Repositories
{ provide: NOTIFICATION_REPOSITORY, useClass: PrismaNotificationRepository },
{ provide: NOTIFICATION_PREFERENCE_REPOSITORY, useClass: PrismaNotificationPreferenceRepository },
// Services
EmailService,
FcmService,
TemplateService,
// CQRS
...CommandHandlers,
// Event Listeners
...EventListeners,
],
exports: [EmailService, FcmService, TemplateService],
})
export class NotificationsModule {}