import 'server-only'; import { getEmailConfigurationForUse } from '@/features/foundation/email/server/email-config.service'; import { SmtpEmailProvider } from '@/features/foundation/email/server/smtp-provider'; import type { NotificationChannel, NotificationProvider, NotificationProviderSendInput, NotificationProviderSendResult, } from '../types'; export class EmailNotificationProvider implements NotificationProvider { readonly channel: NotificationChannel = 'email'; readonly key = 'smtp'; constructor(private readonly organizationId: string) {} private async resolveConfig() { const config = await getEmailConfigurationForUse(this.organizationId, 'smtp'); if (!config) { throw new Error('No active SMTP email configuration was found for this organization.'); } return config; } async validate() { await this.resolveConfig(); } async healthCheck() { try { const config = await this.resolveConfig(); const provider = new SmtpEmailProvider(); const result = await provider.testConnection(config); return result.ok ? { ok: true } : { ok: false, detail: result.detail ?? 'SMTP health check failed.' }; } catch (error) { return { ok: false, detail: error instanceof Error ? error.message : 'Unknown SMTP health check failure', }; } } async send(input: NotificationProviderSendInput): Promise { const config = await this.resolveConfig(); const provider = new SmtpEmailProvider(); return provider.sendEmail(config, { subject: input.subject, text: input.bodyText, html: input.bodyHtml, to: input.to, cc: input.cc, bcc: input.bcc, replyTo: input.replyTo, attachments: input.attachments.map((attachment, index) => ({ fileName: attachment.fileName, contentType: attachment.contentType, buffer: input.attachmentBuffers[index] ?? Buffer.alloc(0), })), }); } }