inmemory to postgres

This commit is contained in:
2025-12-29 20:50:03 +01:00
parent 12ae6e1dad
commit 3f610c1cb6
64 changed files with 3689 additions and 63 deletions

View File

@@ -0,0 +1,52 @@
import type { Notification } from '@core/notifications/domain/entities/Notification';
import type { NotificationChannel } from '@core/notifications/domain/types/NotificationTypes';
import type { NotificationGateway, NotificationGatewayRegistry, NotificationDeliveryResult } from '@core/notifications/application/ports/NotificationGateway';
export class InMemoryNotificationGatewayRegistry implements NotificationGatewayRegistry {
private gateways: Map<NotificationChannel, NotificationGateway> = new Map();
register(gateway: NotificationGateway): void {
this.gateways.set(gateway.getChannel(), gateway);
}
getGateway(channel: NotificationChannel): NotificationGateway | null {
return this.gateways.get(channel) || null;
}
getAllGateways(): NotificationGateway[] {
return Array.from(this.gateways.values());
}
async send(notification: Notification): Promise<NotificationDeliveryResult> {
const gateway = this.gateways.get(notification.channel);
if (!gateway) {
return {
success: false,
channel: notification.channel,
error: `No gateway registered for channel ${notification.channel}`,
attemptedAt: new Date(),
};
}
if (!gateway.isConfigured()) {
return {
success: false,
channel: notification.channel,
error: `Gateway for ${notification.channel} is not configured`,
attemptedAt: new Date(),
};
}
try {
return await gateway.send(notification);
} catch (error) {
return {
success: false,
channel: notification.channel,
error: error instanceof Error ? error.message : String(error),
attemptedAt: new Date(),
};
}
}
}

View File

@@ -0,0 +1,48 @@
import type { NotificationService, SendNotificationCommand } from '@core/notifications/application/ports/NotificationService';
import type { INotificationRepository } from '@core/notifications/domain/repositories/INotificationRepository';
import type { INotificationPreferenceRepository } from '@core/notifications/domain/repositories/INotificationPreferenceRepository';
import type { NotificationGatewayRegistry } from '@core/notifications/application/ports/NotificationGateway';
import { SendNotificationUseCase } from '@core/notifications/application/use-cases/SendNotificationUseCase';
import type { Logger } from '@core/shared/application';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
class NoOpOutputPort implements UseCaseOutputPort<any> {
present(_result: any): void {
// No-op for adapter
}
}
export class NotificationServiceAdapter implements NotificationService {
private readonly useCase: SendNotificationUseCase;
private readonly logger: Logger;
constructor(
notificationRepository: INotificationRepository,
preferenceRepository: INotificationPreferenceRepository,
gatewayRegistry: NotificationGatewayRegistry,
logger: Logger,
) {
this.logger = logger;
this.useCase = new SendNotificationUseCase(
notificationRepository,
preferenceRepository,
gatewayRegistry,
new NoOpOutputPort(),
logger,
);
}
async sendNotification(command: SendNotificationCommand): Promise<void> {
const result = await this.useCase.execute(command);
if (result.isErr()) {
const error = result.error;
if (error) {
this.logger.error('Failed to send notification', new Error(error.details.message));
throw new Error(error.details.message);
} else {
throw new Error('Unknown error sending notification');
}
}
}
}