import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import type { CreateChannelDto, UpdateChannelDto, CreateChannelGroupDto, CreateChannelGroupItemDto, UpdateChannelGroupDto, CreateRouteRuleDto, CreateReportFieldDto, ReplaceReportFieldsDto, CreateReportMaterialDto, CreateReportTaskDto, ChangeReportTaskStatusesDto, CreateReportExportDto, CreateReceiptImportDto, UpsertConnectionStateDto, ChangeChannelStatusDto, CopyChannelDto, TestChannelDto, } from './channels.contracts'; import { ChannelConfigurationService } from './channel-configuration.service'; import { ChannelConnectionService } from './channel-connection.service'; import { ChannelCopyService } from './channel-copy.service'; import { ChannelDeletionService } from './channel-deletion.service'; import { ChannelGroupRoutingService } from './channel-group-routing.service'; import { ChannelReportingService } from './channel-reporting.service'; import { ChannelTestService } from './channel-test.service'; /** Stable compatibility facade; R5 delegates channel behavior to focused domains. */ @Injectable() export class ChannelsService implements OnModuleInit, OnModuleDestroy { private readonly connection: ChannelConnectionService; private readonly configuration: ChannelConfigurationService; private readonly testing: ChannelTestService; private readonly groups: ChannelGroupRoutingService; private readonly reporting: ChannelReportingService; private readonly copy: ChannelCopyService; private readonly deletion: ChannelDeletionService; constructor(prisma: PrismaService) { this.connection = new ChannelConnectionService(prisma); this.configuration = new ChannelConfigurationService(prisma, this.connection); this.testing = new ChannelTestService(prisma, this.connection); this.groups = new ChannelGroupRoutingService(prisma); this.reporting = new ChannelReportingService(prisma); this.copy = new ChannelCopyService(prisma); this.deletion = new ChannelDeletionService(prisma, this.configuration); } onModuleInit() { return this.connection.onModuleInit(); } async onModuleDestroy() { return this.connection.onModuleDestroy(); } listChannels() { return this.configuration.listChannels(); } async listChannelsPage(query: { keyword?: string; carrier?: string; status?: string; page?: number; pageSize?: number; }) { return this.configuration.listChannelsPage(query); } async createChannel(data: CreateChannelDto) { return this.configuration.createChannel(data); } async updateChannel(channelId: string, data: UpdateChannelDto) { return this.configuration.updateChannel(channelId, data); } async changeChannelStatus(channelId: string, data: ChangeChannelStatusDto) { return this.configuration.changeChannelStatus(channelId, data); } async copyChannel(channelId: string, data: CopyChannelDto = {}) { return this.copy.copyChannel(channelId, data); } async deleteChannel(channelId: string, data: ChangeChannelStatusDto = { status: 'deleted' }) { return this.deletion.deleteChannel(channelId, data); } async testChannel(channelId: string, data: TestChannelDto = {}) { return this.testing.testChannel(channelId, data); } listChannelMetrics(channelId: string) { return this.connection.listChannelMetrics(channelId); } listChannelConnections(channelId: string) { return this.connection.listChannelConnections(channelId); } async listChannelConnectionLogs(channelId: string) { return this.connection.listChannelConnectionLogs(channelId); } listTenantConnections(tenantId: string) { return this.connection.listTenantConnections(tenantId); } async upsertConnectionState(data: UpsertConnectionStateDto) { return this.connection.upsertConnectionState(data); } async markTimedOutConnectingChannels(now = new Date()) { return this.connection.markTimedOutConnectingChannels(now); } listGroups() { return this.groups.listGroups(); } createGroup(data: CreateChannelGroupDto) { return this.groups.createGroup(data); } async addGroupItem(data: CreateChannelGroupItemDto) { return this.groups.addGroupItem(data); } async updateGroup(groupId: string, data: UpdateChannelGroupDto) { return this.groups.updateGroup(groupId, data); } async deleteGroup(groupId: string) { return this.groups.deleteGroup(groupId); } getGroupDeletionImpact(groupId: string) { return this.groups.getGroupDeletionImpact(groupId); } listRouteRules() { return this.groups.listRouteRules(); } async createRouteRule(data: CreateRouteRuleDto) { return this.groups.createRouteRule(data); } listReportFields(channelId?: string) { return this.reporting.listReportFields(channelId); } async createReportField(data: CreateReportFieldDto) { return this.reporting.createReportField(data); } async replaceReportFields(channelId: string, reportType: 'signature' | 'drainage', data: ReplaceReportFieldsDto) { return this.reporting.replaceReportFields(channelId, reportType, data); } listReportMaterials(signatureId?: string, channelId?: string) { return this.reporting.listReportMaterials(signatureId, channelId); } upsertReportMaterial(data: CreateReportMaterialDto) { return this.reporting.upsertReportMaterial(data); } async listReportTasks(tenantId?: string, status?: string, channelId?: string, reportType?: string) { return this.reporting.listReportTasks(tenantId, status, channelId, reportType); } async listReportTasksPage(query: { tenantId?: string; applicationId?: string; status?: string; channelId?: string; reportType?: string; keyword?: string; carrier?: string; todaySendMin?: number; todaySendMax?: number; sort?: string; createdAtFrom?: string; createdAtTo?: string; page?: number; pageSize?: number; }) { return this.reporting.listReportTasksPage(query); } async listReportDetailsPage(query: { tenantId?: string; applicationId?: string; signatureId?: string; channelId?: string; carrier?: string; status?: string; reportType?: string; keyword?: string; createdAtFrom?: string; createdAtTo?: string; page?: number; pageSize?: number; }) { return this.reporting.listReportDetailsPage(query); } async createReportTask(data: CreateReportTaskDto) { return this.reporting.createReportTask(data); } async changeReportTaskStatuses(data: ChangeReportTaskStatusesDto) { return this.reporting.changeReportTaskStatuses(data); } async createReportExport(taskId: string, data: CreateReportExportDto) { return this.reporting.createReportExport(taskId, data); } async importReportReceipt(taskId: string, data: CreateReceiptImportDto) { return this.reporting.importReportReceipt(taskId, data); } listReportRecords(taskId?: string, channelId?: string) { return this.reporting.listReportRecords(taskId, channelId); } async listReportRecordsPage(query: { taskId?: string; channelId?: string; batchNo?: string; statusAfter?: string; action?: string; sourceEntry?: string; operatorKeyword?: string; keyword?: string; reportType?: string; createdAtFrom?: string; createdAtTo?: string; page?: number; pageSize?: number; }) { return this.reporting.listReportRecordsPage(query); } async reconcileGatewayConnections(now = new Date()) { return this.connection.reconcileGatewayConnections(now); } /** Preserves the existing private restart-replay test seam. */ private reconnectActiveChannelsAfterGatewayRestart() { return this.connection.reconnectActiveChannelsAfterGatewayRestart(); } }