diff --git a/src/email/email-report.entity.ts b/src/email/email-report.entity.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/email/email-report.service.ts b/src/email/email-report.service.ts new file mode 100644 index 00000000..a5e0fc08 --- /dev/null +++ b/src/email/email-report.service.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; + +@Injectable() +export class EmailReportService { + constructor(private readonly prisma: PrismaService) {} + + async recordDelivery(emailId: string, status: 'delivered' | 'bounced' | 'opened' | 'clicked') { + return this.prisma.emailReport.create({ + data: { + emailId, + delivered: status === 'delivered', + bounced: status === 'bounced', + opened: status === 'opened', + clicked: status === 'clicked', + }, + }); + } + + async getMetrics() { + const total = await this.prisma.emailReport.count(); + const delivered = await this.prisma.emailReport.count({ where: { delivered: true } }); + const bounced = await this.prisma.emailReport.count({ where: { bounced: true } }); + const opened = await this.prisma.emailReport.count({ where: { opened: true } }); + const clicked = await this.prisma.emailReport.count({ where: { clicked: true } }); + + return { + deliveryRate: delivered / total, + bounceRate: bounced / total, + openRate: opened / total, + clickRate: clicked / total, + }; + } +} diff --git a/src/email/email.controller.ts b/src/email/email.controller.ts new file mode 100644 index 00000000..45898554 --- /dev/null +++ b/src/email/email.controller.ts @@ -0,0 +1,12 @@ +import { Controller, Get } from '@nestjs/common'; +import { EmailReportService } from './email-report.service'; + +@Controller('emails') +export class EmailController { + constructor(private readonly reportService: EmailReportService) {} + + @Get('reports') + async getReports() { + return this.reportService.getMetrics(); + } +} diff --git a/src/notifications/notification-preferences.entity.ts b/src/notifications/notification-preferences.entity.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/notifications/notification-throttle.util.ts b/src/notifications/notification-throttle.util.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/notifications/notification.controller.ts b/src/notifications/notification.controller.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/notifications/notification.service.ts b/src/notifications/notification.service.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/utils/observability.ts b/src/utils/observability.ts new file mode 100644 index 00000000..e79acfde --- /dev/null +++ b/src/utils/observability.ts @@ -0,0 +1,10 @@ +export function logEmailEvent(emailId: string, event: string, correlationId?: string) { + console.log(JSON.stringify({ + level: 'info', + type: 'email', + emailId, + event, + correlationId, + timestamp: new Date().toISOString(), + })); +}