# 阶段 4 通道与报备实施计划 ## 目标 让运营端能配置短信通道、通道组、路由规则和签名报备流程;让系统能记录签名在各通道的报备资料、报备任务、导出文件、回执导入和状态同步。 阶段 4 不实现真实发送链路,真实 CMPP 提交在阶段 7 发送链路接入;本阶段只建立通道和报备配置闭环。 ## 实施步骤 1. Prisma 模型 - `SmsChannel` - `SmsChannelGroup` - `SmsChannelGroupItem` - `ChannelRouteRule` - `ChannelHealthMetric` - `ChannelReportField` - `SignatureReportMaterial` - `ChannelSignatureReportTask` - `ChannelSignatureReportRecord` - `ReportExportFile` - `ReportReceiptImport` 2. NestJS 模块 - `ChannelsModule` - 通道 CRUD、测试短信占位、通道健康指标查询。 - 通道组 CRUD、通道组成员配置。 - 路由规则 CRUD。 - 报备字段配置 CRUD。 - 签名报备资料登记。 - 报备任务生成、导出记录、回执导入记录、报备记录查询。 3. 状态同步 - 生成报备任务时记录 `pending`。 - 导出报备资料时记录导出文件和报备记录。 - 导入回执时记录导入批次、回执结果,并更新任务状态。 4. 验证 - `cd api && npm run prisma:generate` - `cd api && npm run build` - API health 冒烟 - `npm run verify:phase3` ## 验收标准 - Prisma Client 生成成功。 - API 构建成功。 - `ChannelsModule` 被 AppModule 引入。 - 通道、通道组、路由规则、报备字段、报备任务基础接口存在。 - 报备导出/导入记录和报备状态同步接口存在。 - 阶段 4 进度文档记录验证结果。 ## 2026-09-17 有效签名名称唯一性 本节补充签名新增、修改和状态恢复规则;批量导入仍遵循 [补资料方案](reporting-batch-import-records-remediation-plan-20260902.md) 的字段合并规则。 - 同一企业、同一应用下,完整签名名称精确相同时只能存在一条有效记录。有效指审核状态不是 `deleted` 或 `disabled`,包含草稿、待审、通过和驳回。未绑定应用作为独立范围,同企业未绑定应用的同名有效签名也唯一;不同企业、不同应用允许同名。 - 新增、改名、换应用、提交审核、审核及状态恢复均执行接口查重,修改排除自身;冲突返回 HTTP 409 和“同一企业、同一应用下已存在同名有效签名,请修改已有签名资料”。保留既有认证、租户校验、审核及报备资料行为,无新增权限、页面和短信链路变更。 - PostgreSQL 使用两个部分唯一索引:绑定应用的 `(tenantId, applicationId, name)`,未绑定应用的 `(tenantId, name)`,都排除停用及删除状态。并发以数据库最终约束为准,唯一冲突转为相同业务错误;Prisma schema 用注释指明 SQL 所有权,不用普通复合唯一键冒充部分索引。 - 迁移在事务和写锁内检查历史有效重名;发现冲突则明确报错、整体回滚,禁止自动删除、合并或改状态。发布前需只读盘点并另行确认历史治理,不把迁移阻断当作成功;本轮只本地提交,不部署。 - 批量导入仍是补资料:优先匹配同范围有效签名,其次沿用未删除的停用记录;原签名 ID、未映射字段、用途及关联记录保留。导入暂存后新增了同名签名时,审核阶段重新匹配并更新;并发创建冲突时重新读取有效记录转为资料更新,仅重试一次,不吞其他错误。已有指定目标不会暗中改写为另一条记录,恢复冲突明确失败。 - 验收覆盖新增/编辑/换应用/空应用/状态恢复、不同企业应用、并发创建、直接 SQL 防重、历史迁移失败回滚,以及导入暂存与审核后补资料保留。使用本机隔离 PostgreSQL 和真实服务/API,不发送短信,不改线上资料;线上历史数据与部署留作未验证项。