Files
lislgosms/docs/testing-progress.md
T

596 KiB
Raw Blame History

第一版系统化测试进度

环境命名:当前 8.160.169.106:12026Web/API)和 8.160.169.106:17890(CMPP 入站)实例统一定义为“预发布环境”。历史记录中涉及该实例的验证、部署和业务页面均按预发布环境理解;production-deploy.shNODE_ENV=production 及正式生产安全/备份规范保留原有技术语义,不代表该实例为正式生产。

2026-08-12 企业签名弹窗、充值回执、通道列表与金额显示优化(已提交、已部署)

  • 已确认企业签名报备状态采用“三列运营商分区”方案,运营商标签采用低饱和胶囊方案;本批同步调整充值回执密度、通道今日提交后端排序、零提交比率展示和成本费率布局。
  • 撤回金额小数弱化规则:所有只读金额恢复同字号同色,最多展示4位并裁掉末尾0;通道成本费率固定4位。运营看板今日消费和企业应用单价恢复正常主数字深色样式。
  • 不涉及数据库结构或生产数据迁移。通道服务专项 1 suite/46 项、API 全量 35 suites/453 项、前后端 TypeScript/构建、Gateway go test ./...go vet ./...、4 份队列结构契约及 git diff --check 已通过;Vite 仅保留既有大分块 warning,测试中的 Redis unavailable 和预期异常日志均为既有受控分支,未伪造外部依赖。
  • 应用内浏览器连接真实本地 NestJS、PostgreSQL、Redis 和 production preview 验收:1366×768 下三运营商报备状态弹窗横向三分区且页面无横向溢出;普通充值回执内容区 scrollHeight=clientHeight=546,无需滚动即可看到完成按钮;通道零提交四个比率均为深灰短杠,移动/联通/电信低饱和胶囊色互不相同;运营看板今日消费为 30px 深黑主数字,企业应用单价为深色常规字号。820px 复核弹窗改为单列且页面无横向溢出,浏览器 console error/warn 为 0。验收未保存报备状态、未充值、未启停或编辑通道、未发送短信。
  • 功能提交 f350bf5ef333c78756505e1d895768c46fe73c72 已推送并部署预发布。发布包 outputs/cmpp-f350bf5e-20260812-131846.tar.gz 的本地/服务器 SHA-256 均为 990a1e0d5fcf69662a73fa0d61a837460858c5dfe9d3ba44495c08b139eb32df;运行目录 .deployed-commit 回读与功能提交完全一致。
  • 有效发布前备份位于 /opt/cmpp-platform-backups/releases/20260812-132030-before-f350bf5e,PostgreSQL、旧运行源码和环境文件均非空并通过 sha256sum -c;旧运行目录保留为 /opt/cmpp-platform.previous-20260812-132030。第一次备份因 Prisma URL 的 schema 参数不被 pg_dump 接受而在切换运行目录前安全中止,其目录 /opt/cmpp-platform-backups/releases/20260812-131846-before-f350bf5e 保留为中止证据;第二次仅在传给 pg_dump 时移除该客户端专用参数,未修改线上环境文件。
  • 预发布 85 条 migration 全部完成且无待执行;API、Gateway、Nginx、PostgreSQL 均 active3000/8090/12026/17890/9000 正常监听,运营端、客户端和公网 API 均返回 200。Redis Stream 为 consumer=1/pending=0/lag=0,发布后 API/Gateway error 日志为 0,前端实际产物为 index-C2qqOO8d.jsindex-D1lUWX4h.css。发布过程未发送、补发或重投真实短信,未修改通道账号、密码、启停状态、企业余额或客户连接配置。

2026-08-12 签名热力图、登录动画、金额样式与利润口径(已提交、已部署)

  • 功能提交 0cd353450abb999bd9c192c6df482af5e07095b5 已推送并部署预发布。签名热力图新增 T-1~T-30 合计并按发送量降序,观察期继续保存真实单日快照但不触发预警;企业签名企业/应用文字改为常规字重,客户端登录框新增可降级的 Canvas 动画,金额展示统一弱化小数部分。
  • 同批发布此前未提交的利润报表口径调整:净消费改为收入,收入按成功条数乘企业应用单价计算,返还字段和返还合计从 API、类型与页面移除。
  • 本地真实 PostgreSQL 验证检测幂等且不增加站内消息或 webhook 投递;定向 2 suites/18 项、API 全量 35 suites/451 项、前后端 TypeScript/构建、Gateway go test ./...go vet ./...、队列结构契约和 git diff --check 均通过。Vite 仅保留既有大分块 warning。
  • 本地浏览器确认登录页 Canvas 存在且无控制台错误,热力图显示 30 日合计并降序,金额小数部分使用弱化色,企业/应用文字字重为 400。生产浏览器新标签连接超时,未把该次生产可见验收记为通过;生产 HTML/API、构建产物和真实数据库回读均正常。
  • 发布包 outputs/cmpp-0cd35345-20260812-114757.tar.gz 的本地/服务器 SHA-256 均为 593b90045694a6e1bda2ff0b75e971b4fdbe9b5d99f1fa5960a31a439c0c0c8f。有效发布前备份位于 /opt/cmpp-platform-backups/releases/20260812-115100-before-0cd35345,PostgreSQL、旧运行源码和环境文件均非空并通过 sha256sum -c;旧运行目录保留为 /opt/cmpp-platform.previous-20260812-115100。首次短连接备份在生成校验清单前中断,未切换线上目录,其不完整事故目录 /opt/cmpp-platform-backups/releases/20260812-114757-before-0cd35345 被保留而未冒充可恢复备份。
  • 预发布 85 条 migration 全部完成且无待执行项;API、Gateway、Nginx、PostgreSQL、Redis 和 MinIO 端口/health 正常,Redis Stream 为 consumer=1/pending=0/lag=0,发布后 API/Gateway error 日志为 0。启动补偿生成 2026-08-12 的 234 条观察期快照;受控补齐 2026-08-11 快照 132 条后,预警周期、站内消息和 webhook 投递仍全部为 0,没有发送、补发或重投真实短信。
  • 生产真实数据库确认 【榆林市供热有限公司】 的 2026-08-12 检测快照对应 2026-08-11 活动,企业维度移动 2494、联通 1029、电信 1489,合计 5012;热力图不再因报备观察期而吞掉该日发送数据。

2026-07-16 客户端签名与引流信息页面重做(已提交、已部署)

  • 客户端“签名与引流信息”按运营端信息结构重做为签名父级、引流信息子级的可展开工作台,增加真实后端状态统计、关键字/应用/状态筛选、已交资料数、修改说明、新增/修改/删除确认;客户端文案不再出现通道和内部报备概念。
  • 新增客户端专用安全视图和工作台 API。NestJS 查询仅选择客户需要的签名、应用、材料和引流字段;动态资料字段移除通道来源,签名响应移除通道、路由、运营商汇总、报备任务和内部要求快照,避免只靠前端隐藏造成泄露。
  • 客户端签名更新补充企业归属校验并重新进入审核;签名列表的顶部统计由 PostgreSQL 状态分组通过真实 API 返回,不使用 mock、localStorage 或前端临时统计冒充。
  • Prisma validate/generate/migrate status 通过,本地 PostgreSQL 共 52 条 migration 且无待执行项;SmsConfig 定向 1 suite/37 项、API 全量 20 suites/209 项、API build、前端 build、Gateway go test ./...git diff --check 均通过。Jest 延续既有 open-handle 提示,使用同一全量用例加 --forceExit 复核退出码为 0;前端仅有既有 Vite chunk size warning。
  • 应用内浏览器可加载最新本地构建,但目标路由因无现成客户端登录态跳转至真实图形验证码登录页;Chrome 也没有可复用的平台登录页。本轮未绕过验证码,因此没有把登录页误记为目标页面视觉通过,登录后的展开、筛选和弹窗交互仍建议补一次可见复测。

2026-07-15 短信模板签名自动填充与真实校验(已提交、已部署)

  • 客户端和运营端短信模板表单将签名改为必选;选择签名时自动在模板内容开头填入规范 【签名】,切换签名只替换原前缀并保留正文,清空选择时移除自动前缀。
  • 两套内容输入框均明确提示“模板内容必须以所选签名开头”,字符数、变量识别和计费条数继续基于包含签名的完整内容计算。
  • NestJS 在模板创建、编辑和提交审核时校验真实签名归属及完整内容前缀,阻止绕过页面提交缺失或不匹配签名的模板。SmsConfig 定向 1 suite/33 项、API 全量 18 suites/194 项、Prisma validate/generate/migrate status47 条 migration 已应用)、API build、前端 build、Gateway go test ./...git diff --check 均通过;Jest 仍有既有 open-handle 提示,相同全量测试加 --forceExit 复核退出码为 0。浏览器交互结果待完成后回填。
  • 应用内浏览器可正常加载最新本地构建,页面标题、登录表单和控制台均正常;本地会话已过期并跳转图形验证码登录页,未绕过验证码进入模板表单,因此没有把目标表单交互误记为浏览器通过。自动填入/替换逻辑由共享纯函数、前端生产构建和真实后端定向/全量测试覆盖,仍建议登录后补一次可见交互复测。

2026-07-15 运营列表排序、短信批量驳回与通道成本展示(已提交、已部署)

  • 短信审核页增加“驳回已选”,统一填写非空原因后调用真实 /admin/risk-review/tasks/batch/reject;NestJS 对 id 去重、限制单批最多 100 条并逐项执行现有风控拒绝和发送链路拒绝处理,不使用前端本地状态冒充完成。
  • 企业管理接口按 PostgreSQL 当日短信消费 todaySpendCents 降序返回;企业应用管理接口按 PostgreSQL 当日短信记录 sentToday 降序返回;两者相同指标均以名称和 id 稳定排序。
  • 通道列表成本继续读取真实 unitPrice,仅将展示格式调整为“X.XX 分”,不修改计费或成本快照精度。
  • 功能与接入号改动提交 3e114ee7294e502ab8a65f84891fd2e1258a00c1 已 push 并部署生产;发布包本地/服务器 SHA-256 均为 8d84c15d2d95c79c38a57af8e74588f1ef52f5550e6eb54d881eb2cb74ac7d1d
  • 部署前生产 PostgreSQL、运行源码和环境文件备份目录为 /opt/cmpp-platform/backups/releases/20260715-154713;三份文件均非空并通过 sha256sum -c,数据库、源码、环境 SHA-256 分别为 12c372c9ccc65a815444b59cd5856864128b25f137a5fc141bec91084b2f09218100e7f88275e87fe7ccca89ceeb76443488335972076a767c6c29d64b94471287ab2efd509b39849b0ee22ead1b4cf0568fba4ab8525c59b5c78da51c73bc86
  • 本地定向 3 suites/46 项、API 全量 18 suites/192 项、API build、前端 build、Gateway 全量 Go 测试、Prisma validate/generate/migrate status 和 git diff --check 均通过。Jest 仍有既有 open-handle 退出提示,使用相同全量测试集加 --forceExit 复核退出码为 0。
  • 生产第 47 条 migration 已成功应用且无待执行项;API、Gateway、MinIO、Nginx、PostgreSQL、Redis 均 active12026/17890/8090/3000/9000 监听,内外 health、首页、运营登录页、Redis 和 PostgreSQL 均通过。真实 PostgreSQL 当日企业消费和应用发送量查询按降序返回,产物包含批量拒绝路由、“驳回已选”和接入号填充交互,废弃设计文档已从运行源码删除,部署后 API/Gateway 无新增 error。
  • 应用内浏览器确认生产运营登录页标题、表单和验证码正常渲染,无框架错误覆盖或控制台错误;点击验证码后题目由 43 + 8 更新为 46 + 6。因浏览器无现成运营登录态且图形验证码需要人工确认,未执行登录后批量拒绝的破坏性真实任务操作,相关闭环由真实 API/数据库/产物及后端测试验收。

2026-07-15 企业应用接入号填充与扩展码(已提交、已部署)

  • 已删除未落地且容易被误作实现依据的 docs/access-number-upstream-downstream-design.md,正式口径改为企业应用级“应用扩展码 + 可选客户接入号填充前缀”。
  • 企业应用新增真实 PostgreSQL 配置:应用扩展码、填充开关、填充前缀和全局唯一客户侧 Src_Id。管理端仅在开启填充时展示可编辑前缀,并实时只读预览客户侧接入号。
  • 配置扩展码后,NestJS 在任务、计费和入队前严格校验客户 CMPP Src_Id;新短信保存客户侧号码与应用扩展码快照。上游 Submit 只使用“通道基础号 + 应用扩展码”,客户填充前缀不进入上游。未配置扩展码的历史应用保持原通道基础号行为。
  • 本地 PostgreSQL 已应用第 47 条 migrationPrisma format/validate/generate/migrate status 通过。SmsConfig/SendChain 定向 2 suites/88 项、API 全量 18 suites/188 项、API build、前端 build、Gateway go test ./... 均通过;前端仅有既有 Vite chunk size warning。Jest 全量用例全部通过但存在既有 open handle,使用 --forceExit 取得明确退出码 0。应用内浏览器确认本地站点、运营登录页和控制台正常,但真实登录及图形验证码阻断表单页,未将条件显示交互误记为浏览器已验收。

2026-07-15 报表与通用报备字段生产发布

  • 功能提交 8c3336600e900667d8bb77fd6e0fb5fe40986c11 已 push 到 origin/main 并部署生产,覆盖对账单、利润报表、发送质量报表和通用报备字段/签名资料动态化全部工作区改动。发布包本地与服务器 SHA-256 均为 94f59561f1a5a2255bb188007a6ce73fd1549ba33ca9241d05ba3ac4118f2d89
  • 部署前备份 PostgreSQL 为 /opt/cmpp-platform/backups/cmpp-20260715-142351.sql(约 65MBSHA-256 7cedd56e15c402c9e6cc03f0d7b03bc232206361704988e7bfd8a0c8c5ca4cf6),运行源码为 /opt/cmpp-platform/backups/cmpp-source-20260715-142351.tar.gz(约 1.3MBSHA-256 fb4e7a6e75a68496c4a4bee68db1760dbafdc53dac2357a965ded6d6843f463e),环境文件备份为 /opt/cmpp-platform/backups/cmpp-env-20260715-142351(权限 600SHA-256 87ab2efd509b39849b0ee22ead1b4cf0568fba4ab8525c59b5c78da51c73bc86)。
  • 生产成功应用第 4446 条 migrationPrisma 确认 46 条 migration 全部齐全。日报启动任务已按北京时间重算 T-4~T-1,生成对账 3 行、利润 4 行、质量 11 行,质量日期范围为 2026-07-11 至 2026-07-14;生产现有通用报备字段为 0,未为验收伪造配置。
  • cmpp-apicmpp-gatewaycmpp-minio、Nginx、PostgreSQL、Redis 均为 activeAPI/Gateway/MinIO health、Redis PONG、PostgreSQL readiness、12026/17890/8090/3000/9000 监听均通过。外部首页、运营端登录页和 API health 均为 HTTP 200CMPP 入站 17890 可连接,部署后 API/Gateway journal 无 error,生产根目录与 API npm audit --omit=dev 均为 0 vulnerabilities。未发送或重投客户短信。

2026-07-15 发送质量报表(已提交、已部署)

  • “报表对账”新增“发送质量报表”,包含企业应用、通道、签名、引流信息四个真实 Tab;统一展示日发送条数、成功条数、成功率、平均到达时长、生成时间,并由 API 按发送条数降序分页。
  • 新增 DailyQualityReport 和第 46 条 migration;质量日报与现有日报任务共同按北京时间 T+1 生成并每日重算 T-4 至 T-1。企业应用/签名/引流按短信最终状态聚合,通道按 accepted submit 与对应 Gateway delivered 回执聚合。
  • 平均到达时长使用成功短信的 deliveredAt - submittedAt,按日期和维度计算 PostgreSQL PERCENTILE_CONT(0.95),只对小于等于 P95 的样本求平均;无有效成功时间时保存 null。
  • SmsMessageRecord 新增真实 drainageInfoId。新短信在同签名 approved 引流信息中按正文 URL 精确匹配并取唯一最长 URL;migration 对历史短信用相同规则回填,歧义或未命中统一进入“未关联引流信息”,不重复展开。
  • 本地真实 PostgreSQL 已应用 46 条 migration,并实际执行四个质量维度的 T-4~T-1 生成 SQL;现有真实短信成功生成企业应用、未关联签名和未关联引流信息质量行,未关联行按企业应用隔离并可正常筛选。Prisma validate/generate/migrate status、报表与发送链路定向 2 suites/58 项、API 全量 18 suites/183 项、API build、前端 build、Gateway 全量 Go 测试、npm audit 0 漏洞和 git diff --check 通过;前端仅有既有 Vite chunk size warning。

2026-07-15 通用报备字段与签名资料动态化(已提交、已部署)

  • 新增真实 PostgreSQL CommonReportField 配置表,字段库可将字段分别配置为通用签名报备资料或通用引流信息报备资料,并支持真实新增、删除;删除配置不删除字段定义或历史材料。字段被通道或通用配置引用时,字段库定义均不能直接删除。
  • 应用报备资料字段统一合并“通用字段 + 当前应用生效通道组/通道字段”,按字段库 ID 去重并合并必填规则。未绑定应用的签名和引流信息仍返回、展示并由 NestJS 强制校验通用字段;通用字段仍保留在通道报备字段的字段库选择项中。
  • 运营端企业签名添加/编辑弹窗移除固定签名依据、资质凭证、企业信息和责任人信息,所有资料改由动态字段生成。运营端和客户端的签名、引流信息添加/编辑均加载对应通用字段;客户端新增签名不再走旧固定材料上传,改为把动态值写入真实签名资料 payload,文件继续上传 MinIO/FileObject。
  • migration 20260715170000_add_common_report_fields 已在本地 PostgreSQL 成功应用,当前 45 条 migration 全部齐全。Prisma format/generate/validate、API 定向 2 suites/39 项、API 全量 18 suites/181 项、API build、前端 build 和 git diff --check 通过;前端仅有既有 Vite chunk size warning。该功能已随 8c333660 提交、push 并部署生产。

2026-07-15 报表对账与利润报表(已提交、已部署)

  • 在“数据详单”后新增“报表对账”一级菜单及“对账单”“利润报表”二级菜单;两页调用真实 /api/admin/reports/reconciliation/api/admin/reports/profit,提供日期、企业、企业应用、通道、统计维度和服务端分页。
  • 新增 DailyReconciliationReportDailyProfitReport 真实 PostgreSQL 表和第 44 条 migration。报表按北京时间 T+1 生成,API 启动后及每日任务重算 T-4 至 T-1;每个日期在独立事务内删除旧聚合并重建,覆盖 72 小时回执更新窗口。
  • 发送量和成功量按 billingUnits 统计;成功取最终 delivered。企业应用利润的消费取当前 charged 账单,退款不计收入;成本累计所有 accepted 上游提交,因此补发成本不会漏算。通道利润按实际 accepted 尝试及对应 Gateway delivered 回执汇总,收入只归属最终提交。
  • SmsSubmitRecord 新增成本单价和金额快照,创建提交记录时写入;migration 按当时现有通道价回填历史记录。SubmitResult 更新同时收窄为优先按 submitId 更新,避免一次补发结果覆盖同一短信的其他尝试并污染成本。
  • 本地真实 PostgreSQL 已成功应用 migration 并实际执行 2026-07-11 至 2026-07-14 的 T-4T-1 生成 SQLPrisma schema validate/generate 和 migrate status 通过,44 条 migration 全部齐全。报表与发送链路定向 2 suites/56 项、API 全量 18 suites/176 项、API build、前端 build、Gateway 全量 Go 测试和 git diff --check 全部通过;前端仅有既有 Vite chunk size warning。本批未修改依赖,npm audit 延续上一批 0 漏洞锁文件;本轮在线复查因 npm registry TLS 建链连续两次失败,未将网络失败误记为 audit 成功。

2026-07-15 依赖安全与今日返还修复(已提交、已部署)

  • 生产数据库只读核查确认目标企业当天共有两笔真实返还:提交前路由失败产生消息级 released=5 分,最终失败产生 refunded=5 分,正确合计为 10 分(页面应显示 ¥0.100)。原 Dashboard 和企业列表只聚合 refunded,因此少算前一笔并显示 5 分。
  • 客户端 Dashboard 与运营端企业列表统一按当天 refundedreleased + relatedType=sms_message_record 汇总;排除任务冻结转扣费时的 released + relatedType=sms_batch_task,避免把内部账务转换误当成返还。
  • API 依赖升级到 NestJS 11.1.28、Multer 2.2.0,并通过 override 将 @hono/node-server 固定为 1.19.13npm --prefix api audit --json 已由 3 个 moderate、2 个 high 降为 0。
  • multipart 文件上传补充单文件 20MB、字段数、part 数、字段名/值长度和 header pair 限制,继续使用认证后的真实 NestJS API、MinIO 与 FileObject 链路。定向回归 3 suites/21 项通过;完整 API 17 suites/173 项、API build、前端 build、Gateway 全量 Go 测试、Prisma validate/migrate status 和依赖 audit 均通过,43 条 migration 全部齐全。前端仅有既有 Vite chunk size warning。
  • 功能提交 a758672436b3ebcd78aab91ba4a8e3cf68cbdfb0 已 push 并部署。生产两次 npm ci 均为 0 vulnerabilities;真实 PostgreSQL 按新口径聚合目标企业当天返还为 10 分,前端产物包含“今日返还金额”。

2026-07-15 下游人工重投无限排队修复(已提交、已部署)

  • 根因是 Gateway 以空的 DownstreamSendResult 同时表达“客户暂时离线”和“原消息映射丢失且缺少 Submit Sequence_Id”,NestJS 收到 sent=false 后又不登记失败,导致历史状态回执永久保持 pending/retryCount=0
  • Gateway 控制结果新增 retryable/reasonCode/errorMessage:缺少原 submitSequenceId 且无法命中内存映射时返回不可恢复的 MISSING_SUBMIT_SEQUENCE_IDNestJS 立即终结为 failed;字段完整但客户离线时返回可恢复的 CLIENT_DISCONNECTED,失败回调进入真实次数上限与指数退避。
  • 新状态回执入队补存 SmsMessageRecord.cmppSubmitSequenceId,Gateway 控制面允许在当前连接存在时立即恢复原 Msg_Id;不生成伪造或为 0 的 Msg_Id。
  • 自动扫描为 pending 增加默认 72 小时绝对终点(CMPP_DOWNSTREAM_PENDING_TIMEOUT_HOURS 可覆盖),从 createdAt 或最近 lastRetriedAt 计算,超时写 failed/queue_timeout 和失败操作日志。积压告警同样以最近人工重投时间重新计时,避免刚重投就因旧创建时间立即告警。
  • 回归已通过:API 定向 send-chain/operations 2 suites、68 项,API 全量 17 suites、173 项,Gateway 全量 Go 测试、Prisma validate、API build、前端 build 和 git diff --check;前端仅有既有 Vite chunk size warning。部署后生产原 3 条历史 pending 均已真实终结为 failed/manualRetryCount=1/retryCount=1,失败原因明确为 MISSING_SUBMIT_SEQUENCE_ID,当前下游投递 pending 为 0。

2026-07-15 待审核通知移除下游投递告警(已提交、已部署)

  • 生产只读核查确认当前“下游投递告警 3”全部为历史状态回执记录:三条均在人工重投后成为 pending/manualRetryCount=1/retryCount=0,因为告警仍按原 createdAt 超过 10 分钟判断,立即计入 stalled_pending;它们不是待审核任务。
  • 右上角“待审核任务”移除下游投递告警菜单项及其数字,通知总数只汇总企业认证、短信、模板、签名和引流信息五类审核。运营看板和下游投递记录页面继续保留独立告警展示。
  • “人工重投排队中”表示记录已由人工重投重置为 pending 并累计人工重投次数,正在等待 Gateway 对在线客户写出 Deliver 并取得 CMPP_DELIVER_RESP,不代表重投已经成功。
  • 进一步核查三条历史记录的 payload.submitSequenceId 均为空;虽然账号 910887 当前 connected 且持续心跳,Gateway 重启后没有原 Submit 的消息映射,也无法安全重建非 0 Msg_Id,因此修复前人工重投没有写出 Deliver 并持续保持 pending。前端 build 与 git diff --check 通过;应用内 Browser 连接因插件运行时初始化失败,未使用独立 Playwright 或 mock 页面替代。
  • 本批随 a7586724 部署,生产源码确认右上角待审核区域不再包含“下游投递告警”;运营看板与下游投递页面仍保留独立告警入口。

2026-07-15 a7586724 生产发布记录

  • 发布前确认本地 main 与最新 origin/main 无分叉;PostgreSQL、运行源码、环境文件分别备份为 /opt/cmpp-platform/backups/cmpp-20260715-120751.sql65MB)、/opt/cmpp-platform/backups/source-20260715-120751.tar.gz104MB)、/opt/cmpp-platform/backups/cmpp-platform-20260715-120751.env,均非空、权限 600 并完成 SHA-256 校验。
  • 发布包本地与服务器 SHA-256 均为 e1f14706389e6c42e89161422b07e6a409213dd54b9ae39b6bcc50dbba53f61e;生产 .deployed-commit=a758672436b3ebcd78aab91ba4a8e3cf68cbdfb043 条 migration 全部齐全且无待执行项。
  • cmpp-apicmpp-gateway、MinIO、Nginx、PostgreSQL、Redis 均 active12026/17890/8090/3000/9000 正常监听;API、Gateway、MinIO、Redis、PostgreSQL、外部首页、运营登录页和外部 API health 均通过,HTTP 返回 200。真实 CMPP 账号 910887 保持 connected,发布后 API/Gateway journal 无 error 级日志;未主动发送或重投计费短信。

2026-07-15 当前工作区汇总发布

  • 当前各对话产生的 34 个文件变更已统一提交为 e47432bc631bf37f4c6a6dcb3576ce3c86370b45 并 push 到 origin/main;提交明确排除 api/tsconfig.build.tsbuildinfologs/。发布前确认本地 main 与最新 origin/main 无分叉,API 全量 17 suites/169 项、API build、前端 build、Gateway 全量 Go 测试、Prisma validate/migrate status 和 git diff --check 全部通过,前端仅有既有 Vite chunk size warning。
  • 部署前生产 PostgreSQL、运行源码和环境文件分别备份为 /opt/cmpp-platform/backups/cmpp-20260715-112406.sql65MB)、/opt/cmpp-platform/backups/source-20260715-112406.tar.gz20MB)和 /opt/cmpp-platform/backups/cmpp-platform-20260715-112406.env;三份文件均非空、权限 600 并完成 SHA-256 校验。
  • 发布包本地与服务器 SHA-256 均为 c26d2414df13e535f3ce69d838d299d80680f23576599f264b7043ad1eea713c。生产成功应用 20260715090000_track_downstream_manual_retries20260715153000_remove_disconnected_downstream_sessions,共 43 条 migration 全部齐全;非 connected 历史连接行已清为 0,下游人工重投字段已可查询。
  • 生产 .deployed-commit=e47432bc631bf37f4c6a6dcb3576ce3c86370b45cmpp-apicmpp-gateway、MinIO、Nginx、PostgreSQL、Redis 均 active12026/17890/8090/3000/9000 监听,API/Gateway health、Redis、PostgreSQL、外部首页、运营登录页和外部 API health 均通过。真实 CMPP2.0 账号 910887 已重新登录并保持 connected,部署后 API/Gateway 新增 error 为 0。
  • 部署未重投 10:52:58 的历史失败短信,也未主动发送新的计费短信。生产 npm ci 报告现有依赖 3 个 moderate、2 个 high audit 风险,未阻断本次构建和启动,后续需在独立依赖升级任务中评估处理。

2026-07-15 CMPP 变量模板与 direct_send 修复

  • 生产只读诊断确认:10:52:58 账号 91088718821203795 提交验证码短信,应用已于 10:52:36 保存 templateMismatchMode=direct_send,且存在审核通过的 ${code} 变量模板;原实现用正文精确相等查询,实际验证码无法匹配占位符,同时模板为空时仅识别 manual_review,导致 direct_send 错误落入 TEMPLATE/REJECTD
  • resolveInboundTemplateCandidate 先保留精确匹配,再对同应用变量模板执行固定正文全量匹配,提取非空变量值;同名变量重复出现必须取值一致。匹配成功后保存真实 templateId,并将变量值传给真实风控评估。
  • 新增 direct_send 分支:模板不匹配时识别并保存已审核完整括号签名,继续执行风控、余额冻结、真实队列、通道组路由和具体通道签名报备校验;只跳过模板要求,不做无条件放行。reject/manual_review 行为保持不变。
  • 新增变量模板验证码和 direct_send 两项回归;SendChainService 1 suite/49 项通过,API 全量 17 suites/169 项通过,Prisma validate、API build、前端 build 和 git diff --check 通过,前端仅有既有 Vite chunk size warning。本修复已随 e47432bc 部署,未重投 10:52:58 的短信。

2026-07-15 运营端细节修复批次

  • 企业签名引流字段统一为“引流信息”并隐藏提交时间;人工充值弹窗移除操作人;待审核通知中的 0 使用黑字灰底。
  • 企业应用表单补充每任务号码上限的整任务拒绝说明;企业代码控件不可编辑并跟随 CMPP 6 位账号,NestJS 创建/更新也强制持久化两者相等。
  • 手机号段新增真实 DELETE;报备字段 API 返回真实通道引用数,未引用可删除,引用数大于 0 时前端禁用且后端返回 400。
  • 客户 CMPP 连接详情只展示已连接会话;Gateway 上报断开时删除活跃连接行,心跳超时扫描也删除,新增 migration 清理旧非 connected 行,断开操作日志仍保留。
  • 短信审核新增逐行/全选勾选,批量按钮只处理已选任务;下游投递列表与 Dashboard 增加统一创建日期范围参数并下推 Prisma/PostgreSQL。
  • 运营端和客户端短信模板变量均插入当前光标/选区位置;短信记录前端改为自适应卡片和分组详情,失败原因独立警示,不改变短信记录后端接口与业务语义。
  • 定向 API 测试 dictionaries/sms-config/operations 为 3 suites、49 项通过;API 全量 17 suites、167 项通过,Prisma validate、API build、前端 build、Gateway 全量 Go 测试和 git diff --check 均通过,前端仅有既有 chunk size warning。本地真实 PostgreSQL 已应用连接清理 migration43 条 migration 全部齐全。
  • 应用内浏览器已验证本地构建的运营端登录路由标题为“聆界短信管理平台”、DOM 非空且无框架错误覆盖;受 HttpOnly 会话和图形验证码限制,未绕过认证进入受保护页面。后续浏览器连接因桌面插件版本热更新失败,未以独立 Playwright 或 mock 页面替代。本批已随 e47432bc 部署,外部首页和运营登录页均 HTTP 200。

2026-07-15 下游人工重投状态追踪修复

  • 根因确认:人工重投会将 CmppDownstreamDelivery 重置为 pending/retryCount=0,前端又将所有 pending 固定翻译为“待首次投递”,导致已人工重投的记录被误展示为从未投递。
  • 新增 CmppDownstreamDelivery.manualRetryCount/lastRetriedAt 及真实 Prisma migration;人工重投时递增人工次数、保存时间,并在 OperationLog 中记录重投前状态、原自动重试次数和新人工次数。自动重试次数仍可为新一轮重置为 0,但不再丢失人工重投轨迹。
  • 列表和详情改为基于真实字段显示:初始 pending 为“待首次投递”,仅自动失败为“等待自动重试”,存在人工重投时为“人工重投排队中”;分开展示自动/人工次数和最近人工时间。
  • 后端新增 awaiting_ack 并发重投拦截,避免绕过前端禁用直接调 API 造成重复投递。并发修改最终已合并且编译问题已修正;汇总回归 API 17 suites/169 项、API/前端 build、Prisma validate/status 和 Gateway 全量 Go 测试均通过。本修复已随 e47432bc 部署,生产人工重投 migration 已应用且 43 条 migration 全部齐全。

2026-07-15 下游投递告警口径统一

  • 修复前存在三套口径:侧栏/首页只统计超阈值 pending 和最近 failed;详情页额外统计超时 awaiting_ack 与最近 unconfirmed/rejected;应用排行则将全部 pending 和所有历史失败累加为告警,造成同一时刻数量不一致。
  • 统一为“超阈值 pending + 超过 ackDeadlineAt 的 awaiting_ack + 最近窗口内 failed/unconfirmed/rejected”;默认积压阈值 10 分钟、最近失败窗口 1 小时,继续支持环境变量覆盖。
  • OperationsService.dashboard()downstreamDeliveryDashboard() 复用同一时间窗生成逻辑,首页/侧栏补齐 stalledAck 与三种最终异常状态;应用告警排行改为单独按统一告警 where 聚合,不再将普通 pending 和历史失败永久累加。
  • 已补实 OperationsService 定向单元测试,覆盖首页三类告警条件和应用排行统一条件。API 完整 17 suites、163 项通过,API build 和前端 build 通过;前端仅有既有 Vite chunk size warning。本批已随 e47432bc 部署。

2026-07-14 生产发送 Worker 配置缺失修复

  • 生产号码 18821203795 的最新短信于 18:24:59 审核通过后恢复为 queuedBullMQ 已生成 job,但一直停留在 bull:sms.send.queue:prioritized,无通道、submitIdSmsSubmitRecord
  • 生产 API 进程环境缺少 API_ENABLE_SEND_WORKER=true,而 SendChainService.onModuleInit() 只在该值严格为 true 时启动 BullMQ WorkerGateway 健康,但任务尚未进入 Gateway。
  • 修复为生产初始化默认写入 API_ENABLE_SEND_WORKER=true 和并发数 50,发布脚本在构建、迁移和重启前强制校验开关与正整数并发数,避免再次带病发布。
  • 与本批工作区改动合并回归:Prisma validate/generate 通过,API 完整 17 suites、163 项通过,API build、前端 build 和 Gateway 全量 Go 测试通过;前端仅有既有 Vite chunk size warning。
  • 功能提交 c1a17699 已 push 并部署生产。部署前 PostgreSQL 备份为 /opt/cmpp-platform/backups/cmpp-20260714-184827.sql(约 65 MB),运行源码备份为 /opt/cmpp-platform/backups/source-20260714-184827.tar.gz(约 23 MB),环境文件备份为 /opt/cmpp-platform/backups/cmpp-platform-20260714-184827.env;发布包本地和服务器 SHA-256 均为 920e01406560214ad5e2ce9c4cbef6c4d627590a7da135be6416ed5f555f4ea5
  • 生产 API 进程已实际加载 API_ENABLE_SEND_WORKER=trueAPI_SEND_WORKER_CONCURRENCY=50Redis prioritized/active 均为 0。原排队短信于 18:51:11 经“赛邮行业-王斯评中转”通道获得 SUBMIT_RESP accepted,证明 Worker、路由、Gateway 和上游提交链路已恢复。18:57:00 上游回执原始状态 DB:9032,平台按 undelivered 最终失败处理,5 分扣费已全额退回,账户余额从 95 分恢复为 100 分。
  • 生产迁移 20260714190000_restore_negative_credit_limit 成功应用,41 条 migration 全部齐全;.deployed-commit=c1a17699db29b7fcbde63c0b716cbf1abceb0cdf。API、Gateway、Nginx、PostgreSQL、Redis、MinIO 均为 active12026/17890/8090/3000 监听,API/Gateway health、Redis 和外部首页/运营登录页 HTTP 200,部署后 API/Gateway 无新增 error。

2026-07-14 恢复授信额度并补齐 72 小时无回执退款

  • 产品口径修正:套餐和短信余量继续移除,但企业账户保留授信额度;授信额度可为正数、负数或 0。
  • 发送校验公式调整为 balanceCents + creditCents > 0,和大于 0 才允许发送,和小于等于 0 时禁止发送;不扣除本次预估费用后再判断。
  • 新增授信调整真实 API、操作日志、企业新建/编辑页输入和运营端企业列表展示,并新增后续迁移恢复 TenantAccount.creditCents;客户端账户页不展示授信额度字段,只展示现金余额和合并后的可用发送额度。
  • 退款时点审查:明确失败回执在补发不可用或耗尽后,于同一次回执处理内同步退款;Submit 拒绝/超时发生在扣费前,只释放冻结而非退款。已修复原 72 小时接口无自动调度且漏掉 submitted 的缺口:API 启动 60 秒后首次扫描,之后默认每 5 分钟扫描 submitted/unknown,超过 72 小时即转 timeout 并退款,单条条件更新避免并发扫描重复处理。
  • CMPP 2.0/3.0 的 Stat 定义包含标准值 UNKNOWN,不是平台自造状态;当前 Gateway 对 DELIVRD 以外的非空最终状态(包括 UNKNOWN)统一映射为 undelivered,因此会进入失败补发,无法补发时直接失败退款。只有空 Stat 才映射为平台 unknown,并由 72 小时扫描兜底。
  • 本地验证通过:新增迁移已应用于本地 PostgreSQLPrisma validate/generate、完整 API 17 suites/163 项、API build、前端 build 和 Go Gateway 全量测试通过;前端仅保留既有 Vite chunk size warning。

2026-07-14 计费收敛为现金余额、失败退款展示

  • 生产只读核查确认 17:01 的人工充值已将目标企业现金余额从 0 增加到 100 分;17:04 发送预估费用仅 5 分却被拒绝,根因是旧逻辑同时要求 TenantAccount.smsUnits >= billingUnits,充值只增加现金时短信余量仍为 0。
  • 发送前账户检查已收敛为只判断 TenantAccount.balanceCents >= amountCents,错误文案统一为“企业账户余额不足”;冻结、提交成功扣费、最终失败退款均只变更现金余额。短信 billingUnits 继续作为 70/67 拆分和费用计算字段,不再充当套餐额度。
  • 删除 BillingPlan、账户短信余量、授信额度及充值订单套餐字段,并增加 Prisma 迁移;移除管理端套餐接口和客户端套餐购买入口,客户端改为展示真实现金余额与人工充值记录,运营端人工充值只录入金额。
  • 企业管理列表隐藏企业 ID 和透支限额,增加“今日返还”;后端只聚合当日 AccountTransaction.transactionType=refunded 的实际退款,普通冻结释放 released 不计入返还。
  • 失败退款链路复核:提交拒绝或超时且未实际扣费时只释放冻结;已提交扣费短信收到最终失败回执后才退款;已有 SmsBillingRecord.billingStatus=refunded 的消息不会重复退款。新增 TC-BILLING-011/012 覆盖余额唯一判断和退款口径。
  • 同步更新第一版需求和系统功能测试用例;Prisma validate/generate、本地 PostgreSQL migration deploy、完整 API 17 suites/162 项、API build、前端 build 和 Go Gateway 全量测试均通过。前端仅保留既有 Vite chunk size warning。
  • 功能与日志治理提交 28dad93e 已 push 并部署生产。部署前 PostgreSQL 备份为 /opt/cmpp-platform/backups/pre-billing-20260714-173949.sql.gz(约 4.1 MB),运行源码备份为 /opt/cmpp-platform/deploy-backups/pre-billing-20260714-173949.tar.gz(约 26 MB),发布包 SHA-256 为 6253aa50bdea9d5bd35786b7414286b72b56737df3fa533b3555544983537e19
  • 生产两条迁移成功应用,40 条 migration 无待执行项;BillingPlan 表和 TenantAccount.smsUnits/creditCents 字段已移除,目标企业 CMPP生产对接测试企业A 的现金余额保持 100 分。生产 .deployed-commit=28dad93e3ed7adcc7791a92723200ffe19509999API、Gateway、Nginx、PostgreSQL、Redis、MinIO 均 activeAPI/Gateway health、12026/17890/8090/3000 监听和外部首页/运营入口 HTTP 200;前端产物包含“今日返还”“账户余额”且不含“充值套餐”“透支限额”。未擅自重发计费短信。

2026-07-14 系统日志增长治理、分页索引与归档

  • 生产只读评估确认 OperationLog 已有约 3 万条、总占用约 17 MB,当前查询尚未形成性能事故;其中 cmpp_downstream_connection.heartbeat 约 2.4 万条、gateway.downstream_recovery_status_sync 约 5700 条,两类周期事件约占全部日志 99.5%。
  • SmsConfigService.recordDownstreamConnectionEvent 调整为 heartbeat/Submit/Deliver 只更新 CmppDownstreamConnection 当前状态和时间,只有 connected/disconnected 写系统日志。
  • SendChainService.recordGatewayDownstreamRecoveryStatus 在 upsert 前读取审计状态,只在 state、gatewayInstanceId、lockOwner、failureCategory、lastError 或 lastSkipReason 真实变化时写 gateway.downstream_recovery_status_changed;仅尝试次数、重试时间和锁过期时间变化不再重复写日志。
  • Prisma 为 OperationLog 新增 createdAtresource+createdAt 索引;系统日志 level 条件移入 PostgreSQL 查询后再 count/分页,排序增加 id 稳定次序。/admin/operations/audit-logs/admin/operation-logs 均改为分页响应并限制 pageSize 最大 100。
  • 新增 OperationLogArchive 和定时归档服务:在线日志默认保留 180 天,每日最多 20 批、每批 1000 条,使用单条 PostgreSQL CTE、FOR UPDATE SKIP LOCKED 和“归档存在后才删除源记录”保证并发与失败安全;归档记录按 archiveMonth=YYYY-MM 标记且不自动删除。
  • 同步需求与用例:TC-LOG-010 覆盖高频运行事件不写永久审计,TC-LOG-011 覆盖数据库侧分页、接口上限、归档完整性和失败不丢数据。
  • 验证通过:Prisma schema validate、Prisma Client 生成、本地 PostgreSQL migration deploy;本地真实 PostgreSQL 归档 smoke 验证过期日志进入 archiveMonth=2000-01 且仅在归档成功后删除在线源记录;数据库级 error 筛选真实查询通过。相关 5 suites/87 项和完整 API 17 suites/162 项测试全部通过;API build、前端 build 通过。前端仅保留既有 Vite chunk size warning。

2026-07-09 运营端通道测试短信闭环修复

  • 生产验证发现运营端通道“短信测试”弹窗仅关闭页面,未调用后端;POST /api/admin/channels/:id/test 仍返回 phase-4 placeholder,不创建 SmsMessageRecord/SmsSubmitRecord,也不写入 Gateway SubmitCommand,因此短信记录页面无记录。
  • 已修复为真实链路:前端提交手机号、内容和可选接入号;NestJS 校验通道 active 且存在在线 CMPP 连接后,创建独立 SmsMessageRecordSmsSubmitRecord 和操作日志,并向 BullMQ gateway.submit.queue 与 Redis Stream gateway.submit.commands 写入真实 SubmitCommand。通道测试不绑定企业、企业应用或 SmsBatchTask 发送任务。
  • 测试口径同步:TC-ADMIN-003 增加通道测试短信闭环要求,必须能从页面/API 发起真实测试短信,短信记录页面可查询到对应记录,Gateway submit worker 按通道真实 CMPP 配置消费发送。
  • 已执行:npm --prefix api test -- channels.service.spec.ts --runInBandnpm --prefix api run buildnpm run build。待生产部署后用指定号码做一次真实发送验证,并回查 DB/短信记录。
  • 2026-07-09 追加:按产品边界收窄通道测试短信,SmsMessageRecord/SmsSubmitRecord/SmsReceiptRecord/SmsMessageSegmentAudit 支持 tenantId/batchTaskId 为空;通道测试只记录短信、提交结果和回执,不进入企业账务、发送任务进度、客户侧 Deliver 推送或业务补发。
  • 2026-07-09 追加:生产验证短信进入 Gateway 后出现 SUBMIT_TIMEOUT/context deadline exceeded,上游平台疑似内容乱码;排查确认 API、数据库和 Redis Stream 中中文内容正常,SubmitCommand.cmpp.msgFmt=8,根因为 Gateway 在 CMPP 2.0 通道上仍固定构造 Cmpp3SubmitReqPkt。已修复为按通道 cmppVersion 分别构造 Cmpp2SubmitReqPkt/Cmpp3SubmitReqPkt,并同时处理 CMPP 2.0/3.0 SubmitResp。新增 submit_packet_test.go 覆盖 CMPP 2.0 中文 UCS2 Submit 包类型和长度。
  • 2026-07-09 追加:生产验证 Submit 已 accepted 后未见 SmsReceiptRecord,结合上游为 CMPP 2.0 排查 Gateway readLoop,确认只处理 Cmpp3DeliverReqPktCMPP 2.0 回执 Deliver 即使到达连接也不会 ACK 或进入 receipt 事件链路。已修复为同时处理 Cmpp2DeliverReqPkt/Cmpp3DeliverReqPkt,分别返回 Cmpp2DeliverRspPkt/Cmpp3DeliverRspPkt,并统一 Deliver 解码、回执和上行处理。新增 deliver_test.go 覆盖 CMPP 2.0 DELIVRD 回执写入事件链路。
  • 2026-07-09 追加:运营端短信记录“发送详情 - 通道发送与回执”的“回执码”必须展示通道原始回执码 SmsReceiptRecord.rawStatus,用于和上游平台核对;该字段不再回退展示平台映射状态 receiptStatus 或提交状态。
  • 2026-07-09 追加:生产验证 17317959177 在 DB 中已有 rawStatus=DELIVRD,但页面仍显示空。排查确认页面调用 /admin/send/messages 时生产返回缺少 submitRecords/receiptRecords 明细,而 /admin/operations/messages 返回完整通道发送与回执记录;短信记录页已切换到完整明细接口,并将 UTC ISO 时间按 Asia/Shanghai 展示,避免 16 点多页面显示 8 点多。

2026-07-09 企业应用短信接口开关和接口类型

  • 按设计基线恢复企业应用添加/编辑页“短信接口 开通/关闭”和“接口类型 CMPP/HTTP”;当前第一版只允许 CMPP2.0,HTTP 在页面中禁用,后端拒绝未实现的 interfaceType=http
  • Prisma SmsApplication 新增 interfaceEnabledinterfaceType 持久化字段;企业应用创建、编辑、列表和 CMPP 参数接口均返回真实数据库值。
  • 发送链路新增硬校验:interfaceEnabled=false 时客户端/API 发送、Gateway bind/login 鉴权和 Gateway submit 入站都会拒绝,不进入任务、计费或 Gateway 上游提交。
  • 测试口径同步:TC-ADMIN-018A 覆盖表单保存、CMPP2.0 only、HTTP 禁用和接口关闭后的发送/Gateway 拒绝;TC-GW-006 覆盖 Gateway 鉴权与 submit 对接口开关的校验。
  • 已执行:npm --prefix api run prisma:generatenpm --prefix api test -- sms-config.service.spec.ts send-chain.service.spec.tsnpm --prefix api run buildnpm run buildgit diff --checknpm --prefix api run prisma:migrate:deploy

2026-07-09 通道复制默认停用与真实连接池状态回写修复

  • 生产验证发现当前 3 个赛邮行业通道中有 2 个由首个 active 通道复制而来;数据库 CmppConnectionState 曾显示 3 条通道都为 connected/currentConnections=1,但生产机 ss/netstat 与上游平台都只能看到 1 条真实 TCP 长连接。
  • 根因一:POST /api/admin/channels/:id/copy 会继承源通道 status=active,复制后的通道创建完成后立即参与 Gateway 连接流程,和“复制只是拷贝配置,不应自动上线”的产品预期不符。
  • 根因二:Gateway /connections/connect 之前只做一次性 DialCMPP 探测,探测成功后就把 connected/currentConnections=desiredConnections 回写给 NestJS;该探测连接随后立即断开,导致页面状态与真实上游连接池不一致。
  • 已修复:
    • 通道复制后统一保存为 disabled,复制日志补充 sourceStatuscopiedStatus,避免 active 通道副本自动占用上游连接。
    • Gateway ConnectChannel 改为直接建立/复用真实上游连接池,并由连接池回写 connected/failed/disconnectedcurrentConnections、最近错误和断开时间;连接丢失时状态随真实连接数变化更新。
  • 测试口径同步:
    • TC-ADMIN-003 增加“连接状态必须来自真实上游连接池回写”的要求。
    • TC-ADMIN-016 明确复制 active 通道后副本默认 disabled,且不会立即触发上游真实连接。
  • 已执行:npm --prefix api test -- channels.service.spec.ts --runInBandnpm --prefix api run buildgo test ./internal/control ./internal/upstreamgo build -o ..\\dist\\cmpp-gateway .\\cmd\\gateway

2026-07-09 线上通道 CMPP 版本修复

  • 线上生产验证发现 3 个赛邮行业通道配置均指向 121.40.172.212:7890,其中 2 个已触发 Gateway 真实连接并失败,CmppConnectionState.lastErrorpacketWriter.ReadBytes error: ReadBytes reads 14 bytes, not equal to 16 we expected
  • 生产机到上游 121.40.172.212:7890 TCP 可连接,失败不是 API/Gateway 服务不可用,也不是网络完全不通;结合上游确认参数为 CMPP 2.0,根因定位为通道创建默认 CMPP 3.0 且运营端没有版本选择入口。
  • 已修复通道创建/编辑:运营端新增 CMPP 2.0/3.0 版本选择,默认 2.0NestJS 通道 API 默认 cmppVersion=2.0,并只允许 2.0 或 3.0Prisma SmsChannel.cmppVersion 默认值同步改为 2.0。
  • 测试口径同步:TC-ADMIN-003 要求通道协议默认 CMPP,CMPP 版本默认 2.0,且可选择 2.0 或 3.0;Gateway 连接命令必须携带真实通道版本。
  • 待复测:部署迁移后将线上赛邮通道 cmppVersion 调整为 2.0,并重新触发 Gateway 连接验证。

2026-07-07 企业应用通用下拉与优先队列需求补充

  • 已补充需求文档,明确运营端企业应用新增时选择企业必须使用通用 Select/下拉控件,企业选项来自真实企业 API,支持加载、空态和错误态,不允许静态数组或 localStorage 兜底。
  • 已补充应用发送队列等级需求:短信应用必须保存普通队列/优先队列配置,默认普通队列;优先队列用于验证码、登录确认、交易通知等高时效短信。
  • 已补充发送链路要求:发送入队必须按应用队列等级分流,优先队列在同等业务校验、通道组路由、通道限速和 Gateway 连接条件下插队消费;普通队列不能永久饿死。
  • 已补充测试计划和系统功能用例:
    • 企业应用新增表单企业选择与队列等级真实保存。
    • 优先队列插队发送。
    • SubmitCommand 队列等级契约校验。
    • 混合优先级队列性能 smoke。
  • 当前状态:仅完成需求和测试口径补充,前后端、Prisma、BullMQ/Send Worker、Gateway 队列契约尚未实现,不能记为功能验收通过。
  • 2026-07-07 追加:Prisma 与 NestJS 企业应用 API 已增加 queuePriority 持久化字段,创建/编辑支持 normal/priority 校验,列表/详情随真实应用数据返回;前端表单、发送入队、Send Worker 调度和 Gateway 队列契约仍待后续步骤实现。
  • 2026-07-07 追加:运营端企业应用新增第一步企业选择已改为通用 Select;企业应用新增/编辑表单已按设计锚点恢复“发送队列”单选项,并在保存时真实提交 queuePriority。发送入队、Send Worker 调度和 Gateway 队列契约仍待后续步骤实现。
  • 2026-07-07 追加:发送链路已将应用 queuePriority 固化到 SmsMessageRecordBullMQ 入队按 priority/normal 写入不同 job prioritySubmitCommand 契约、示例和 Go Gateway 队列结构已增加 queuePriority;当前实现覆盖优先队列插队的基础能力,持续高优先级流量下普通队列防饥饿策略仍需后续压测和调度增强。
  • 2026-07-07 追加:Gateway 队列契约第 8 步已独立校验,SubmitCommand schema/example 要求 queuePriorityGo Gateway SubmitCommand 结构可反序列化该字段,并通过 npm run spike:contractsnpm run spike:gateway
  • 2026-07-07 追加:第 9 步收口验证通过:npm --prefix api run prisma:generatenpm --prefix api test -- sms-config.service.spec.ts send-chain.service.spec.ts --runInBandnpm run spike:contractsnpm run spike:gatewaynpm --prefix api run buildnpm run build 均通过;前端 build 仅保留既有 Vite chunk size warning。

2026-07-06 企业管理列表字段回归

  • 按设计锚点 131f344a^ 恢复运营端企业管理列表字段:企业 ID、企业名称、当前余额、透支限额、今日消费、企业状态、操作。
  • 新增真实后端接口 GET /api/admin/tenants/management-list,由 NestJS/Prisma 聚合租户、企业账户和当天短信消息金额;前端不再用静态字段或本地假数拼出今日消费。
  • 当前余额来自 TenantAccount.balanceCents,透支限额来自 TenantAccount.creditCents,今日消费来自当天 SmsMessageRecord.amountCents 汇总。
  • 已执行:
    • npm --prefix api test -- tenants.service.spec.ts --runInBand
    • npm --prefix api run build
    • npm run build
  • 验证结果:API 单测、API build、前端 build 均通过;前端 build 仅保留既有 Vite chunk size warning。

2026-07-06 企业编辑页和上传链路修复

  • 按设计锚点 131f344a^ 恢复运营端企业新建/编辑页字段:企业照片、企业名称、统一社会信用代码、省/直辖市、市/区、通讯地址、联系人姓名、身份证号、手机号、电子邮箱。
  • 运营端企业新建/编辑页移除偏离锚点的企业编码、企业状态字段;后端 POST /api/admin/tenants 支持不传企业编码,并按信用代码/企业名生成真实唯一企业编码。
  • 修复营业执照/企业照片上传 500
    • 启动脚本在 MinIO 不可用时启用本地对象存储 .local-data/object-storage,文件仍通过真实 NestJS 上传接口写入对象存储目录并创建 FileObject 数据库记录。
    • 文件上传接口缺少 multipart 文件时返回 400。
    • FileObject.sizeBytes 返回前转换为字符串,避免 Prisma BigInt JSON 序列化 500。
  • 已执行:
    • npm --prefix api test -- tenants.service.spec.ts files.service.spec.ts --runInBand
    • npm --prefix api run build
    • npm run build
    • POST http://localhost:3000/api/admin/files/upload multipart smoke
  • 验证结果:API 单测、API build、前端 build 和真实上传 smoke 均通过;前端 build 仅保留既有 Vite chunk size warning。

2026-07-06 本地 MinIO 启动脚本补充

  • tools/start-local.ps1 补充本地 MinIO 启动流程:Docker Compose 优先;无 Docker 时查找 C:\cmpp-platform-local\minio.exeC:\cmpp-platform-local\minio\minio.exe 或 PATH 中的 minio.exe,使用 C:\cmpp-platform-local\minio-data 作为数据目录,监听 9000/9001
  • package.json 新增 npm run start:local:minio,用于单独启动本地 MinIO。
  • MinIO 不可用时,脚本仍会明确启用 .local-data/object-storage fallback;启动完成提示会区分 MinIO 是否真实运行。
  • MinIO 模式下对象存储服务会在上传/预签名前自动确认并创建 cmpp-platform bucket。
  • 已执行:
    • npm --prefix api run build
    • npm run start:local -- -SkipApi -SkipWeb -SkipMigrate
  • 验证结果:API build 和启动脚本 smoke 通过;当前机器未发现 minio.exe,脚本按预期提示并启用本地对象存储 fallback。

2026-07-06 应用级 CMPP 连接和签名/引流表单基线

  • CMPP 连接状态从企业/租户级聚合改为应用级独立连接:
    • CmppConnectionState 新增 applicationId 并关联 SmsApplication
    • 企业应用列表和连接详情只读取当前应用的 CmppConnectionState
    • 运营端断开连接只操作当前应用下的连接。
    • Gateway 连接上报 POST /api/admin/gateway/connections 支持 applicationId,新连接可按应用独立记录。
  • 运营端添加/编辑短信签名页面按设计锚点 131f344a^ 补齐字段:签名依据、短信签名、资质凭证、公司名称、统一社会信用代码、法人姓名、法人身份证号、法人身份证照片、责任人姓名、责任人手机号、责任人身份证号、责任人身份证照片、三网报备状态。
  • 运营端添加/编辑引流信息页面按设计锚点 131f344a^ 补齐字段:引流信息、字段名称 1-10、文件上传、三网报备状态、提交时间、备注。
  • 签名和引流表单仍使用真实 enterprise-signatures 后端接口保存;扩展字段写入 SmsSignature.drainageInfo JSON,文件上传走真实 admin/files/upload 并保存 FileObject 引用。
  • 已执行:
    • npm --prefix api run prisma:generate
    • npm --prefix api test -- sms-config.service.spec.ts channels.service.spec.ts --runInBand
    • npm run build
    • npm --prefix api run build
    • npm --prefix api run prisma:migrate:deploy
  • 验证结果:Prisma Client 生成、API 针对测试、API build、前端 build 和本地 PostgreSQL migration deploy 均通过;前端 build 仅保留既有 Vite chunk size warning。

2026-07-01

新增测试基础

  • API 引入 Jest + ts-jest。
  • API 新增脚本:
    • npm --prefix api test
    • npm --prefix api test -- <spec>
  • 根目录新增脚本:
    • npm run test:api
    • npm run test:gateway

新增 API 测试

测试文件 覆盖范围
api/src/risk-review/risk-review.service.spec.ts 最大号码数、重复率、非法号码率、黑名单率、模板变量异常、非工作时间营销大批量、短时间频控、直接拒绝、人工审核。
api/src/billing/billing.service.spec.ts 70/67 费用预估、余额/授信/套餐检查、充值、冻结、扣费、释放、退款、调整、短信计费记录。
api/src/send-chain/send-chain.service.spec.ts 批量任务创建、手机号去重拆分、发送入队、Gateway SubmitCommand 投递、submit result、receipt、uplink、72 小时未知转超时。
api/src/channels/channels.service.spec.ts 通道创建、路由规则、报备材料 upsert、报备任务创建、导出、回执导入、签名报备状态同步。
api/src/operations/operations.service.spec.ts 发送记录查询过滤、dashboard、statistics、trace、reconciliation。

新增 Gateway 测试

  • gateway/internal/tracker/tracker_test.go 增加并发 SEQID/MSGID/GatewayMessageID 映射测试。
  • 既有 Gateway 测试继续覆盖:
    • tracker 基础映射和未知 submit resp。
    • reconnector 重连和最终错误返回。
    • health handler。
    • gocmpp adapter。
    • spike simulator。

已执行命令

npm --prefix api test -- risk-review.service.spec.ts
npm --prefix api test -- billing.service.spec.ts
npm --prefix api test -- send-chain.service.spec.ts
npm --prefix api test -- channels.service.spec.ts
npm --prefix api test -- operations.service.spec.ts
npm run test:api
npm run verify:phase8
npm run build
npm run spike:gateway
npm --prefix api test
npm run test:gateway
node tools/smoke/real-env-smoke.mjs
$env:API_PORT='3101'; npm --prefix api run start:dev
node <inline step4 precheck smoke>
$env:API_PORT='3101'; $env:API_ENABLE_SEND_WORKER='true'; npm --prefix api run start:dev
node <inline step5 send-chain smoke>
node <inline step5 schedule probe>
$env:API_PORT='3101'; npm --prefix api run start:dev
node <inline step6 billing/reconciliation smoke>
node <inline step6 auto-billing probe>
npm run spike:contracts
npm run test:gateway
$env:API_PORT='3101'; $env:API_ENABLE_SEND_WORKER='true'; npm --prefix api run start:dev
node <inline step7 channel/cmpp status smoke>
npm run verify:phase8
npm run test:api
npm run test:gateway

当前结果

  • API Jest5 个 test suite 通过,22 个测试通过。
  • Gatewaynpm run spike:gateway 通过。
  • 阶段 8 完整验证:npm run verify:phase8 通过,其中 BullMQ spike 15000 条消息、并发 500、端到端 705.65 TPS,满足 500 TPS。
  • 前端 build 通过,仍存在既有 Vite chunk size warning。
  • API Jest 使用 mock 依赖的结果仅代表单元/轻集成测试通过;系统功能验收仍要求 PostgreSQL/Redis/MinIO 和真实 API smoke 通过。
  • 真实 PostgreSQL/Redis/MinIO smoke 通过:
    • PostgreSQL localhost:5432、Redis localhost:6379、MinIO localhost:9000/9001 端口均连通。
    • npm --prefix api run prisma:migrate:deploy 通过,无待应用迁移。
    • API 以真实 .env 启动,GET http://127.0.0.1:3101/api/health 返回 ok
    • tools/smoke/real-env-smoke.mjs 已补充最小幂等 seed,并验证登录、企业/客户、人工充值、余额检查、发送任务、MinIO 预签名上传、运营日志、发送链路追踪和账务对账聚合。
  • 第 4 步发送前置校验 smoke 通过:
    • TC-TEMPLATE-001TC-TEMPLATE-002TC-TEMPLATE-003 / TC-RISK-005TC-RISK-001TC-RISK-002TC-RISK-003TC-RISK-004TC-BILLING-001 / TC-TEMPLATE-005TC-BILLING-PRECHECK-001 均通过。
    • 记录两个接口健壮性问题:不存在的 reviewerId、不存在的 createdById 会触发数据库外键 500。
    • 客户侧导入发送、非法字符展示、敏感词接入发送前风控当前缺少完整入口,已在 docs/testing-execution-step-4.md 记录为阻塞缺口。
  • 第 5 步发送链路 smoke 通过:
    • TC-SEND-001 / TC-SEND-002、旧版 TC-SEND-003 / TC-SEND-004TC-SEND-005TC-SEND-006TC-SEND-007TC-SEND-008、旧版 TC-SEND-009 / TC-SEND-010 均通过。
    • 2026-07-03 新增的通道组真实路由用例 TC-SEND-010TC-SEND-018 尚未开发和执行,不能沿用旧 smoke 通过结论。
    • 使用真实 Redis/BullMQ 和 API_ENABLE_SEND_WORKER=true 验证了任务创建、号码去重拆分、自动入队、Worker 消费、submit record、submit result、receipt、uplink、72 小时 unknown 转 timeout、客户端/运营端任务查看。
    • 定时发送探测发现 scheduledAt/sendMode=scheduled 会被接口忽略,任务直接变为 queued,已在 docs/testing-execution-step-5.md 记录为功能缺口。
  • 第 6 步计费和对账 smoke 通过:
    • TC-BILLING-001TC-BILLING-002 / TC-RECHARGE-001TC-BILLING-003TC-BILLING-004 / TC-BILLING-005 / TC-BILLING-006 / TC-BILLING-007TC-BILLING-008 / TC-RECON-001 seedTC-RECON-001TC-DASHBOARD-001 / TC-STAT-001TC-TRACE-001TC-BILLING-009 均通过。
    • 验证了费用预估、人工充值、余额检查、冻结、扣费、释放、退款、短信计费记录、账务流水、dashboard/statistics、trace 和 reconciliation。
    • 自动计费探测发现发送任务不会自动生成短信计费记录、账户交易流水,消息金额默认为 0,已在 docs/testing-execution-step-6.md 记录为发送计费集成缺口。
  • 第 7 步客户/通道 CMPP 连接状态和 Gateway smoke 通过:
    • TC-GW-CONTRACT-001TC-GW-001TC-GW-002TC-GW-003TC-GW-004TC-CMPP-STATUS-001 / TC-CHANNEL-001TC-CHANNEL-ROUTE-001TC-CHANNEL-METRIC-001TC-CMPP-SESSION-001 / TC-CONNECTION-COUNT-001TC-CMPP-STATUS-002 / TC-OPERATIONS-MONITOR-001TC-GATEWAY-EVENT-001 均通过。
    • 验证了 Gateway 队列契约、Go Gateway health/重连/tracker/gocmpp 模拟器、通道创建、路由、metrics、submit session、通道维度监控和 Gateway submit event trace。
    • 客户级 CMPP 连接状态、客户连接数量、通道连接列表和 Gateway health 聚合到运营 dashboard 尚缺少一等 API,已在 docs/testing-execution-step-7.md 记录。
  • 第 8 步最终回归通过:
    • npm run verify:phase8 通过,BullMQ 15000 条消息、并发 500、端到端 TPS 668.71,满足 500 TPSPrisma generate、API build、前端 build 均通过。
    • npm run test:api 通过,5 个 test suite、22 个 tests 全部通过。
    • npm run test:gateway 通过,Go Gateway health、connection、tracker、cmpp、spike 测试全部通过。
    • 最终归档见 docs/testing-execution-step-8.md

已知缺口

  • 暂未新增前端测试框架,前端仍以 npm run build 作为 smoke。
  • BullMQ 真实链路仍由 npm run spike:bullmq 覆盖,不在 Jest 内启动 Redis。
  • Gateway 未接真实运营商 SMSC;真实 CMPP 互通需要运营商测试环境后补充联调记录。
  • 客户侧导入发送、短信内容非法字符展示和敏感词发送前拦截尚未形成完整业务入口。
  • 定时短信发送缺少计划发送时间字段、scheduled 状态、到点触发和取消接口。
  • 发送链路尚未自动接入计费闭环,发送任务不会自动冻结/扣费/生成短信计费记录。
  • 客户/通道 CMPP 连接状态和连接数量尚未形成运营端/客户端一等接口,Gateway health 未聚合到 NestJS dashboard。

2026-07-01 缺口修复复测

本轮修复范围

  • P0 定时短信发送闭环:
    • SmsBatchTask 增加 scheduledAtcanceledAt 字段和 status/scheduledAt 索引。
    • CreateBatchTaskDto 支持 sendMode=scheduledscheduledAt
    • 新增定时任务取消和到点触发入口:POST /api/client/send/batch-tasks/:id/cancelPOST /api/admin/send/scheduled/dispatch-due
    • 到点触发前重新校验企业状态、认证状态、应用状态、模板审核状态、签名审核/报备状态和账户余额。
  • P0 发送链路自动计费闭环:
    • 发送创建时按通道单价写入消息计费条数、单价和金额。
    • 立即发送创建时执行账户检查和冻结;定时发送创建时检查余额,到点再冻结。
    • submit accepted 后生成/更新 SmsBillingRecord、写入 charged 流水;submit rejected/timeout 释放冻结;失败回执和 72 小时超时执行退款。
  • P0 发送前内容校验:
    • 风控评估接入敏感词字典和控制字符扫描。
    • variableIssues 扩展为 { variables, content },同时保留变量异常和内容异常证据。
    • emoji/UCS2、多空格和换行不直接拒绝,继续通过 70/67 字符长度影响计费。
  • P1/P2 补齐:
    • 新增企业认证模型/API,提交、审核通过、驳回会同步 Tenant.certificationStatus,发送前强制认证通过。
    • 新增客户侧导入预览/确认入口,覆盖 CSV/TXT 文本解析、20MB 限制、重复/非法/黑名单/变量缺失提示。
    • 新增客户/通道 CMPP 连接状态模型/APIGateway 或本地 Gateway 模拟器可通过真实 API 回写连接状态,运营 dashboard 聚合连接状态。
    • 新增应用密钥重置、应用/签名/模板状态变化、通道启停接口,并写入系统日志。
    • 无效 createdByIdreviewerId 改为明确 400,不再冒泡数据库外键 500。

新增/更新测试

测试文件 新增覆盖
api/src/send-chain/send-chain.service.spec.ts TC-SCHEDULE-001 到 006、TC-BILLING-AUTO-001 到 004、TC-IMPORT-001 到 006 子集、企业认证/状态阻断。
api/src/risk-review/risk-review.service.spec.ts TC-CONTENT-001 到 004 子集、敏感词和控制字符拦截、无效 createdById。
api/src/certification/certification.service.spec.ts TC-CERT-001 到 004 子集,认证提交、审核、驳回和租户状态同步。
api/src/channels/channels.service.spec.ts 通道启停日志、通道连接状态 upsert/list、客户连接状态 list。
api/src/sms-config/sms-config.service.spec.ts 无效 reviewerId 400,避免审核外键 500。
api/src/operations/operations.service.spec.ts Dashboard Gateway 连接状态聚合。

已执行命令

npm run prisma:generate
npm --prefix api test -- send-chain.service.spec.ts risk-review.service.spec.ts sms-config.service.spec.ts
npm --prefix api test
npm --prefix api run build
npm --prefix api run prisma:migrate:deploy
npm run verify:phase8
npm run test:api
npm run test:gateway

当前结果

  • Prisma Client 生成通过。
  • 新增迁移已应用到真实 PostgreSQL
    • 20260701103000_add_scheduled_sms_fields
    • 20260701110000_add_certification_and_connection_state
  • API build 通过。
  • API Jest7 个 test suite 通过,34 个测试通过。
  • 最终回归通过:
    • npm run verify:phase8 通过,BullMQ 15000 条消息、并发 500、端到端 TPS 608.93,满足 500 TPSPrisma generate、API build、前端 build 均通过。
    • npm run test:api 通过,7 个 test suite、34 个 tests 全部通过。
    • npm run test:gateway 通过,Go Gateway health、connection、tracker、cmpp、spike 测试全部通过。

剩余说明

  • 客户侧导入当前提供 API 级文本预览/确认闭环;浏览器端真实文件选择、GBK 二进制转码和错误文件下载仍需前端/E2E 后续覆盖。
  • Gateway 连接状态通过 NestJS API 支持 Go Gateway 或本地模拟器回写;真实运营商 SMSC 联调仍需运营商测试环境。

2026-07-02 运营端优化转真实后端补齐

本轮修复范围

  • 修正测试策略说明:mock 仅作为单元/轻集成测试替身,不能作为业务完成标准;新增页面能力必须接 NestJS API、Prisma/PostgreSQL 和必要操作日志。
  • 通道管理补齐真实 API
    • POST /api/admin/channels/:id/copy:复制通道配置、通道报备字段和该通道签名报备材料,写入操作日志。
    • DELETE /api/admin/channels/:id:软删除通道,避免破坏历史发送/报备外键。
    • GET /api/admin/channels/:id/connection-logs:基于 OperationLogCmppConnectionState 查询连接日志;保留 /link-logs 兼容旧前端。
  • 安全控制补齐真实 API:敏感词、全局黑名单、企业黑名单支持 keyword/status 查询、创建、启停/软删除,并写操作日志。
  • 企业黑名单修正为企业应用级黑名单:Prisma EnterpriseBlacklist 新增 applicationId 并改为 applicationId + phoneNumber 唯一;运营端页面按企业和短信应用新增/搜索;发送预览和风控只命中当前应用的 active 黑名单。
  • 模板审核补齐真实查询:运营端模板列表支持 keyword/status,并返回企业、应用、签名信息;前端模板审核页已改为调用真实 API。
  • 运营端企业模板管理新增短信模板时,后端直接写入 auditStatus=approved;短信模板审核页展示为“已通过”,客户端自行提交模板仍保留审核流。
  • 企业认证审核补齐真实查询:列表支持 keyword/status,详情返回企业信息和认证 materials;前端企业认证审核页已改为调用真实 API。
  • 前端新增 /api Vite 代理和 src/api/adminApi.ts,通道管理、模板审核、企业认证审核应调用真实 API;API 不可用时页面应展示错误态或空态,静态兜底不能作为验收通过依据。

新增/更新测试

测试文件 新增覆盖
api/src/channels/channels.service.spec.ts 通道复制、软删除、连接状态日志写入、连接日志查询。
api/src/dictionaries/dictionaries.service.spec.ts 敏感词、全局黑名单、企业黑名单查询、创建、软删除和操作日志。

已执行命令

npm --prefix api run build
npm --prefix api test
npm run build

当前结果

  • API build 通过。
  • API Jest8 个 test suite 通过,38 个测试通过。
  • 前端 build 通过,仍存在既有 Vite chunk size warning。

文档同步

  • 已将今天的客户端和运营端优化要求补入 docs/first-version-development-requirements.md
    • 去除客户端独立账号设置菜单,改为头像下拉承载退出登录和修改密码。
    • 明确模板审核搜索、企业认证详情审核、企业应用 CMPP 连接数/连接详情/参数复制、通道复制、通道软删除、通道连接日志、安全控制 CRUD、系统日志分页等均需要真实后端 API 支撑。
    • 补充客户端用户、运营端企业认证、通道、连接、字典、安全控制、系统日志等接口范围。
    • 修正 Codex 执行模板,明确 mock、localStorage 或静态数据不得作为真实开发完成标准。
  • 已将今天的验收点补入 docs/system-functional-test-cases.md
    • 新增 TC-CLIENT-010 到 TC-CLIENT-011。
    • 新增 TC-ADMIN-014 到 TC-ADMIN-022。

2026-07-02 新增浏览器和业务闭环用例执行

执行环境

  • APInpm --prefix api run start:dev,监听 http://localhost:3000/api
  • 前端:npm run build 后使用 npm run preview -- --port 4173,访问 http://localhost:4173
  • Browser 插件:可连接本地 tab,但对 Vite dev 页 Page.navigate 超时;改用临时目录 Playwright 包加本机 Chrome 执行浏览器 smoke,未修改项目依赖。
  • PostgreSQL:本地 localhost:5432 可用,API smoke 使用真实数据库。

已执行命令

npm run build

# 临时目录 C:\Users\hectorzhao\AppData\Local\Temp\cmpp-pw-smoke
npm init -y
npm install playwright --no-save
node <browser-and-api-smoke>

通过用例

用例 结果 覆盖点
TC-DASHBOARD-CLIENT-UI UI-SMOKE PASS / BACKEND GAP 客户端 Dashboard 可渲染账户余额、今日发送、账户状态,但页面数据仍需确认全部来自真实 API。
TC-DASHBOARD-ADMIN-UI UI-SMOKE PASS / BACKEND GAP 运营端 Dashboard 可渲染今日发送总量、总体成功率、企业消费排行、通道运行,但当前源码仍存在 mock 数据路径。
TC-BILLING-MANUAL-UI UI-SMOKE PASS / BACKEND GAP 运营端人工充值弹窗填写后,前端表格新增企业、金额、操作人和备注;该页面当前未调用真实充值 API。
TC-LOG-ADMIN-UI UI-SMOKE PASS / BACKEND GAP 运营端系统日志页面可展示人工充值、账户计费等记录;页面数据仍需接真实日志 API。
TC-LOG-CLIENT-UI UI-SMOKE PASS / BACKEND GAP 客户端系统日志页面可渲染并展示客户侧日志记录;页面数据仍需接真实日志 API。
TC-CMPP-STATUS-UI UI-SMOKE PASS / BACKEND GAP 企业应用管理可展示 CMPP 状态和连接数量并打开连接详情;页面当前仍有本地初始数据路径。
TC-FRONTEND-CONSOLE PASS 关键页面无相关 console error/pageerror;仅忽略 favicon 404。
TC-BILLING-MANUAL-API PASS 人工充值无需审批:确认后账户余额、短信条数、充值单、账户流水和 Dashboard transactions 聚合同步更新。
TC-CMPP-STATUS-API PASS 通道创建、Gateway 连接状态回写、按通道/客户查询、连接日志和 Dashboard gatewayConnections 聚合通过。

发现和说明

  • npm run dev 在本机 5173 被占用后切换到 5174Vite 首次依赖 bundling 长时间未完成,浏览器看到白屏;生产构建和 preview 渲染正常。
  • 运营端人工充值页面当前是前端本地状态 smoke,不能作为系统功能通过;真实入账闭环通过 POST /api/admin/billing/manual-recharges 验证。
  • 人工充值不需要审批,测试口径已同步修正为“有权限确认即入账,不产生 pending 审批态”。

真实后端缺口和 Bug 清单

编号 严重级别 问题 证据 期望修复
BUG-FE-001 P0 运营端人工充值页面未调用真实后端,提交后只更新前端本地表格状态。 src/apps/admin/AdminRechargeRecordsPage.tsx 使用 rechargeRecordsSeeduseStatesubmitManualRechargesetRecords 页面提交调用 POST /api/admin/billing/manual-recharges,成功后刷新真实充值记录、账户余额、流水和日志。
BUG-FE-002 P0 运营端 Dashboard 仍使用 mock service 和静态排行,不能证明真实统计准确。 src/apps/admin/AdminHome.tsx 引用 adminServicehourlySendTrendauditTrend,指标从前端数组计算。 接入 GET /api/admin/operations/dashboard/statistics 或拆分真实统计接口,所有卡片和排行从 API 返回。
BUG-FE-003 P0 客户端 Dashboard 仍使用 mock service,余额、发送量、最近充值等不是实时后端数据。 src/apps/client/ClientHome.tsx 使用 clientService.getOverview() 和客户端 mock 数据。 接入客户端真实 dashboard、账户、任务、充值流水 API,点击明细继承真实筛选条件。
BUG-FE-004 P0 客户端和运营端系统日志页面仍有静态数据路径,无法验证真实日志、分页、筛选和租户隔离。 src/apps/admin/AdminSystemLogsPage.tsxsrc/apps/client/ClientSystemLogsPage.tsx 页面 smoke 可展示,但未证明调用真实日志 API。 接入真实日志 API,支持分页、筛选、详情、租户隔离,失败动作也可查。
BUG-FE-005 P0 企业应用 CMPP 状态和连接详情页面仍使用本地初始数据,未读取真实连接状态 API。 src/apps/admin/AdminEnterpriseApplicationsPage.tsx 使用 initialSmsAppssetSmsApps,连接删除也是本地状态变更。 接入企业应用、连接状态、连接详情、连接删除/断开真实 API 或 Gateway 回写接口。
BUG-API-001 P1 通道创建参数缺失时返回 Prisma 500,而不是业务 400。 浏览器 smoke 第一轮 POST /api/admin/channels 缺少 code/gatewayHost/gatewayPort/account/passwordCipher/srcIdAPI 返回 Internal server error。 为通道创建 DTO 增加校验,缺失必填字段返回 400 和可读错误,并写失败日志。
BUG-DEV-001 P1 npm run dev 在 5173 被占用后切到 5174Vite 依赖 bundling 长时间未完成,浏览器看到白屏。 本轮浏览器测试中 5174 HTTP 后续可达,但首次打开截图为空白;生产 build/preview 正常。 检查 Vite dev 依赖预构建和端口占用问题,确保开发模式可稳定渲染。
BUG-SEND-001 P0 发送路由规则允许直接绑定单个通道,违反“规则只能绑定通道组”的业务约束。 SendChainService.selectChannel() 当前存在 route?.channel ?? route?.group... 路径;ChannelRouteRule 模型也保留 channelId 字段。 路由规则只能表达应用到通道组的绑定关系;发送链路必须从企业应用绑定的运营商通道组内选路,不允许规则直接指定单个通道。
BUG-SEND-002 P0 未命中路由规则时会 fallback 到全局第一个 active 通道,可能把短信发到未配置给该企业/应用的通道。 SendChainService.selectChannel() 未找到 route 后执行 smsChannel.findFirst({ where: { status: 'active' } }) 企业应用没有配置对应运营商通道组或无可用通道时,短信直接 failed;不得进入 pending/delayed,不得 fallback 到其他 active 通道,需记录 trace/日志。
BUG-SEND-003 P0 发送选路只判断通道业务状态 active,不判断 CMPP 真实连接状态。 selectChannel() 只检查 SmsChannel.status,未查询 CmppConnectionState.status/currentConnections/lastHeartbeatAt/lastError 选路必须跳过离线、认证失败、心跳超时、重连中或 currentConnections=0 的通道;至少 1 条连接 connected 且心跳正常才可发送,连续 3 次心跳失败进入重连且不可选。
BUG-SEND-004 P0 通道组主通道提交失败、超时或回执失败后不会切换到下一个通道补发。 handleSubmitResult()handleReceipt() 只更新状态、释放/退款和刷新进度,没有重新选路或创建补发记录;retry.maxAttempts 目前未形成业务补发闭环。 除 unknown、超过 72 小时、超过通道组补发时间上限或通道组关闭补发外,submit rejected/timeout、连接断开、未提交成功、receipt failed 均需补发;省网失败后立即走全国通道,全国通道按优先级继续补发,最终成功只按企业应用客户费率扣一次。
BUG-SEND-005 P0 通道组省网/全国路由没有接入真实发送链路,手机号段库也未参与归属地识别。 SmsChannelGroupItemChannelRouteRule 虽有 carrier/province 字段,PhoneSegmentprefix/carrier/province/city,但 SendChainService.selectChannel() 未读取 message.phoneNumber、未查询 phoneSegment,只按优先级取第一个 active 通道;前端 AdminChannelGroupFormPage 的省网/全国配置仍为本地 useState 发送前按可配置号码前缀正则识别运营商,识别失败走移动通道组;按手机号段库识别省份和城市,省份识别失败走对应运营商全国通道;通道需支持移动/联通/电信/三网和全国/单省发送地区,三网作为通配。
BUG-SEND-006 P0 企业应用缺少按运营商绑定多个通道组和保存校验的真实闭环。 当前发送链路只按 tenantId/applicationId 查询单一路由规则;未体现一个应用分别绑定移动、联通、电信通道组,也未强制至少绑定一个通道组后才能保存。 企业应用可分别绑定移动、联通、电信通道组;一个都不绑定时 UI 不允许保存,发送时直接 failed;移动、联通、电信短信按识别结果进入对应通道组。

2026-07-03 通道组真实路由和补发修复

本轮修复范围

  • BUG-SEND-001:后端 createRouteRule 禁止直接绑定单通道,路由规则只能绑定应用、运营商和通道组;发送链路不再读取 route.channel
  • BUG-SEND-002:发送链路未找到企业应用对应运营商通道组或无可用在线通道时,短信直接标记 failed,不再 fallback 到全局第一个 active 通道。
  • BUG-SEND-003:发送选路加入 CMPP 连接状态过滤,通道必须业务 active、连接 connecteddesiredConnections > 0currentConnections > 0 才可选;online/open 仅作为旧 Gateway 回写兼容词入库归一化。
  • BUG-CMPP-STATUS-001:新建/启用通道后若 Gateway 连接请求长时间无回写,API 后台兜底任务会将超过 30 秒的 connecting 连接标记为 failed,写入超时原因和连接日志,避免页面长期停留“连接中”。
  • BUG-SEND-004submit rejected、submit timeout、回执 failed 等失败场景会在补发开启且未超过时间限制时,排除已尝试通道并切换到同一通道组全国通道继续提交;unknown、超过 72 小时、超过通道组补发上限或关闭补发时不补发。
  • BUG-SEND-005:新增 PhoneCarrierRule 运营商前缀正则配置,发送前先识别运营商,识别失败默认移动;手机号段库用于识别省份,省份识别失败走对应运营商全国通道;通道新增 sendRegion,支持全国或单省。
  • BUG-SEND-006:企业应用创建页面可分别选择移动、联通、电信通道组,一个都不选时 UI 阻止保存;创建应用成功后写入真实通道组路由规则。
  • 前端配置补充:通道创建支持移动、联通、电信、三网和发送地区;手机号段库新增“运营商区分规则”tab。

新增/更新测试

测试文件 新增覆盖
api/src/send-chain/send-chain.service.spec.ts 应用运营商通道组路由、在线连接过滤、失败不 fallback、补发关闭时释放/退款。
api/src/channels/channels.service.spec.ts 通道发送地区默认值、通道组补发配置、禁止单通道路由规则。

已执行命令

npm --prefix api run prisma:generate
npm --prefix api test -- send-chain.service.spec.ts channels.service.spec.ts --runInBand
npm --prefix api test
npm --prefix api run build
npm run build
npm run verify:phase8                         # 阻塞:BullMQ spike endToEndTps 未达到 500
npm run spike:bullmq                          # 复跑仍未达到 500

当前结果

  • Prisma Client generate:通过。
  • API Jest10 个 test suite 通过,50 个测试通过。
  • API build:通过。
  • 前端 build:通过,仍存在既有大 chunk warning。
  • npm run verify:phase8:未通过,阻塞在 spike:bullmq 性能阈值;第一次 endToEndTps=464.58,复跑 npm run spike:bullmq endToEndTps=495.97,第三次 endToEndTps=477.17,均低于 500 TPS 阈值。
  • 尚未执行真实 PostgreSQL/Redis/Gateway 端到端 smoke;需在生产验证或本地真实服务环境中覆盖 TC-SEND-010TC-SEND-018TC-CMPP-STATUS-008A

2026-07-02 真实后端缺口修复

本轮修复范围

  • BUG-FE-001:运营端充值记录页移除 rechargeRecordsSeed 验收路径,加载真实租户、人工充值记录、账户余额和账户流水;确认人工充值调用 POST /api/admin/billing/manual-recharges,成功后刷新真实记录、账户、流水,并由后端写 billing.manual_recharge 操作日志,不产生 pending 审批态。
  • BUG-FE-002:运营端 Dashboard 移除 adminService、静态趋势和前端排行计算,改为调用 GET /api/admin/operations/dashboard/statistics、真实通道 API 和真实账户聚合。
  • BUG-FE-003:客户端 Dashboard 移除 clientService、静态趋势和本地 mock,改为调用 GET /api/client/operations/dashboard、客户端账务/任务聚合,并通过 x-tenant-id 限定当前租户。
  • BUG-FE-004:运营端和客户端系统日志页移除静态 logsSeed,接入真实日志 API,支持分页、关键字、级别、模块和时间范围;长详情使用详情卡展示 JSON 摘要。
  • BUG-FE-005:企业应用管理短信应用 tab 接入真实企业应用、租户连接状态、连接详情和 CMPP 参数 API;断开连接调用真实后端并写系统日志,变更后刷新列表。彩信 tab 仍为第一版待开发路径,不作为短信验收依据。
  • BUG-API-001:通道创建在 Service 层校验 code/name/gatewayHost/gatewayPort/account/passwordCipher/srcId,缺失或端口非法返回 400,不再让 Prisma validation error 冒泡成 500。
  • BUG-DEV-001:复现 Vite 8 dev server 在端口切换后依赖/模块转换请求超时,导致白屏;根 npm run dev 改为先 npm run buildvite preview --host 0.0.0.0,确保本地打开稳定。vite.config.ts 保留 optimizeDeps.noDiscovery,避免自动扫描引发的预构建卡住。

新增/更新测试

测试文件 新增覆盖
api/src/channels/channels.service.spec.ts 通道创建缺少必填字段时返回可读 400。
api/src/billing/billing.service.spec.ts 人工充值写入 billing.manual_recharge 操作日志。
api/src/operations/operations.service.spec.ts Dashboard 新增今日统计、账户/充值/待审核聚合和系统日志分页详情。
api/src/sms-config/sms-config.service.spec.ts 企业应用列表聚合真实 CMPP 连接状态、CMPP 参数读取、断开连接写日志。

已执行命令和 Smoke

npm --prefix api test
npm --prefix api run build
npm run build
npm run dev

# API HTTP smoke on API_PORT=3101
GET  /api/health
POST /api/admin/channels                 # 缺必填字段返回 400
GET  /api/admin/operations/dashboard/statistics
GET  /api/admin/system-logs?page=1&pageSize=2

当前结果

  • API Jest8 个 test suite 通过,43 个测试通过。
  • API build:通过。
  • 前端 build:通过,仍存在既有大 chunk warning。
  • npm run dev:通过,当前会 build 后启动 Vite preview,实际可访问 http://localhost:4173/,避免 Vite 8 dev optimizer/transform 白屏。
  • 浏览器 smoke 通过:
    • 运营端 Dashboard 渲染真实聚合指标,无相关 console error。
    • 运营端人工充值页渲染真实记录,人工充值弹窗展示真实企业下拉和确认入口。
    • 运营端系统日志页渲染真实日志,长详情以卡片展示。
    • 企业应用管理页渲染真实应用和 CMPP 状态,连接详情弹窗和 CMPP 参数弹窗可打开。
    • 客户端 Dashboard 和客户端系统日志页按当前租户渲染,无相关 console error。
  • API HTTP smoke/api/health 返回 ok;通道缺参返回 400 和可读错误;dashboard/statistics、system-logs 返回真实数据。

剩余说明

  • npm run dev 为稳定预览模式,不提供 Vite HMR;保留原因是 Vite 8/Rolldown dev transform 在当前 Windows + 中文路径工作区下会阻塞模块请求并造成白屏。开发时如需热更新,可另行评估降级 Vite 或迁移工作区路径后恢复原生 dev server。

2026-07-02 登录与用户管理闭环补充

本轮修复范围

  • 新增用户登录字段和 fail2ban 持久化字段:emailphonefailedLoginCountlockedUntillastLoginAtdeletedAt
  • 登录入口拆分为 /client/login/admin/login,两端均调用真实验证码和登录 API。
  • 用户登录入口和用户表单统一文案为“用户名/登录账号”,提示可用用户名、邮箱或手机号登录。
  • 运营端登录仅允许 platform_admin;客户端登录仅允许已关联企业的 enterprise_admin
  • 运营端用户管理接入真实 /api/admin/users,支持平台管理员和企业管理员的新增、编辑、启用/禁用、删除、改密;企业管理员必须关联企业。
  • 客户端用户管理接入真实 /api/client/users,所有操作继承当前登录企业 tenantId
  • 启用/禁用、删除均通过确认弹窗执行;用户删除采用软删除,不破坏历史日志和业务记录。
  • 连续 5 次登录失败后锁定 24 小时;登录成功清空失败次数和锁定状态。

已执行测试

npm --prefix api test -- users.service.spec.ts auth.service.spec.ts
npm --prefix api run prisma:generate
npm --prefix api run build
npm run build

当前结果

  • users.service.spec.tsauth.service.spec.ts:通过,覆盖用户类型约束、企业关联约束、操作日志、端登录隔离和失败次数累计。
  • API build:通过。
  • 前端 build:通过,仍有既有大 chunk warning。
  • tools/smoke/real-env-smoke.mjs 已同步企业管理员邮箱/手机号、角色 seed、验证码登录和 CMPP 端口 17890
  • 真实数据库迁移、浏览器端登录 smoke 需要在预发布环境执行 prisma migrate deploy 后补充记录。

2026-07-02 非彩信纯 mock 菜单真实化

本轮修复范围

  • 客户端:充值套餐、账单流水、批量任务、短信发送、短信签名、短信模板改为调用真实 API;签名材料使用真实文件元数据和材料关联接口;发送任务调用真实批量任务接口。
  • 运营端:数据统计、账务账户、发送监控、敏感词、全局黑名单、企业黑名单、手机号段库、报备字段库、通道组、通道报备字段、报备任务、报备记录、短信审核、短信记录改为真实 API。
  • 企业管理:客户列表、客户表单、客户详情由 adminEnterpriseMock/localStorage 改为真实租户、账户、应用、签名、模板接口;后端补充租户编辑、状态变更和删除接口。
  • 通道管理:删除静态通道兜底,API 失败展示错误态。
  • 企业认证审核:删除静态认证兜底,API 失败展示错误态。
  • 企业签名/企业模板运营端列表只展示真实短信配置数据;彩信相关菜单继续作为待开发边界,不计入第一版短信验收。

已执行命令

npm --prefix api test
npm --prefix api run build
npm run build
npm run verify:phase8

当前结果

  • API Jest10 个 test suite 通过,49 个测试通过。
  • API build 通过。
  • 前端 build 通过,仍存在既有大 chunk warning。
  • npm run verify:phase8 通过:
    • Gateway 队列契约 4 个示例通过。
    • Go Gateway 测试通过。
    • BullMQ 15000 条消息、并发 500、端到端 TPS 681.47,满足 500 TPS。
    • Prisma generate、API build、前端 build 均通过。
  • 源码搜索剩余静态业务数据集中在彩信待开发页面、彩信审核页面、企业应用彩信 tab,以及 src/api/session.ts 的登录 session 持久化;非彩信主菜单的 clientService/adminService 业务路径已清理。

待复测

  • 浏览器 smoke 和真实文件上传 smoke 需要在预发布环境补跑,重点复测客户端发送、签名材料上传、短信审核、短信记录、客户管理和报备任务。

2026-07-03 单运营商通道组、应用级费率和回执幂等

本轮修复范围

  • 通道组规则:
    • SmsChannelGroup.carrier 固化为移动、联通、电信三选一,禁止三网通道组。
    • SmsChannelGroupItem.carrier 保留并参与发送,必须等于通道组运营商。
    • 三网只作为通道本体能力 SmsChannel.carrier=all,放入某个通道组后只服务该组运营商。
    • 同一通道组内同一省份只能配置一个通道;省份 item 必须引用发送地区一致的通道。
    • 全国通道允许多个,但同一通道组内全国通道优先级禁止重复;本期不做权重分流。
    • 路由规则必须绑定应用、运营商、通道组,且 route carrier 必须等于 group carrier。
  • 发送和计费规则:
    • 运营商以号码前缀正则为准;手机号段库只提供省份/城市,carrier 仅作后台提示或校验。
    • 发送前校验最终选中通道的签名报备任务为 approved,补发切换通道时重新校验。
    • 企业应用新增 customerUnitPrice,客户扣费按应用级客户费率;通道成本只作内部成本。
    • 迟到旧通道 failed receipt 不覆盖新通道 delivered 最终状态;历史回执仍入库可查。
    • 重复 submit/receipt 回调不得重复扣费、释放冻结或退款。
    • 补发使用触发时当前通道组配置;本期不考虑人工重发。
  • 前端和真实 smoke
    • 企业应用表单增加客户单价输入,保存时写入真实应用 API。
    • 企业应用按移动、联通、电信分别选择通道组,选项按通道组 carrier 过滤。
    • 真实 smoke seed 补充应用客户单价、三网通道放入移动组、签名-通道 approved 报备。

新增/更新测试

测试文件 新增覆盖
api/src/channels/channels.service.spec.ts 单运营商通道组、通道组 item carrier 校验、通道 carrier 兼容、省份与发送地区一致、同省唯一、全国优先级唯一、route carrier 与 group carrier 一致。
api/src/send-chain/send-chain.service.spec.ts 通道组 item carrier 参与发送、最终通道签名报备校验、应用级客户费率、迟到旧 failed receipt 不覆盖 delivered、重复账务动作幂等。
api/src/sms-config/sms-config.service.spec.ts 应用配置与列表在新增客户费率字段后继续通过。

已执行命令

npm --prefix api run prisma:generate
npm --prefix api test -- channels.service.spec.ts send-chain.service.spec.ts sms-config.service.spec.ts --runInBand
npm --prefix api test
npm --prefix api run build
npm run build
npm --prefix api run prisma:migrate:deploy
$env:API_PORT='3101'; $env:API_ENABLE_SEND_WORKER='true'; npm --prefix api run start:dev
node tools/smoke/real-env-smoke.mjs
node <inline channel-group rule HTTP smoke>
npm run spike:contracts
npm run test:gateway
npm run verify:phase8

当前结果

  • Prisma Client 生成通过。
  • 新增迁移已应用到真实 PostgreSQL
    • 20260703143000_add_channel_group_carrier
    • 20260703152000_add_application_customer_rate
  • API Jest10 个 test suite 通过,56 个测试通过。
  • API build 通过。
  • 前端 build 通过,仍存在既有 Vite chunk size warning。
  • 真实 API smoke 通过:
    • tools/smoke/real-env-smoke.mjs 通过,验证真实 API、Prisma/PostgreSQL、Redis/BullMQ、登录、充值、发送任务、worker 入队、文件上传元数据和操作日志。
    • inline 通道组规则 HTTP smoke 通过,覆盖三网组拒绝、item carrier 不匹配拒绝、通道 carrier 不兼容拒绝、省份/发送地区不匹配拒绝、同省重复拒绝、全国优先级重复拒绝、route carrier/group carrier 不匹配拒绝。
  • Gateway 队列契约通过,4 个示例均验证通过。
  • npm run test:gateway 通过,Go Gateway health、connection、tracker、cmpp、spike 测试全部通过。
  • npm run verify:phase8 未通过,仍阻塞在已知 BullMQ spike 性能阈值:
    • 15000 条消息、并发 500。
    • enqueue TPS 3139.43。
    • end-to-end TPS 479.02,低于 500 TPS。

剩余说明

  • verify:phase8 当前失败点是独立 BullMQ 性能阈值,不是本轮通道组、计费、报备、回执业务逻辑测试失败。
  • 浏览器端完整手工回归仍建议补跑企业应用创建、通道组配置、短信记录详情弹窗中的历史回执展示。

2026-07-07 Gateway 下游 CMPP 入站第一阶段补齐

本轮修复

  • Go Gateway 启动时同时监听 GATEWAY_CMPP_ADDR,默认生产端口 0.0.0.0:17890,不再只是 HTTP /health 控制服务。
  • 新增企业应用独立 6 位 cmppAccountPrisma 迁移 20260707162000_add_application_cmpp_account 会为存量应用生成账号;客户端/运营端 CMPP 参数接口返回该应用独立账号。
  • Gateway 下游 CMPP bind 使用真实 gocmpp 协议解析 Source_Addr/AuthSource/Timestamp,调用 NestJS /api/gateway/events/inbound/authenticate,由真实数据库校验应用账号、应用 CMPP 密码、企业状态、企业认证状态、应用状态和 IP 白名单。
  • Gateway 下游 CMPP submit 解码 CMPP 3.0 SubmitReq,调用 NestJS /api/gateway/events/inbound/submitNestJS 按 sourceType=cmpp 创建发送记录并复用模板/签名/风控/余额/运营商识别/通道组路由/队列优先级链路。
  • Go Gateway 新增入站集成测试,覆盖本地 CMPP 客户端 connect/login、UCS2 submit 和 API 回调。

验证状态

  • npm --prefix api run prisma:generate:通过。
  • npm --prefix api test -- sms-config.service.spec.ts send-chain.service.spec.ts --runInBand:通过。
  • npm --prefix api run build:通过。
  • go test ./...Gateway):通过。

剩余缺口

  • 下游连接状态回写、连接数上限、断开/心跳历史日志仍需继续产品化。
  • 下游 submit 当前通过 sourceType=cmpp 的系统批次兼容承载,尚未完全拆成独立单条发送模型。
  • 客户侧最终 Deliver Receipt 投递、客户侧上行 Deliver 推送、上游真实 SMSC submit worker、上游 receipt/uplink 生产解析仍未完成。

2026-07-11 Gateway 客户侧 Submit 日志完善

本轮修复

  • Gateway 入站 Submit 日志增加 submit_receivedsubmit_acceptedsubmit_rejected 结构化事件,同时记录 CONNECT 声明的客户协议版本与 Go 实际解包类型,并记录账号、客户 IP、sequenceId、号码、srcId、编码、分片、CMPP result、平台 messageId、CMPP Msg_Id 和处理耗时。
  • Gateway HTTP 回调在 NestJS 返回非 2xx 时保留最多 64KB 响应体,客户 Submit 失败日志可直接显示模板不匹配、IP 白名单、余额或路由等真实业务原因,不再只显示 HTTP 状态码。
  • 日志不记录明文短信正文,仅记录字符数和 MD5 哈希,便于比对同一内容且避免日志泄露。
  • 将当前 gocmpp 版本固定为仓库内小型 fork,仅在 server 循环补充底层诊断:包在进入业务 handler 之前发生长度、命令字、包体读取或 Unpack 失败时,记录 read/unpack packet failed、远端地址、库解析协议模式、Go 错误类型和原始错误;正常 EOF 断开不记为解包失败。
  • 生产复现确认 CMPP2.0 客户 Submit 被固定 CMPP3.0 解包导致 MsgSrc/手机号/内容 错位为空。现在 gocmpp server 按 CONNECT Version 将每条连接切换到 CMPP2.0/2.1/3.0 解包模式,并返回同版本 ConnectResp、SubmitResp 和 Deliver。
  • Gateway 使用 bind 时已鉴权会话账号调用 NestJS 入站接口,Submit MsgSrc 改为与鉴权返回的应用级 cmppEnterpriseCode 独立比对,不再将企业代码误当登录账号。

验证状态

  • go test ./internal/inbound -count=1:通过。
  • go test ./... -count=1:通过。
  • go build ./cmd/gateway:通过。
  • 真实 TCP 非法包用例:向入站端口写入非法 total_length,确认业务 handler 未执行时仍产生 read/unpack packet failed 日志。
  • CMPP2.0 真实集成用例:客户使用与登录账号不同的 MsgSrc=SP0001,完成 V20 ConnectResp、Cmpp2SubmitReq/Resp 和 Cmpp2Deliver ReceiptNestJS 收到的 account 仍为 bind 账号:通过。
  • 已将合并后提交 bb4992f0 部署到预发布环境;Prisma 无待执行迁移,前端/API/Gateway 构建和标准健康检查通过,12026/3000/8090/17890 监听正常。生产账号 910887 重连日志确认 requested_version=0x20 response_version=0x20;该测试应用的 cmppEnterpriseCode 已通过真实运营 API 同步为 910887

2026-07-07 Gateway 上游提交与下游 Deliver 闭环补齐

本轮修复

  • SubmitCommand 契约、示例和 Go 结构增加 upstream.gatewayHost/gatewayPort/account/passwordCipher/cmppVersion,API 发送链路在真实业务校验通过后保留 BullMQ 审计投递,同时写入 Redis Stream gateway.submit.commands 主命令流。
  • Go Gateway 新增上游提交管理器,按通道建立/复用 gocmpp 客户端连接,发送真实 CMPP Submit,接收 SubmitResp,并回调 NestJS SubmitResult
  • Go Gateway 上游读循环开始处理 deliver receipt 和普通 deliver 上行:receipt 解析后回调 NestJS /gateway/events/receipt,普通上行解码后回调 /gateway/events/uplink
  • Gateway 下游入站服务记录客户 Submit 对应的 messageId 到在线客户连接映射;NestJS 收到最终 receipt/uplink 并入库后调用 Gateway /downstream/receipt/downstream/uplinkGateway 向在线客户下发 CMPP Deliver Receipt 或普通 Deliver。
  • api/src/send-chain/send-chain.service.spec.ts 覆盖 SubmitCommand 上游配置和 Redis Stream 发布;gateway/internal/inbound/server_test.go 覆盖客户 submit 后平台下发 Deliver ReceiptGateway 契约示例覆盖新 upstream 字段。

验证状态

  • npm --prefix api test -- send-chain.service.spec.ts:通过。
  • npm --prefix api test:通过,12 个 suites、82 个 tests。
  • npm --prefix api run build:通过。
  • go test ./...Gateway):通过。
  • npm run spike:contracts:通过,4 个 Gateway 队列契约示例通过。

剩余缺口

  • Gateway 控制面 /upstream/submit 仅保留为调试/补偿入口;生产主链路由 Go Gateway submit worker 消费 Redis Stream gateway.submit.commands 触发。worker 当前覆盖新消息 > 消费和 ack,pending 历史消息扫描与精细重试治理放入后续在途恢复阶段。
  • 客户侧 Deliver Receipt/上行 Deliver 当前依赖 Gateway 内存在线连接映射;客户断线、Gateway 重启或映射丢失时尚未实现持久化缓存、重试和投递失败审计。
  • 普通上行只有能关联 messageId 的事件可推送给客户;仅按接入号、手机号、应用和时间窗口匹配客户连接仍待产品化。
  • 长短信拆分/重组、多连接窗口、窗口满、在途消息恢复、断线重连后的状态补偿仍待后续实现和压测。

2026-07-07 阶段 1Gateway SubmitCommand 独立消费

本轮修复

  • NestJS SendChain 取消主链路同步调用 Gateway /upstream/submit;真实业务校验通过后创建 SmsSubmitRecord、保留 BullMQ gateway.submit.queue 审计/兼容投递,并向 Redis Stream gateway.submit.commands 写入 SubmitCommand
  • Go Gateway 新增 submitworker,启动时默认创建/复用 consumer group cmpp-gateway,独立消费 Redis Stream 中的 SubmitCommand,调用同一个上游提交管理器真实 submit 到上游 SMSC。
  • Gateway /upstream/submit 保留为调试/运维补偿接口,不作为 API 主发送路径。
  • Gateway worker 支持环境变量:REDIS_URLGATEWAY_SUBMIT_STREAMGATEWAY_SUBMIT_GROUPGATEWAY_SUBMIT_CONSUMERGATEWAY_SUBMIT_WORKER_DISABLED=true

验收口径

  • API 入队后不再因为 Gateway 控制面短暂不可达而自己生成 timeoutSubmitResult 必须由 Gateway worker 真实消费和提交后回调。
  • Gateway 停止时,SubmitCommand 留在 Redis StreamGateway 恢复后由 consumer group 继续消费新消息。
  • BullMQ gateway.submit.queue 仅作为审计/兼容,不再是唯一主提交通道。

剩余边界

  • 当前 worker 先覆盖新消息 > 消费和 ackpending 历史消息扫描、claim、重试退避和死信审计放到在途恢复阶段继续做。

2026-07-07 阶段 2/3:客户侧 Deliver 持久化重投与普通上行匹配

本轮修复

  • Prisma 新增 CmppDownstreamDelivery,用于保存客户侧待投递 Deliver Receipt 和普通 Deliver 上行;状态覆盖 pending/delivered,记录 retryCount、nextRetryAt、lastError、payload、message/application 关联。
  • SmsUplinkMessage 增加 applicationIdmessageRecordIdmatchStatusmatchReason,并建立应用和匹配下发记录关系。
  • NestJS 收到最终 receipt 后,先写平台回执和消息状态,再创建客户侧待投递记录,尝试调用 Gateway /downstream/receipt;成功标记 delivered,客户不在线或 Gateway 不可达时保留 pending 并记录失败原因。
  • NestJS 收到普通上行后执行匹配:messageId 精确匹配优先;无 messageId 时按接入号匹配应用路由;仍无唯一应用时按手机号和最近下发时间窗口匹配;多候选标记 ambiguous,未匹配标记 unmatched,但均真实入库。
  • Gateway 下游客户 bind/login 成功后保存账号级在线连接,并调用 NestJS /gateway/events/downstream/pending 拉取 pending 投递;补发成功后回调 /gateway/events/downstream/delivered,失败回调 /gateway/events/downstream/failed
  • 运营/客户端上行查询 include 应用和匹配下发记录,便于页面展示 matchStatus/matchReason。

验证状态

  • npm --prefix api run prisma:generate:通过。
  • npm --prefix api test -- send-chain.service.spec.ts:通过。
  • npm --prefix api test:通过,12 个 suites、82 个 tests。
  • npm --prefix api run build:通过。
  • go test ./...Gateway):通过。
  • npm run spike:contracts:通过。
  • npm run build:通过,仅既有 Vite chunk size warning。

剩余边界

  • 待投递 pending 目前在客户 bind/login 时拉取补发;后台周期扫描、指数退避、过期策略、死信队列和运营端失败审计页面仍待后续实现。
  • 上行匹配已覆盖 messageId、接入号和手机号时间窗口;共享接入号、多应用多候选时不会误推,但人工认领/改派流程尚未实现。
  • 客户连接断开检测和应用级连接数状态回写仍需继续产品化。

2026-07-08 阶段 4Gateway 长短信拆分与长上行重组

本轮修复

  • Go Gateway 上游 Submit 支持长短信第一版拆分:超过 140 字节的短信按 CMPP 标准 6 字节 UDH 生成分片,每片总长度不超过 140 字节,并设置 PkTotal/PkNumber/TpUdhi 后逐包发送到上游 SMSC。
  • 同一平台 SubmitCommand 的多个 accepted 分片 MsgId 均登记到 Gateway 映射表,后续任一分片 receipt 可回溯到原 messageId/submitId/channelId
  • Go Gateway 上游普通 Deliver 支持长上行第一版重组:收到 TpUdhi=1 且携带标准 UDH 的分片时,按通道、主叫、被叫、引用号和总片数缓存;分片齐全后只回传一条完整 UplinkEvent 给 NestJS。
  • 新增 gateway/internal/upstream/long_message_test.go,覆盖 UCS2 长短信拆分、短短信不分片、长上行乱序重组。

验证状态

  • go test ./...Gateway):通过。

剩余边界

  • 阶段 4 后长短信仍按单条平台消息记录展示,尚未提供运营端分片级提交明细、分片级补发审计和部分分片失败后的精细补偿;该审计缺口已在阶段 23 补齐第一版。
  • 长上行分片缓存当前为 Gateway 进程内内存;Gateway 重启、跨连接分片漂移或超过缓存 TTL 的残片不会恢复,后续在“在途消息恢复/状态补偿”阶段继续做。

2026-07-08 阶段 5Gateway 多连接窗口与窗口满控制

本轮修复

  • SubmitCommand.upstream 契约、示例、Go 结构和 NestJS 生产者增加 desiredConnections/windowSize,字段来自通道真实配置;未配置时默认 desiredConnections=1windowSize=16
  • Go Gateway 上游提交管理器从单连接升级为通道级连接池:同一通道按 desiredConnections 建立多条 CMPP 客户端连接,每条连接独立维护 submit pending、receipt/uplink 映射和长上行分片缓存。
  • 每条上游连接增加窗口令牌;提交前必须获得窗口,SubmitResp、reject 或 timeout 后释放窗口;所有连接窗口均满时等待可用窗口,超过提交超时时返回 WINDOW_TIMEOUT
  • 长短信分片也复用连接池窗口调度,同一条平台消息的多个 accepted 分片仍映射回原 messageId/submitId/channelId
  • 新增 gateway/internal/upstream/pool_test.go,覆盖连接池跨连接获取窗口、窗口满拒绝继续占用、释放后可重新获取。

验证状态

  • go test ./...Gateway):通过。
  • npm --prefix api test -- send-chain.service.spec.ts:通过。

剩余边界

  • 当前窗口状态为 Gateway 进程内控制,尚未把连接级窗口占用、等待队列长度、submit latency 等指标回写到 NestJS 或运营端页面。
  • 当前阶段只处理窗口容量和多连接发送;Gateway 重启、上游连接断开时的在途 submit 恢复、pending claim、状态补偿和死信审计仍在下一阶段处理。

2026-07-08 阶段 6CMPP 配置入口补齐

本轮修复

  • 运营端通道创建/编辑表单新增上游 desiredConnectionswindowSize 输入,真实提交到 NestJS 通道 API,并规范化写入 SmsChannel.config
  • NestJS ChannelsServicedesiredConnections/windowSize 增加正整数校验;通道激活后的 ConnectChannel 请求和发送链路 SubmitCommand.upstream 均复用该真实配置。
  • Prisma 为 SmsApplication 新增 cmppMaxConnectionscmppWindowSize 字段;运营端短信应用创建/编辑表单新增 cmppAccount 和客户最大连接数输入,客户提交窗口暂不展示给运营配置,保留后端默认值。
  • 企业应用 cmppAccount 现在支持两种真实路径:显式填写 6 位数字账号,或留空由后端自动生成唯一账号;重复账号和非法格式会被后端拒绝。
  • 企业应用 CMPP 参数接口改为从应用真实字段返回 enterpriseCode/account/passwordCipher/maxConnections/windowSize,不再借用任意通道企业代码或默认值拼装客户参数。
  • 应用级 cmppEnterpriseCode 新建/编辑可自定义;接口密码新建默认随机 16 位 UUID 片段,编辑留空不覆盖、填写 16 位后更新。AppID 仅作为平台应用标识展示,不作为 CMPP 协议认证参数。

验证状态

  • npm --prefix api run prisma:generate:通过。
  • npm --prefix api test -- sms-config.service.spec.ts channels.service.spec.ts:通过,2 个 suites、34 个 tests。
  • npm --prefix api run build:通过。
  • npm run build:通过,仅既有 Vite chunk size warning。

说明

  • desiredConnections/windowSize 不是 CMPP 协议标准字段,也不是 gocmpp 的原生配置项;它们是本平台对上游通道连接池和提交窗口的运行参数。
  • cmppAccount 是客户侧应用接入账号;当前已支持真实生成、真实保存和显式配置。

2026-07-08 阶段 7SubmitCommand 在途恢复第一步

本轮修复

  • Go Gateway submitworker 在正常消费新消息前新增 pending 恢复流程:对 Redis Stream consumer group 中空闲超过阈值的消息执行 XAUTOCLAIM,将滞留在 PEL 的 SubmitCommand 认领到当前 consumer。
  • 被认领的 pending 命令复用现有 handleMessage -> Upstream.Submit -> XAck 成功路径处理;成功后 ack,失败时保留在 PEL,留给后续重试/死信治理。
  • submitworker 增加可注入 Submit 函数,便于单测覆盖消息处理路径;新增单测覆盖 injected submit 和默认 minIdle 阈值。

验证状态

  • go test ./...Gateway):通过。

剩余边界

  • 当前恢复能力只覆盖 Redis Stream PEL 中“已被读走但未 ack”的 pending 命令;尚未实现恢复次数上限、死信队列、失败审计页面和人工补偿入口。
  • Gateway 重启时上游连接内已经发出但尚未收到 submit resp 的 in-flight CMPP 请求,仍未完成状态补偿;这部分继续放在后续“断线重连后的消息状态处理”阶段。

2026-07-08 阶段 8:上游连接断开时 pending submit 补偿

本轮修复

  • Go Gateway 上游连接读循环开始区分“空读超时”和“真实连接断开”;空读超时继续等待,真实断开则进入连接丢失处理。
  • 某条上游连接断开时,Gateway 会把该连接上所有等待 submit resp 的 pending submit 立即唤醒,返回 timeout + CONNECTION_LOST,不再机械等待固定 SUBMIT_TIMEOUT
  • 连接池在再次分配连接前会重新执行 ensureConnected();旧连接断开后,后续新消息可重新建立物理连接继续提交。
  • 新增 gateway/internal/upstream/connection_loss_test.go,覆盖 pending submit 被唤醒和临时读超时识别。

验证状态

  • go test ./...Gateway):通过。
  • npm --prefix api test -- send-chain.service.spec.ts:通过。

剩余边界

  • 当前补偿只覆盖“连接断开且 submit resp 尚未返回”的场景;尚未覆盖“上游其实已受理,但 submit resp 在断线前后丢失”的二次确认和幂等回查。
  • submit 结果死信队列、失败审计、恢复次数上限和人工补偿入口仍在后续阶段。

2026-07-08 阶段 9receipt 驱动的保守二次归因

本轮修复

  • Gateway 上游 receipt 事件补充 phoneNumber,即使无法从内存 tracker 中精确恢复平台 messageId,也会把运营商回执手机号带回 NestJS。
  • NestJS handleReceipt 新增保守归因:如果 receipt 无法按平台 messageId/gatewayMessageId 精确命中,只在“同通道、同手机号、72 小时窗口内、且仅存在 1 条 timeout + gatewayMessageId=null 的 submit 记录”时才接收该回执。
  • 归因成功后会先回填该次 sms_submit_record.gatewayMessageId/sequenceId,再写入真实 sms_receipt_record 并按既有逻辑更新 sms_message_record、下游客户回执推送和幂等保护。
  • 新增 SendChainService 单测,覆盖唯一候选归因成功和多候选拒绝归因两种场景。

验证状态

  • go test ./...Gateway):待本轮统一回归。
  • npm --prefix api test -- send-chain.service.spec.ts:待本轮统一回归。

剩余边界

  • 当前只做“唯一候选才归因”的保守版本,仍未实现面向运营商或供应商的 submit 结果主动回查。
  • 如果同通道同手机号在窗口内存在多条 timeout 候选,系统会拒绝归因,后续仍需人工补偿或更强的协议级关联键。

2026-07-08 阶段 10SubmitCommand 死信治理第一版

本轮修复

  • Prisma 新增真实表 GatewaySubmitDeadLetter,保存 Gateway SubmitCommand 死信的消息 ID、租户/应用/通道、失败原因、尝试次数、原始命令载荷、人工重入队状态和解决状态。
  • Go Gateway submitworker 新增失败次数治理:同一条 Stream 消息处理失败达到阈值后,调用 NestJS /gateway/events/dead-letter 入库死信,并对原消息执行 ack,避免它无限滞留在 PEL。
  • Gateway 对非法 SubmitCommand 载荷也会直接转死信,防止 poison message 持续阻塞消费。
  • NestJS 新增真实死信接口:Gateway 可上报死信;运营端后端可分页查询 /api/admin/operations/gateway-submit-dead-letters;可通过 /api/admin/operations/gateway-submit-dead-letters/:id/requeue 将原始 SubmitCommand 重新写回 Redis Stream。
  • NestJS 在收到同一 submitId/messageId 的后续真实 SubmitResult 时,会把对应死信自动标记为 resolved

验证状态

  • npm --prefix api run prisma:generate:通过。
  • npm --prefix api test -- send-chain.service.spec.ts operations.service.spec.ts:通过,2 个 suites、26 个测试通过。
  • npm --prefix api run build:通过。
  • go test ./...Gateway):通过。

剩余边界

  • 当前死信治理只提供“达到阈值后入库 + 人工重入队”的第一版,尚未实现后台自动重放、重放节流、过期清理和专门的前端运营页面。
  • 非法载荷死信如果缺少完整 SubmitCommand,当前不可人工重放,只能用于审计和人工排查。

2026-07-08 阶段 11:下游客户在线时周期补投与失败封顶

本轮修复

  • 明确责任边界:客户系统负责断线后的重新 bind;平台负责客户不在线或临时投递失败时的消息不丢、待投递保存和补投。
  • Go Gateway 下游入站服务新增在线账号周期补投:除客户 bind 成功后立即拉取 pending 外,Gateway 还会按周期为当前在线账号再次调用 /gateway/events/downstream/pending,继续补发未投递成功的 Deliver Receipt/上行 Deliver。
  • Gateway 向下游发送 Deliver 失败时会清理失效的内存会话映射,避免对已失效连接无休止重复尝试。
  • NestJS markDownstreamDeliveryFailed 新增失败上限:未超过阈值时继续 pending 并推进 retryCount/nextRetryAt;达到阈值后转为 failed,停止无限重试,并写 gateway.downstream_delivery_failed 系统日志。

验证状态

  • npm --prefix api test -- send-chain.service.spec.ts:通过,1 个 suite、21 个测试通过。
  • go test ./internal/inbound ./internal/control ./...Gateway):通过。

剩余边界

  • 当前周期补投只针对“Gateway 认为客户在线”的账号;尚未实现下游投递失败专门列表、人工重投页面和跨 Gateway 实例共享的客户在线状态。
  • CmppDownstreamDelivery 目前仍使用固定重试间隔,尚未实现指数退避、不同消息类型差异化策略和过期归档。

2026-07-08 阶段 12:下游投递失败审计与人工重投

本轮修复

  • 运营端新增真实下游投递查询接口 /api/admin/operations/downstream-deliveries,支持按 tenantId/applicationId/deliveryType/status/keyword 筛选并分页返回真实 CmppDownstreamDelivery 数据。
  • NestJS 新增 /api/admin/operations/downstream-deliveries/:id/requeue,可对单条下游投递记录执行人工重投,真实调用 Gateway /downstream/receipt/downstream/uplink,并写 gateway.downstream_delivery_requeue 系统日志。
  • 运营端新增“下游投递记录”页面,列表、详情、筛选和重投均接真实后端,不使用 mock、本地状态或静态数组。

验证状态

  • npm --prefix api test -- send-chain.service.spec.ts operations.service.spec.ts:通过,2 个 suites、29 个测试通过。
  • npm --prefix api run build:通过。
  • npm run build:通过,仅有既有 Vite chunk size warning。

剩余边界

  • 当前人工重投仍是单条操作,尚未提供批量重投、失败聚合告警和专门的下游投递 Dashboard。
  • 页面侧暂未做自动轮询刷新,需要手动查询或重进页面观察状态变化。

2026-07-08 阶段 13:下游投递自动退避第一版

本轮修复

  • CmppDownstreamDelivery 的失败重试从固定 60 秒改为指数退避:基础间隔来自 CMPP_DOWNSTREAM_RETRY_DELAY_MS,每次失败按 2 倍递增,并受 CMPP_DOWNSTREAM_RETRY_MAX_DELAY_MS 上限约束。
  • 这样在客户长时间离线或网络持续抖动时,平台不会每分钟机械重试同一条下游投递,能更温和地消耗 API、Gateway 和连接资源。
  • 总重试次数上限逻辑保持不变,超过 CMPP_DOWNSTREAM_MAX_RETRIES 后仍转 failed 并写失败审计。

验证状态

  • npm --prefix api test -- send-chain.service.spec.ts:通过,新增指数退避单测。

剩余边界

  • 当前退避策略还没有加入随机抖动,多个记录在同一时间失败时,后续重试时刻仍可能比较集中。
  • 退避参数当前是全局环境变量,尚未细分到 receipt/uplink 或不同客户应用级别。

2026-07-08 阶段 14:下游投递批量重投

本轮修复

  • 运营端下游投递记录页新增勾选和“批量重投”操作,仅允许对当前页的 pending/failed 记录执行批量重投。
  • NestJS 新增真实批量接口 /api/admin/operations/downstream-deliveries/requeue,逐条调用既有单条重投逻辑,返回成功/失败汇总,不用前端自行拼结果。
  • SendChainService 新增批量重投结果汇总与空选择拦截单测。

验证状态

  • npm --prefix api test -- send-chain.service.spec.ts:通过,新增批量重投单测。
  • npm --prefix api run build:通过。
  • npm run build:待本轮统一回归。

剩余边界

  • 当前批量重投只支持“勾选当前页记录”,还不支持“按筛选条件全量重投”或后台异步大批量任务。
  • 批量结果当前以内联提示为主,尚未做专门的批量执行历史与导出。

2026-07-08 阶段 15:下游投递告警第一版

本轮修复

  • OperationsService.dashboard() 新增真实下游投递告警聚合 downstreamDeliverySummary,统计 pending/failed/delivered 总量,以及“积压过久的 pending”和“最近失败”两类告警计数。
  • 运营端右上角通知新增“下游投递告警”,数量直接来自真实 Dashboard 聚合。
  • 运营看板新增下游投递告警摘要卡片,帮助运营从总览页直接感知当前下游投递异常。

验证状态

  • npm --prefix api test -- operations.service.spec.ts:随定向测试通过。
  • npm --prefix api run build:通过。
  • npm run build:通过,仅有既有 Vite chunk size warning。

剩余边界

  • 当前告警仍是站内聚合提醒,尚未接短信、邮件、企业微信等外部告警通道。
  • 告警口径当前采用全局阈值环境变量,尚未按客户应用、消息类型或时间段细分。

2026-07-08 阶段 16:下游投递 Dashboard 第一版

本轮修复

  • 新增真实接口 /api/admin/operations/downstream-deliveries/dashboard,直接按 CmppDownstreamDelivery 聚合返回 summary/typeBreakdown/retryBuckets/topApplications
  • 运营端“下游投递记录”页面顶部补上真实 Dashboard 区域,展示投递总量、待投递、已投递、告警、类型分布、重试压力和应用告警排行。
  • Dashboard 筛选范围与页面应用/类型筛选保持一致,不允许由前端只根据当前页列表数据临时拼装。

验证状态

  • npm --prefix api test -- operations.service.spec.ts:通过。
  • npm --prefix api run build:通过。
  • npm run build:通过,仅有既有 Vite chunk size warning。
  • git diff --check:无空白错误,仅 Windows LF/CRLF 提示。

剩余边界

  • 当前 Dashboard 仍偏运营处置视角,尚未补时间趋势、按客户/账号维度的更细颗粒聚合。
  • 应用告警排行当前以 pending + failed 为主排序,尚未加入更复杂的权重和 SLA 指标。

2026-07-08 阶段 17:下游在线账号 Presence 持久化底座

本轮修复

  • Gateway inbound 新增 Redis presence store,客户 cmppAccount 在 bind 成功、submit 建链和下游回执/上行投递时,会把在线账号状态写入 Redis。
  • presence 数据至少包含 account/srcId/remoteIp/gatewayInstanceId/state/connectedAt/updatedAt,并按 TTL 自动过期,避免该状态只存在单进程内存中。
  • Gateway 发送失败触发连接清理时,会同步移除该账号的 Redis presence 记录。
  • 该阶段先完成“在线状态外部化”,尚未宣称“Gateway 重启后 pending 投递自动恢复”已完成;恢复逻辑在后续阶段继续补。

验证状态

  • go test ./internal/inbound/...:通过。
  • go test ./cmd/gateway/...:通过。

剩余边界

  • 当前 presence 主要服务于后续恢复能力,Gateway 还未在启动时主动根据 Redis presence 扫描并恢复 pending 投递。
  • 连接断开当前主要依赖发送失败清理和 TTL 过期兜底,尚未建立更完整的显式断线回收机制。

2026-07-08 阶段 18Gateway 恢复候选视图

本轮修复

  • Gateway 启动时会读取 Redis presence,并输出恢复候选账号加载日志。
  • 新增控制面接口 GET /downstream/recovery-candidates,返回 Redis presence 与当前内存在线账号合并后的恢复候选视图。
  • 候选视图当前用于后续恢复逻辑和运维排查,不直接触发 pending 下游投递补发。

验证状态

  • go test ./internal/inbound/...:通过。
  • go test ./internal/control/...:通过。
  • go test ./cmd/gateway/...:通过。

剩余边界

  • 当前只是“识别谁值得恢复”,还没有执行“把这些账号的 pending 回执/上行自动继续补投”。
  • 候选视图默认按 Redis TTL 和最近活跃时间保留,尚未叠加更复杂的健康判定和跨实例去重策略。

2026-07-08 阶段 19Gateway pending 恢复执行第一版

本轮修复

  • Gateway 启动时会立即按恢复候选账号执行一次 pending 下游投递恢复扫描。
  • 后续每轮补投周期除扫描当前内存在线账号外,也会继续扫描恢复候选账号,尝试恢复 CmppDownstreamDelivery.pending
  • 当前恢复策略是“能投就投,投不了继续 pending”:若账号尚无可用下游连接,Gateway 不会把记录误标成失败,而是等待客户重连后的后续恢复机会。

验证状态

  • go test ./internal/inbound/...:通过。
  • go test ./internal/control/...:通过。
  • go test ./cmd/gateway/...:通过。

剩余边界

  • 当前恢复仍按固定扫描周期触发,尚未做更细的按账号退避、恢复批次追踪和恢复告警。
  • 仍未覆盖更复杂的长短信分片恢复、跨实例抢占协调和恢复中的重复投递防抖。

2026-07-08 阶段 20Gateway 恢复退避、锁与状态审计

本轮修复

  • Gateway 新增账号级恢复锁,避免同一 cmppAccount 被并发重复恢复。
  • 恢复失败、等待连接和部分成功场景会写入真实恢复状态,并按指数退避计算下一次可恢复时间,减少无意义高频重试。
  • 控制面新增 GET /downstream/recovery-statuses,可查看账号最近恢复状态、尝试次数、下一次重试时间和错误原因。

验证状态

  • go test ./internal/inbound/...:通过。
  • go test ./internal/control/...:通过。
  • go test ./cmd/gateway/...:通过。

剩余边界

  • 当前恢复状态审计仍停留在 Gateway 控制面和 Redis,尚未同步到运营端页面或 NestJS 持久化审计表。
  • 恢复退避当前按账号统一处理,尚未细分到回执/上行类型、失败类别或跨实例抢占优先级。

2026-07-08 阶段 21Gateway 恢复总览与链路缺口收口

本轮修复

  • 控制面新增 GET /downstream/recovery-overview,一次性返回恢复候选账号和恢复状态,便于生产联调与排查。
  • 需求文档已按当前真实代码重新梳理 CMPP 端到端链路剩余缺口,明确区分“已能验收的真实链路能力”和“尚未产品化完成的恢复审计/指标/复杂补偿能力”。
  • 系统测试用例新增恢复总览接口口径,便于后续生产验证直接对照。

验证状态

  • go test ./internal/control/...:通过。
  • go test ./internal/inbound/...:通过(延续前一阶段验证结果,本轮未改动 inbound 核心分支逻辑)。
  • go test ./cmd/gateway/...:通过。

阶段 21 后剩余真实缺口

  • 恢复状态仍未写回 NestJS/Prisma/PostgreSQL,运营端暂无真实恢复状态页面。
  • 多 Gateway 实例下更强的恢复抢占协调、分片级补偿审计、共享接入号上行人工认领仍未完成。
  • 连接级窗口利用率、恢复吞吐、恢复失败分布等运营指标仍未进入真实后台页面。

2026-07-08 阶段 22:恢复状态回流 NestJS 与运营端展示

本轮修复

  • NestJS 新增真实恢复状态接收接口 /api/gateway/events/downstream/recovery-status
  • Prisma/PostgreSQL 新增 GatewayDownstreamRecoveryStatus 表,按 cmppAccount 持久化恢复状态、尝试次数、下一次恢复时间、错误原因及应用/企业关联。
  • 运营端新增独立“恢复状态管理”页面,支持真实恢复状态列表、分页、详情接口和当前筛选结果 CSV 导出。
  • 原“下游投递记录”页面仅保留投递记录与重投能力,不再混放恢复状态列表。
  • 恢复状态新增 failureCategory 失败分类字段,Gateway 回传、NestJS 兜底归类并落库,运营端支持分类筛选、分布统计、详情展示和导出。
  • 多 Gateway 恢复抢占协调补强:恢复锁升级为 Redis token 租约,恢复完成时通过 Lua 原子校验 token 后才写状态和释放锁;迟到旧实例不能误删新实例锁。
  • GatewayDownstreamRecoveryStatus 新增 lockOwner/lockExpiresAtGateway 回传并由 NestJS 入库,运营端恢复状态列表和详情可查看锁持有实例。
  • 本地启动脚本补充 .local-tools\minio.exe 查找路径,并已验证本机 MinIO 可通过 npm run start:local:minio 启动。

验证状态

  • npm --prefix api run prisma:generate:通过。
  • npm --prefix api test -- operations.service.spec.ts send-chain.service.spec.ts:通过。
  • npm --prefix api run build:通过。
  • go test ./internal/inbound/... ./internal/control/... ./cmd/gateway/...:通过。
  • npm run build:通过,仅有既有 Vite chunk size warning。
  • npm --prefix api run prisma:migrate:deploy:通过,已应用 20260708213000_add_recovery_lock_observability
  • npm run start:local:minio:通过,MinIO API http://localhost:9000、Console http://localhost:9001 已监听。

阶段 22 后剩余真实缺口

  • 恢复状态已回流 NestJS,并已具备独立运营页、详情、导出和第一版失败分类分布;后续仍缺少恢复吞吐、耗时趋势、连续失败账号等更细指标。
  • 多 Gateway 账号级恢复抢占协调已具备 token 租约和完成校验;分片级补偿审计、共享接入号上行人工认领仍未完成。
  • 连接级窗口利用率、连接级心跳、恢复吞吐和恢复耗时等运营指标仍未进入真实后台页面。

2026-07-08 阶段 23:长短信分片级补偿审计

本轮修复

  • Prisma/PostgreSQL 新增 SmsMessageSegmentAudit,按短信记录、submitId、分片序号保存真实分片提交、回执和补偿归因。
  • Go Gateway 上游提交结果 SubmitResult 增加 segments[],逐片回传 segmentTotal/segmentIndex/sequenceId/gatewayMessageId/submitStatus/submittedAt,长短信不再只暴露首个分片结果。
  • NestJS handleSubmitResult 写入分片提交审计,handleReceipt 按上游 gatewayMessageId 回填分片回执状态;重投或补偿产生的新 submitId 与历史 submitId 可并存追踪。
  • 运营端短信记录详情新增“分片补偿审计”列表,从真实 API 查询 SmsMessageSegmentAudit,展示分片、submitId、通道、Sequence、MsgId、提交状态、回执状态、补偿类型和错误信息。
  • 契约文档和示例补充 SubmitResult.segments[],系统测试用例新增 TC-GW-026 长短信分片补偿审计

验证状态

  • npm --prefix api run prisma:generate:通过。
  • go test ./internal/upstream/... ./internal/queue/... ./internal/submitworker/...:通过。
  • npm --prefix api test -- send-chain.service.spec.ts operations.service.spec.ts:通过。
  • npm --prefix api run build:通过。
  • npm run build:通过,仅有既有 Vite chunk size warning。

阶段 23 后剩余真实缺口

  • 长短信分片级提交、回执和补偿归因已具备真实审计;后续仍需补按单个分片自动重投、分片级人工重投和更细的补偿指标。
  • 共享接入号、多候选普通上行的人工认领流程仍未完成。
  • 连接级窗口利用率、连接级心跳、恢复吞吐、恢复耗时趋势和连续失败账号等运营指标仍未进入真实后台页面。

2026-07-08 阶段 24:共享接入号上行人工认领

本轮修复

  • Prisma/PostgreSQL 新增 SmsUplinkMatchCandidate,用于保存普通上行 ambiguous 场景下的候选企业、应用、下发短信、候选来源、置信度、认领状态和认领时间。
  • NestJS 上行匹配逻辑增强:接入号匹配多个应用、或手机号时间窗口匹配多条下发时,不误推客户;上行记录标记 ambiguous,并真实写入候选表。
  • 运营端“短信上行记录”详情新增候选认领区,展示候选企业、候选应用、候选来源、置信度、候选下发短信和候选原因,支持“认领并推送”。
  • 新增 POST /admin/operations/uplink-messages/:id/claim:认领后更新 SmsUplinkMessagematched,选中候选置为 claimed,其他候选置为 rejected,写入操作日志,并创建真实 CmppDownstreamDelivery(deliveryType=uplink) 走客户侧下游投递链路。
  • 系统测试用例新增 TC-GW-027 共享接入号上行人工认领

验证状态

  • npm --prefix api run prisma:generate:通过。
  • npm --prefix api run prisma:migrate:deploy:通过,已应用 20260708233000_add_uplink_match_candidates
  • npm --prefix api test -- send-chain.service.spec.ts operations.service.spec.ts:通过,40 个测试。
  • npm --prefix api run build:通过。
  • npm run build:通过,仅有既有 Vite chunk size warning。

当前剩余真实缺口

  • 共享接入号上行已具备候选记录、人工认领和认领后下游投递第一版;后续仍需补批量认领、认领复核和认领准确率/积压指标。
  • 长短信分片级提交、回执和补偿归因已具备真实审计;后续仍需补按单个分片自动重投、分片级人工重投和更细的补偿指标。
  • 连接级窗口利用率、连接级心跳、恢复吞吐、恢复耗时趋势和连续失败账号等运营指标仍未进入真实后台页面。

2026-07-03 阶段 9:运营端报备回执导入真实上传/解析

本轮修复

  • 运营端报备任务导入弹窗改为真实选择 CSV/TSV/TXT 文件。
  • 前端先调用 /api/admin/files/upload 保存文件对象,再提交 fileObjectId、文件名和文本内容到 /api/admin/report-tasks/{id}/receipt-import
  • 后端导入接口解析文本回执,识别 status/result/状态/结果 列,统计成功行、失败行,并保存行级解析结果。
  • 报备任务状态由后端按解析结果派生:全成功为 completed,有成功有失败为 partial,全失败或空文件为 failed
  • 未识别的运营商状态按失败处理,避免把未知回执误判为通过。

已执行命令

npm --prefix api test -- channels.service.spec.ts
npm --prefix api test
npm --prefix api run build
npm run build
git diff --check

当前结果

  • api/src/channels/channels.service.spec.ts 新增文本回执解析和任务状态派生覆盖。
  • API Jest12 个 test suite 通过,73 个测试通过。
  • API build 通过。
  • 前端 build 通过,仍存在既有 Vite chunk size warning。
  • git diff --check 无空白错误,仅 Windows 工作区 LF/CRLF 提示。
  • 本地服务已重启:http://localhost:3000/http://localhost:5173/ 均监听,/api/admin/report-tasks/admin/report-tasks HTTP smoke 返回 200。

2026-07-03 全菜单真实后端、上传和列宽回归

本轮修复

  • 客户端企业认证从纯前端状态机改为真实 GET/POST /api/client/enterprise-certification 驱动。
  • 客户端企业认证营业执照上传接入 /api/admin/files/upload,提交时保存 licenseFileObjectId 等材料字段。
  • 运营端企业表单“企业照片”从禁用占位按钮改为真实上传,保存时写入 photoFileObjectId
  • 客户端账号设置、运营端系统配置无真实保存接口,已移除路由并删除纯前端页面。
  • 彩信待开发菜单路由统一指向占位页,不再进入静态 mock 演示页面。
  • 客户端短信发送详情、批量任务表格中明显偏窄的中文字段列已加宽。

已执行命令

npm --prefix api test
npm --prefix api run build
npm run build
npm run spike:contracts
npm run test:gateway
$env:API_BASE_URL='http://127.0.0.1:3000/api'; node tools/smoke/real-env-smoke.mjs
npm run verify:phase8
git diff --check

当前结果

  • API Jest12 个 test suite 通过,73 个测试通过。
  • API build 通过。
  • 前端 build 通过,仍存在既有 Vite chunk size warning。
  • Gateway 队列契约通过,4 个示例均验证通过。
  • npm run test:gateway 通过。
  • 真实 API smoke 通过,覆盖真实 PostgreSQL/Redis/MinIO/API 主链路和文件上传对象写入。
  • 浏览器抽检通过:客户端真实登录后,企业认证页面无“纯前端原型”文案,资料页出现真实上传入口;彩信待开发入口显示占位页而非静态表单。
  • npm run verify:phase8 仍未通过,失败点仍是已知 BullMQ spike 性能阈值:15000 条消息、并发 500、end-to-end TPS 469.76,低于 500。

2026-07-03 企业列表列宽和新建应用交互回归

本轮修复

  • 通用 Table 组件增加 colgroup、列最小宽度和表格最小宽度计算,显式配置的业务列不再被容器强行压窄,超出区域横向滚动。
  • 企业管理列表加宽企业 ID、企业名称、企业编码、统一社会信用代码、联系人、联系电话、余额、短信余量、状态和操作列。
  • 企业模板管理列表加宽企业、应用、签名、模板内容、审核状态、更新时间和操作列,模板内容列保留两行展示。
  • 运营端短信任务进度、短信审核、短信记录、报备任务、用户、系统日志、安全控制、充值记录等列表中的状态/操作/数量等易挤压列统一加宽。
  • 新建企业应用入口弹窗改为先选择真实企业,再进入应用参数、客户单价、IP 白名单和三网通道组配置;未选择企业时“下一步”禁用。
  • 新建短信应用表单把移动、联通、电信通道组配置改为独立卡片区,显示已配置数量和无可用通道组提示;未填写应用名称或未选择任一运营商通道组时禁止保存。
  • 补齐基础弹窗居中、遮罩、最大宽度和正文滚动样式,避免 1280px 视口下弹窗偏移或被截断。

已执行命令和浏览器验证

npm run build
git diff --check
  • 前端 build 通过,仍存在既有 Vite chunk size warning。
  • git diff --check 无空白错误,仅 Windows 工作区 LF/CRLF 提示。
  • 窄列扫描仅剩短字段列:报备字段“必填”90px、运营看板排名72px、短信上行选择框72px。
  • 浏览器使用真实运营端登录 admin@example.com 抽检通过:
    • 企业管理表格最小宽度 1920px,统一社会信用代码列 220px,联系人列 160px,联系电话列 150px,横向滚动生效。
    • 企业模板管理表格最小宽度 1820px,模板内容列 420px,横向滚动生效。
    • 新建企业应用弹窗在 1280px 视口下未截断,未选择企业时“下一步”禁用。
    • 新建短信应用页显示三网通道组卡片、已配置数量和无可用通道组提示,初始状态“创建应用”禁用。

2026-07-06 文件上传预览和下载回归

本轮修复

  • 文件服务新增真实下载接口 GET /api/admin/files/:id/download,从 MinIO 或本地对象存储读取真实文件对象,支持 inline 预览和 attachment 下载。
  • 运营端企业照片、企业签名材料、引流材料、报备回执导入均在真实上传成功后显示下载入口;图片类型文件显示点击预览入口。
  • 客户端企业认证营业执照上传成功后显示下载入口,图片类型文件显示点击预览入口;提交认证时保存文件类型信息。
  • 客户端签名列表对已保存签名材料显示下载入口,图片材料按文件名或类型显示预览入口。
  • 客户端短信发送导入号码文件为前端解析文件,未生成后端文件对象;页面仅提供本地原始文件下载,不标记为真实后端归档。

已执行命令

npm --prefix api test -- files.service.spec.ts
npm --prefix api run build
npm run build
git diff --check

当前结果

  • 文件服务单测通过:1 个 test suite、2 个测试通过。
  • API build 通过。
  • 前端 build 通过,仍存在既有 Vite chunk size warning。
  • git diff --check 无空白错误,仅 Windows 工作区 LF/CRLF 提示。

2026-07-06 企业列表人工充值入口

本轮修复

  • 运营端企业管理列表新增“充值”按钮。
  • 点击“充值”打开企业人工充值弹窗,展示企业名称、当前余额,并支持录入充值金额、操作人和备注;充值金额允许负数冲正,0 金额不允许提交;企业列表入口不要求填写短信条数。
  • 提交后调用现有真实接口 POST /api/admin/billing/manual-recharges,成功后重新拉取企业管理列表,余额来自真实账户接口聚合结果。
  • 该入口不使用前端本地状态模拟充值入账;充值订单、账户余额、账户流水和操作日志仍由后端 BillingService.createManualRecharge 负责。

已执行命令

npm run build
git diff --check

当前结果

  • 前端 build 通过,仍存在既有 Vite chunk size warning。
  • git diff --check 无空白错误,仅 Windows 工作区 LF/CRLF 提示。

2026-07-07 手机号段 Tab 和通道组补发上限

本轮修复

  • 运营端手机号段库页面移除自定义卡片式 Tab,改用通用 Tabs 控件,与企业应用管理页面“短信应用/彩信应用”交互一致。
  • 通道组添加/编辑页面新增“补发时间上限(小时)”输入控件,编辑时回填 retryTimeLimitHours,保存时写入真实通道组接口。
  • 补发时间上限按后端现有校验限制为 1 到 72 小时。

已执行命令

npm run build
git diff --check

当前结果

  • 前端 build 通过,仍存在既有 Vite chunk size warning。
  • git diff --check 无空白错误,仅 Windows 工作区 LF/CRLF 提示。

2026-07-07 账单流水页面移除和列表分页

本轮修复

  • 删除客户端账单流水页面和运营端账单流水页面,移除对应路由、菜单、占位映射和首页跳转入口。
  • 移除公开交易查询/创建接口:GET/POST /api/admin/billing/transactionsGET /api/client/billing/transactions
  • 保留内部 AccountTransaction 写入能力,人工充值、扣费、释放、退款等真实计费动作仍可写入内部账务记录;本期不作为独立账单流水页面验收。
  • 通用 Table 组件新增内置分页,默认每页 10 条;服务端分页页面关闭内置分页,避免双分页。
  • 补齐手写列表和卡片列表分页:通道管理、通道组、充值记录、客户端应用、客户端充值套餐、客户端签名、客户端模板、客户端批量任务、客户端发送详情、运营端短信任务进度、运营端企业签名。

已执行命令

npm run build
npm --prefix api run build
npm --prefix api test -- billing.service.spec.ts --runInBand
git diff --check

当前结果

  • 前端 build 通过,仍存在既有 Vite chunk size warning。
  • API build 通过。
  • BillingService 单测通过:1 个 test suite、6 个测试通过。
  • git diff --check 无空白错误,仅 Windows 工作区 LF/CRLF 提示。

2026-07-07 通道组表格和分钟级补发上限

本轮修复

  • 通道组添加/编辑页的省网分流、全国通道配置从卡片改为通用表格展示,行内保留编辑、删除操作。
  • 通道状态文案改为设计锚点口径“链接正常/通道停用”;“链接正常”必须来自真实 CMPP 连接状态 connected 且当前连接数大于 0,新建但未连接的 active 通道不再显示为链接正常。
  • 通道组补发时间上限从整小时升级为分钟级配置,页面交互为“小时 + 分钟”,默认 12 小时 0 分钟;后端新增 retryTimeLimitMinutes 持久化字段,并保留 retryTimeLimitHours 兼容旧调用。
  • 发送链路按分钟级上限判断是否继续补发,超过配置分钟数、超过 72 小时或关闭补发时均不再补发。

已执行命令

npm --prefix api run prisma:generate
npm --prefix api test -- channels.service.spec.ts send-chain.service.spec.ts --runInBand
npm --prefix api run build
npm run build
git diff --check

当前结果

  • Prisma Client 已根据新 schema 生成。
  • ChannelsService 和 SendChainService 定向单测通过:2 个 test suites、35 个测试通过。
  • API build 通过。
  • 前端 build 通过,仍存在既有 Vite chunk size warning。
  • git diff --check 无空白错误,仅 Windows 工作区 LF/CRLF 提示。

2026-07-10 手机号段库大数据分页

本轮修复

  • GET /api/admin/dictionaries/phone-segments 从固定返回前 200 条改为按唯一 prefix 游标分页,支持服务端按号段、运营商、省份和城市搜索。
  • API 每页多读取 1 条计算 hasMore/nextCursor,不执行 50 万级号段表的 COUNT(*)
  • 运营端手机号段页面使用真实服务端分页,移除号段总数卡片、Tab 数字和分页总数,只显示当前页码及上一页/下一页。
  • 生产手机号段数据已从 dannyhu926/phone_location 2026 年 4 月数据导入;源数据 516470 条,过滤 253 条非 7 位异常记录,最终有效 7 位号段 516217 条。

验证口径

  • API 定向单测覆盖游标、搜索、每页多取 1 条和不查询总数。
  • 前端 build 和 API build 必须通过。
  • 生产验证应覆盖首尾翻页、关键词搜索、API/Gateway/PostgreSQL 健康状态和典型号段归属地查询。

已执行命令与结果

npm --prefix api test -- --runTestsByPath src/dictionaries/dictionaries.service.spec.ts
npm --prefix api run build
npm run build
git diff --check
  • DictionariesService 定向单测通过:1 个 test suite、3 个测试通过。
  • API build 和前端 build 通过;前端仍有既有 chunk size warning。
  • 生产 API 实测 pageSize=2:第一页返回 1300000/1300001nextCursor=1300001,下一页返回 1300002/1300003,响应无 total 字段。
  • 生产 API 搜索 1882120 返回“中国移动/上海/上海”;搜索“上海”首屏响应约 80ms。
  • 生产 cmpp-apicmpp-gateway、PostgreSQL、Nginx 均为 activeAPI health 正常。
  • 隔离部署后曾因 dist/assets 被保留为 700 root:root 导致 Nginx 无权读取 JS/CSS、admin 页面空白;线上已修正为目录 755、文件 644,正式生产部署脚本同步固化权限。
  • 正式部署发现已有生产管理员且未配置 PROD_ADMIN_PASSWORD 时,upsert.create 仍会对空密码执行哈希;已拆分 create/update 密码变量,已有账号不改密码,新建账号才生成临时密码。

2026-07-10 Batch 0 飞书瑕疵台账与分批策略

来源:飞书《短信平台第一版瑕疵》。本表仅记录问题路由和验收边界;除 Batch 1 外,其他项目仍须先在预发布环境只读复现并核对真实代码、API、PostgreSQL、Redis、MinIO 或 Gateway 状态,不能根据页面现象直接修改。

飞书项 初步分类 真实链路/风险 计划批次 当前状态
1.1-1.5 企业-充值流程 UI + API/DB 对象存储预览、人工充值、充值订单、账户流水 Batch 1 已完成并部署;历史余额取 AccountTransaction 快照
2.1 通道密码展示/修改 UI + API/DB + 安全 密码密文、权限、审计、上游连接配置 Batch 2 已完成:密码不回显,留空不覆盖,填写新值才更新
2.2 扩展位数和通道流速 UI + API/DB + Gateway 通道配置持久化、Gateway submit 限速 Batch 2 已完成:真实持久化并下发 Gateway SubmitCommand
2.3 通道组名称为空提示 UI 校验 服务端字段校验与前端错误提示一致 Batch 2 已验证:既有前端提示会在真实 API 调用前中断保存
2.4 发送记录详情弹窗 UI + API 详情、回执、提交记录必须来自真实接口 Batch 2 已完成:真实状态、提交和回执信息分层展示
2.5 连接日志优化 UI + API + Gateway 连接状态回写、操作日志、分页筛选 Batch 2 已完成:展示真实连接状态摘要并支持日志关键词筛选
2.6 通道测试 API/DB + Gateway/CMPP 测试 submit、Redis Stream、上游响应、审计 Batch 2 已完成:提交结果展示真实测试流水和提交记录
2.7 短信记录页面 UI + API/DB + Gateway 短信、submit、回执、分片审计真实查询 Batch 2 已完成:筛选下推 PostgreSQL,详情/审计为真实接口
3.1 报备配置无返回 UI 导航 返回后筛选/表单状态不丢失 Batch 3 已完成:返回通道列表
3.2 通道组添加通道弹窗 UI + API 通道组成员真实保存和回填 Batch 3 已完成:真实候选、状态展示、重复项限制和错误提示
4.1 创建用户 UI + API/DB 用户、角色、企业关联、审计 Batch 4 已完成:真实表单校验、提交状态和错误提示
4.2 禁用/删除/改密后踢下线 API/DB + 会话 Token/session 失效、跨浏览器验证、审计 Batch 4 已完成:数据库会话版本使旧 token 失效
4.3 禁用按钮颜色 UI 仅样式,保持通用危险操作语义 Batch 4 已完成:使用 warning 语义色
4.4 个人改密缺失 UI + API/会话 当前用户校验、密码更新、旧会话失效 Batch 4 已完成:右上角真实当前密码校验与改密
5.1 待审核任务数不准 API/DB 聚合 审核状态口径与任务明细一致 Batch 5 已完成:风险审核改按 SmsSendTask.pending_review 统计
5.2 任务进度 UI + API/DB + Gateway 状态机、发送/回执计数、分页 Batch 5 已完成:未知/超时不重复累计,已处理数不超过总号码数
5.3 企业应用 UI + API/DB 短信应用真实 CRUD/审核;彩信仅占位 Batch 5 已完成:停用使用 warning 色,启用使用 success 色,搜索区宽度协调
5.4 企业模板 UI + API/DB 模板材料、审核状态、真实筛选 Batch 5 已完成:审核状态以中文展示,draft 显示为草稿
5.5 企业签名 UI + API/DB + MinIO 资质文件、签名审核、对象存储预览 Batch 5 已完成:左边框按三网真实报备结果展示,编辑页不允许手工改报备状态
5.6 引流信息 UI + API/DB 字典字段、签名/模板关联、审核口径 Batch 5 已完成:列表改为引流信息、长链接不跳转且省略展示、操作列可见,编辑页不允许手工改报备状态
6.1 手机号段库 Tab UI 使用通用 Tabs,不改变真实号段数据路径 Batch 6 已完成:Tab 按内容宽度展示
6.2 运营商区分规则分页 UI + API/DB 服务端分页、筛选与总数口径 Batch 6 已完成:PostgreSQL 分页、总数、25 条每页
7.1 敏感词页 UI + API/DB 敏感词 CRUD、生效范围、发送校验 Batch 6 已完成:状态 Tag 清晰展示,添加弹窗扩展,保留真实 CRUD
8.1 系统日志 IP 为空 API/DB + Nginx 转发头、请求上下文、OperationLog 落库、历史数据边界 Batch 6 已完成:真实 HTTP 操作日志记录 Nginx 转发的客户端 IP;后台任务保持空值
8.2 客户端标题 UI 客户端产品名称与运营端区分 Batch 6 已完成:短信平台客户端
8.3 通用输入框/文本框样式 UI 去除内层填充色,保留边框和焦点状态 回归复查 已完成:含 Chromium 自动填充背景
8.4 精确时间格式 UI 所有精确时间统一 YYYY-MM-DD HH:mm:ss Batch 6 已完成:统一 helper 覆盖日志、用户、充值、任务与配置展示
8.5 中文图片文件名乱码 API/DB + MinIO + UI multipart 编码、对象存储文件名、历史展示兼容 回归复查 已完成:新上传正确入库,历史展示兼容解码
8.6 全局分页控件 UI + API/DB 总页数、首页/末页、指定页跳转与服务端分页口径 Batch 6 已完成:统一控件支持首页、末页、页码跳转;真实服务端分页页传入总页数
9.1 客户端菜单顺序 UI 签名与引流信息菜单位于模板管理之前 Batch 6 已完成

执行约束

  • 每个 Batch 先只读复现并记录页面、API、DB、Gateway 分类,再做最小真实修复。
  • 纯 UI 项也必须确认页面数据源不是 mock、localStorage 或静态数组;未实现后端的彩信仅保留待开发占位。
  • 每批结束执行相关 API 测试、API build、前端 build;涉及 Gateway 时追加 Go 测试和生产 Gateway health/CMPP 验证。
  • 完成后更新本文件;未经明确要求不提交或推送代码。

2026-07-10 Batch 1 企业充值流程瑕疵

本轮修复

  • 企业新建/编辑页的图片“预览”改为站内弹窗展示,不再跳转或新开页面;下载仍走真实对象存储文件接口。
  • 通用 InputSelectTextarea 根据 required 属性显示必填标识;企业资料和人工充值弹窗不再依赖页面散落的文案约定。
  • 运营端充值记录列表的“充值后余额”改为真实订单关联 AccountTransaction.balanceAfter;不再用当前 TenantAccount 余额冒充历史快照。没有可追溯流水的历史记录显示 -
  • 人工充值弹窗补齐非零校验、提交中禁用和 API 失败提示;提交仍调用 POST /api/admin/billing/manual-recharges,成功后刷新真实记录。
  • 企业名称与统一社会信用代码已经使用同一双列栅格,本轮复现未见对齐问题,不做无效样式改动。

验证口径

  • GET /api/admin/billing/manual-recharges 必须基于 Prisma/PostgreSQL 的 RechargeOrder 和关联 AccountTransaction 返回余额快照。
  • TC-BILLING-006 增加断言:充值记录“充值后余额”等于关联账务流水的 balanceAfter,与后续充值或消费后的当前余额无关。

已执行命令与结果

npm --prefix api test
npm --prefix api run build
npm run build
git diff --check
  • API 全量单测通过:12 个 test suites、113 个测试通过;新增 BillingService 覆盖两笔人工充值分别返回其历史余额。
  • API build 和前端 build 通过;前端仍有既有 Vite chunk size warning。
  • git diff --check 无空白错误,仅 Windows 工作区 LF/CRLF 提示。
  • 已按正式发布标准脚本部署到预发布服务器 8.160.169.106Prisma migration deploy 无待执行迁移,cmpp-apicmpp-gateway、Nginx、MinIO 均为 activeAPI/Gateway health、Redis 均通过。
  • 生产管理员真实登录后只读调用 GET /api/admin/billing/manual-recharges 成功返回 2 条记录,响应包含真实 balanceAfterCents10000、1000)。

2026-07-10 Batch 2 通道配置真实链路

本轮修复

  • 运营端通道编辑/新建页的“通道流速”不再固定提交 100;输入值按 1-2000 TPS 校验后写入 SmsChannel.rateLimitPerSecond,发送链路和通道测试继续从该真实字段生成 Gateway SubmitCommand.route.rateLimitPerSecond
  • “扩展位数”仅允许 0/2/4/6,持久化到 SmsChannel.config.extensionDigits;编辑页回填该值,普通发送和通道测试均将其放入 Gateway SubmitCommand.cmpp.extensionDigits
  • NestJS 更新通道时修正 config 合并行为:传入的配置会与既有 JSON 配置合并,不会再被 desiredConnections/windowSize 规范化过程静默丢弃。
  • 网关密码保持安全策略:编辑时不回显已配置密码,留空不覆盖;输入新密码才更新真实通道配置。

已执行命令与结果

npm --prefix api test -- channels.service.spec.ts --runInBand
npm --prefix api run build
npm run build
go test ./internal/queue ./internal/upstream
git diff --check
  • ChannelsService 和 SendChainService 定向测试通过:2 个 test suites、55 个测试通过ChannelsService 单独测试 23 项,覆盖流速、扩展位数持久化和非法配置拒绝。
  • API build、前端 build、Gateway queue/upstream 测试通过;前端仍有既有 Vite chunk size warning。
  • 已重新部署预发布环境;Prisma migration deploy 无待执行迁移,cmpp-apicmpp-gateway、Nginx、MinIO 均为 activeAPI/Gateway health 正常。生产运行源码已确认包含流速校验、扩展位数持久化及 Gateway 队列字段。
  • 通道组名称为空时已有前端提示“请输入通道组名称”,保存会在调用真实创建/更新 API 前中断;本轮复核后不重复改动。
  • 通道编辑密码保持掩码且不回显:编辑时明确提示“留空保持不变,填写新密码才更新”;新建通道仍要求填写密码。
  • 上述密码交互调整已于 2026-07-10 生产验证部署后再次核验:cmpp-apicmpp-gateway、Nginx、MinIO 均为 active,内外部 health/HTTP 检查通过。
  • 短信记录列表修复:企业、应用、手机号、状态之外的提交日期、短信内容、通道名称筛选改为传给 GET /api/admin/operations/messagesNestJS 通过 Prisma/PostgreSQL 执行内容、关联通道名和上海自然日范围查询,页面不再仅筛选已加载的前 500 条记录。
  • 生产只读复现确认:短信记录 9 条均有真实 SmsSubmitRecord,其中 4 条已有真实 SmsReceiptRecord3 个通道均有 CmppConnectionStateOperationLog 连接日志。按一条生产记录的日期、内容、通道关键词组合查询,9 条中仅返回 1 条且条件均匹配。
  • OperationsService 定向测试 12 项、API build、前端 build 均通过;已部署生产验证,cmpp-apicmpp-gateway、Nginx、MinIO 均为 activeAPI/Gateway health 正常。
  • 发送详情弹窗重组为真实状态摘要、短信内容、通道提交/回执轨迹、状态信息和分片补偿审计;提交轨迹新增真实 submitStatus,不再只展示时间和回执码。
  • 连接日志弹窗新增 CmppConnectionState 摘要(连接 ID、状态、当前/期望连接数、最近心跳、最近错误),日志内容以真实 OperationLog.detail 可读格式呈现,并仅对已返回日志做关键词筛选。
  • 通道测试成功后展示 API 返回的真实 testNo、提交数量、手机号与 SmsSubmitRecord.submitId,禁用重复提交,并提供跳转至短信记录入口;没有虚构“发送成功”或模拟回执。

2026-07-10 Batch 3 通道报备与通道组配置

  • 通道报备配置页新增返回通道列表入口,沿用现有 /admin/channels/:channelId/reports 路由的来源页面,避免运营人员进入配置页后没有回退路径。
  • 通道组“添加通道”弹窗不再使用固定省份数组:省份和候选通道均来自 GET /api/admin/channels,按真实运营商、地区和已绑定通道过滤;选中后展示通道代码、地区和真实连接状态。
  • 弹窗在省份、优先级或通道未选择时提供表单错误提示;没有符合条件的候选时显示可读空态。前端仅做交互约束,最终仍由 NestJS ChannelsService 校验运营商/地区兼容性、重复通道和优先级规则,并持久化到 SmsChannelGroupItem
  • 已执行 npm --prefix api test -- channels.service.spec.ts --runInBand23 项通过)、npm run buildgit diff --check;前端保留既有 Vite chunk size warning。
  • 已部署生产验证:Prisma migration deploy 无待执行迁移,cmpp-apicmpp-gateway、Nginx、MinIO 均为 activeAPI/Gateway health 正常;生产只读接口返回 3 个真实通道(其中 2 个启用)、1 个真实通道组和 2 个组成员。

2026-07-10 Batch 4 用户管理与会话失效

  • User.sessionVersion 真实持久化到 PostgreSQL;登录 token 携带该版本。浏览器携带 token 请求时,NestJS 会话中间件校验用户状态、删除状态和版本;禁用、删除、管理员改密和个人改密都会递增版本,使原会话在下一次请求被 401 拒绝,前端清理本地会话并跳回对应登录页。
  • 为避免破坏 Gateway 与现有服务间无浏览器会话链路,中间件仅校验带 Authorization 的浏览器 token;未携带该 header 的既有内部请求保持原行为。
  • 右上角“修改密码”补齐真实 POST /api/auth/password:要求当前密码、新密码(至少 6 位)和确认密码一致;成功后当前会话立即失效并回到登录页,写入操作日志。
  • 运营端和客户端用户新建补齐姓名、至少一个联系方式、初始密码/企业关联等前端校验,提交中禁用按钮并展示 API 错误;用户禁用操作改用通用 warning 语义色。
  • 已执行 npm --prefix api run prisma:generatenpm --prefix api test -- auth.service.spec.ts session-validation.middleware.spec.ts users.service.spec.ts --runInBand3 suites、8 项通过)、npm --prefix api run buildnpm run buildgit diff --check;前端保留既有 Vite chunk size warning。
  • 已部署生产验证:第 25 条 Prisma migration 20260710153000_add_user_session_version 成功应用;cmpp-apicmpp-gateway、Nginx、MinIO 均为 activeAPI/Gateway health 正常。生产管理员新登录 token 为版本格式且可读取真实用户列表;伪造旧版本 token 被 401 拒绝,验证会话版本失效生效。

2026-07-10 Batch 5 审核与企业配置

  • 修复 Dashboard 待审核聚合:短信审核的真实状态存储在 SmsSendTask.status=pending_review,原逻辑错误统计 SmsBatchTask.auditStatus=pending。聚合现统一模板、签名、企业认证和风险审核的真实待审状态。
  • 生产 PostgreSQL 与对应 API 在部署后均显示四类待审为 0,Dashboard 也为 0,当前数据口径一致;无非零待审样本,未将该 0 值当作非零场景的充分验收。
  • 任务进度、企业应用、企业模板、企业签名与引流字段页面均使用真实 NestJS API;生产只读接口成功返回任务、应用、模板、签名和引流字段数据,不存在 mock/localStorage 回退。
  • 已根据下载的瑕疵文档修复 5.2-5.6:任务进度不重复累计未知/超时,企业应用启停语义色与搜索区,模板中文审核状态,签名三网状态驱动边框且移除人工状态选择,引流信息标题、链接展示、操作列和人工状态选择。
  • 已执行 npm --prefix api test -- operations.service.spec.ts --runInBand(12 项通过)、前端 build 和 git diff --check;已部署生产验证,cmpp-apicmpp-gateway、Nginx、MinIO 均为 activeAPI/Gateway health 正常。

2026-07-10 瑕疵回归复查

  • 逐图复查下载的《短信平台第一版瑕疵》后,确认中文图片文件名乱码仍真实存在:生产 FileObject.fileName 中可见 UTF-8 被按 Latin-1 解释后的值。上传链路现先恢复 multipart 文件名编码;历史记录由前端展示层兼容解码,避免签名材料和企业认证页继续显示乱码。
  • 通用输入框、文本框去除内部填充色;同时覆盖 Chromium 自动填充产生的蓝色内层背景。企业认证页此前额外写死的灰色输入背景已移除。
  • 2026-07-11 回归发现此前金额展示验收不充分:充值记录和多处金额页面仍混用整数、两位或四位小数。现统一金额展示为人民币元三位小数,并新增输入框聚焦底色与文本选中高亮;需求和 TC-BILLING-006 已同步。
  • 已执行 FilesService 定向单测(3 项通过)、API build、前端 build 和 git diff --check;生产部署后四个服务均为 activeAPI/Gateway health 正常。通过真实 POST /api/admin/files/upload 上传 营业执照-编码回归.png,响应和 FileObject 持久化文件名均为正常中文。
  • Batch 6 的 6.1、6.2、7.1、8.1 仍为待修,不得因之前的前端构建通过而标记完成;其余 8.x 与客户端菜单顺序将继续按原始文档逐项复核。

2026-07-11 文档瑕疵二次闭环

  • 基于本地《短信平台第一版瑕疵.docx》重新逐项复查,撤销“代码已改即已验收”的旧口径;本轮必须以源码、真实 NestJS API 返回、测试和生产页面复核共同作为完成条件。
  • 通道扩展位数改为真实 API 与页面共同约束 0-20 的整数;流速仍由 NestJS 约束为 1-2000 TPS 并继续下发 Gateway。
  • Dashboard API 新增四类真实待审明细:企业认证、短信审核、模板、签名;运营首页和右上角通知分别展示并跳转到各自真实审核入口。
  • 手机号段接口从 cursor-only 响应升级为带 total/page/pageSize 的 PostgreSQL 分页,页面获得总页数、首页、末页和跳转能力;短信记录与通用 Table 同步补齐完整分页控制。
  • 统一修复充值记录不展示操作人、客户端标题、引流详情名称、用户初始密码显示/隐藏与随机生成、时间秒级格式、输入框无填充焦点状态,以及发送页真实应用单价三位小数显示。
  • 已执行:channels.service.spec.ts24 项通过)、dictionaries.service.spec.ts4 项通过)、operations.service.spec.ts12 项通过)、API build、前端 build 与 git diff --check 均通过;前端仍仅有既有 chunk size warning。
  • 已部署生产验证:cmpp-apicmpp-gateway、Nginx、MinIO 均为 activeAPI/Gateway health 均通过。真实认证 API 返回四类待审明细并与总数一致;手机号段第 2 页返回 25 条、总数 516217、page=2/pageSize=25,证明页面分页不再依赖 cursor 猜测总页数。
  • 浏览器自动化在登录页连接阶段超时,未使用 CAPTCHA 绕过或修改生产数据;登录后页面视觉验收需在下一轮以人工登录或可用浏览器会话补充截图。其余项目以源码、真实 API 和构建结果验收,不能将该未完成的视觉截图记录成已完成。

2026-07-11 运营端查询控件与手机号段库重做

  • 企业应用、企业签名、企业模板管理页的查询与重置统一为通用 Button 操作组:查询提交当前条件到真实 NestJS 列表 API,重置清空条件后重新加载真实列表,不再依赖输入即筛选或状态更新竞态。
  • 系统管理的用户管理、手机号段库、报备字段库、系统日志均增加查询和重置;用户与报备字段使用已加载真实数据的显式筛选,系统日志使用已提交筛选条件请求真实日志 API。
  • 手机号段库重做为概览、关键词筛选、号段/运营商规则双视图和统一分页工作台。号段和规则均使用 PostgreSQL 返回的 total/page/pageSize,不使用静态数组或 cursor 猜测总页数。
  • 已执行前端 npm run buildgit diff --check;已部署生产验证,cmpp-apicmpp-gateway、Nginx、MinIO 均为 activeAPI/Gateway health 通过。生产源码和已构建静态资源均包含新的查询操作组与手机号段工作台样式;手机号段 API 继续返回真实 total/page/pageSize

2026-07-11 CMPP 业务失败回执闭环

  • 修复下游 CMPP 入站的审计缺口:客户已完成 bind、账号可识别且手机号参数合法后,NestJS 会先创建真实 SmsBatchTaskSmsApiRequestSmsMessageRecord,再执行模板、签名/报备、风控和余额校验;不再因模板未报备等业务失败而直接丢弃客户 Submit。
  • 协议、鉴权、源 IP 和手机号参数错误仍由 Gateway/NestJS 返回非零 SubmitResp,且不创建短信记录。其余业务失败返回成功 SubmitResp 与平台 Msg_Id,并创建真实 SmsReceiptRecord(rawStatus=REJECTD)CmppDownstreamDelivery,客户通过 Deliver Receipt 获得 undelivered 结果。
  • 同一回执策略覆盖最终通道签名报备失败、无可用路由,以及上游 Submit rejected/timeout 在补发耗尽后的终态失败;失败记录、错误码和错误原因均可在运营端真实短信记录链路查询。
  • Gateway 在客户 Submit 成功并建立 messageId-连接映射后立即冲刷该账号 pending 下游投递,避免 API 先创建失败回执时只能等待周期补投。
  • 已执行 npm --prefix api test -- --runInBand send-chain.service.spec.ts34 项通过)、npm --prefix api run buildgo test ./...(Gateway 全量通过)。待本轮全量 API/前端构建及生产验证完成后补充最终部署结果。

2026-07-11 企业应用下游 CMPP 连接状态修复

  • 修复企业应用列表误用上游 CmppConnectionState 的问题。新增 PostgreSQL CmppDownstreamConnection,一条记录对应一个已鉴权的客户 CMPP TCP bind 会话,按应用保存账号、企业代码、客户端 IP、协议版本、建立时间、最近心跳、最近 Submit、最近 Deliver、断开时间和错误原因。
  • Gateway 在客户 bind 成功、ACTIVE_TEST、Submit 和下游 Deliver 写入成功/失败时通过真实 NestJS API 回写连接事件;运营端只以该表的 connected 会话统计当前连接数,不再把上游通道连接数显示为企业客户连接数。
  • API 列表/详情查询会将最近心跳超过 CMPP_DOWNSTREAM_HEARTBEAT_TIMEOUT_MS(默认 90 秒)的会话标记为 heartbeat_timeout;运营端展示真实客户端 IP、企业代码与最近心跳。移除了不能真正关闭 TCP 连接的运营端“删除连接”伪操作。
  • 已执行 sms-config.service.spec.ts(17 项通过)、API 全量测试(13 suites、121 项)、Gateway 全量 go test ./...、API build 和前端 build;前端仅有既有 chunk size warning。
  • 已部署生产验证:第 26 条 Prisma migration 20260711193000_add_cmpp_downstream_connections 已成功应用,CmppDownstreamConnection 表存在。cmpp-apicmpp-gateway、Nginx、MinIO 均为 active12026/17890/8090 监听及 API/Gateway health 均通过。部署时没有保持在线的客户 bind 会话,故新表初始为 0 条;下一次真实 CMPP bind 将作为生产数据验收样本写入该表。

2026-07-11 短信号码运营商与省份持久化

  • 确认发送链路在进入应用通道组路由后,会先按真实 PhoneCarrierRule 正则识别号码运营商,再按 PhoneSegment 号段库识别省份。本轮不扩展地市字段。
  • SmsMessageRecord 新增 carrier/province,路由阶段完成号码识别后立即持久化;即使后续缺少通道组或无在线通道而失败,短信记录仍保留识别结果。选中通道时与 channelId/submitId 再次同步写入;Prisma migration 使用真实号段库和生效运营商规则回填已有短信记录。
  • 运营端短信记录列表、发送详情和 CSV 导出展示记录上的号码省份/运营商,不再以通道发送地区或通道本体 carrier 冒充号码归属。
  • 短信任务进度详情中的“号码运营商分布”和“号码省份分布”均直接聚合任务内真实短信记录的 carrier/province
  • 已执行 npm --prefix api test -- --runInBand send-chain.service.spec.ts35 项通过)、npm --prefix api run buildnpm run buildgit diff --check;前端仅有既有 chunk size warning。
  • 已将 7b8424d9 部署生产,migration 20260711210000_add_message_route_identity 成功应用。cmpp-apicmpp-gateway、Nginx、MinIO 均为 active12026/17890/8090/3000 监听、API/Gateway health 及外部 12026 HTTP 均通过。生产 11 条已有短信已全部回填运营商和省份:移动 9 条、电信 1 条、联通 1 条,省份均为上海。

2026-07-12 全页面固定条数截断与总数口径整改

  • 生产核查确认企业管理只返回前 100 条,但 PostgreSQL 实际有 106 个企业(未删除 105 个);企业应用只返回前 100 条,实际有 204 条。页面将截断后的数组长度展示为“企业总数/共找到”,属于真实数据口径 Bug。
  • 已系统审计页面主列表 API,移除会把前 100/200/500 条直接作为页面全量的固定截断。覆盖企业、企业应用、企业认证、用户/角色/权限、签名、模板、通道/通道组/路由规则、报备字段/材料/任务/记录、账务、文件、审计、风控、敏感词/黑名单/引流字段、短信任务/记录/提交/回执/上行等真实列表。
  • 企业应用的“今日发送/到达率”不再每应用加载最多 1000 条 SmsMessageRecord 后用数组长度计算,改为 PostgreSQL 按 applicationId/statusgroupBy 全量聚合。
  • 短信任务进度不再为每个任务最多加载 100000 条短信后统计,改为 PostgreSQL 按 batchTaskId/carrier/province/status 聚合总数、成功数和计费条数,任务运营商/省份分布不再受 10 万条截断影响。
  • 保留的固定条数均属于明确的近期日志/监控窗口、超时扫描单批、导出保护、单消息重试尝试或唯一候选判定,这些响应不被页面展示为业务总数。
  • 已执行 API 全量测试(13 suites、122 项通过),及受影响服务定向测试(5 suites、91 项通过)、API build、前端 build 与 git diff --check;前端仅有既有 chunk size warning。
  • 已将 390b9700 部署生产,部署前完成 PostgreSQL 和当前发布源码备份,Prisma 确认 27 条 migration 均已应用。cmpp-apicmpp-gateway、Nginx、MinIO 均为 active12026/17890/8090/3000 监听、API/Gateway health 和外部 12026 HTTP 均通过。使用生产平台管理员会话调用真实受保护 API:企业管理返回 105 条未删除企业,企业应用返回 204 条,不再封顶 100。

2026-07-12 客户批量任务与 CMPP 内部批次隔离

  • 短信任务进度的产品口径回归为“客户在客户端提交的批量发送任务”。运营端和客户端任务列表统一强制 SmsBatchTask.sourceType=client,不再展示每条 CMPP Submit 创建的 sourceType=cmpp 内部批次或通道测试批次。
  • CMPP 内部批次仍保留在 PostgreSQL,继续承载模板/签名/报备校验、风控、冻结/计费、队列、补发和 Deliver Receipt 关联;所有 CMPP 号码仍进入短信记录。
  • 客户端任务详情、任务短信明细和取消接口同时校验当前 tenantIdsourceType=client,不能通过内部批次 ID 读取或操作 CMPP 内部任务。
  • 生产现状只读核对:sourceType=cmpp 2 个、sourceType=admin_channel_test 1 个、sourceType=client 0 个。部署后任务进度应显示 0 个客户批量任务,但不删除现有内部批次数据。
  • 已执行 send-chain.service.spec.ts + operations.service.spec.ts2 suites、50 项通过)、API 全量测试(13 suites、125 项通过)、API build 和前端 build;前端仅有既有 chunk size warning。已随 8b6ec92f 部署生产,受保护任务进度 API 返回 0 个客户批量任务,未将现有 2 个 CMPP 内部批次和 1 个通道测试批次误展示。

2026-07-12 CMPP 模板不匹配短窗口聚合审核

  • 只有企业应用配置 templateMismatchMode=manual_review 时,CMPP 模板不匹配短信才进入人工审核。reject 继续逐条失败并下发 REJECTD;其他模式不被聚合逻辑接管。
  • 新增 SmsSendTask.sourceType/aggregationKey/contentHash/windowStartedAt/windowEndsAt,以应用、CMPP 账号、规范化内容 SHA-256 和默认 10 秒窗口生成唯一聚合键。SmsMessageRecord.reviewTaskId/signatureId 保留每条成员与审核任务、真实签名的关联。
  • 聚合前仍校验签名审核/报备、风控直接拒绝和账户余额,并按每条短信独立冻结。审核通过后逐条恢复到各自 sourceType=cmpp 内部批次并入队;驳回后逐条释放冻结、写入失败记录并生成客户侧 Deliver Receipt。
  • 运营端短信审核页新增“审核来源”和“聚合号码数”,区分 CMPP 模板不匹配聚合与普通风控审核。
  • 聚合窗口关闭前,任务不返回到待审列表且审核接口拒绝提前操作,避免窗口内后到短信加入已完成任务。
  • Prisma migration20260712113000_add_cmpp_review_aggregation。已执行 API 全量测试(13 suites、129 项通过)、API build、前端 build、Prisma validate 和 git diff --check
  • 已将 8b6ec92f 部署生产,部署前完成 PostgreSQL 和发布源码备份,migration 已成功应用。SmsSendTask 5 个聚合字段、SmsMessageRecord.reviewTaskId/signatureId 均已存在;生产应用中 manual_review 3 个、reject 201 个。审核 API 返回 200,当前无待审样本,未为验收人工注入短信或修改业务数据。cmpp-apicmpp-gateway、Nginx、MinIO 均为 active12026/17890/8090/3000 监听、API/Gateway health 和外部 12026 HTTP 均通过。

2026-07-12 报备字段库到企业签名/引流资料完整链路

  • ChannelReportField 通过 drainageFieldId 真实关联报备字段库,并增加 reportType=signature/drainage/both;通道报备配置页改为选择字段库字段和报备用途,不再在通道内手工复制字段编码、名称和类型。
  • 新增企业应用报备字段解析 API,按生效的应用路由规则遍历通道组及组内通道,以字段库 ID 求合集;同字段任一通道必填即整体必填,并返回全部来源通道。
  • 企业签名与引流信息弹窗根据所选企业应用动态加载字段合集。签名只展示签名/共用字段,引流项只展示引流/共用字段;文件字段继续走真实 MinIO/对象存储上传,文本值和文件对象 ID 均提交 NestJS API。
  • API 在写签名前执行必填校验,防止绕过前端;保存后同步写入各目标通道的 SignatureReportMaterial 和新增的 DrainageReportMaterial,删除引流项时同步清理旧材料。
  • 为避免运营人员面对动态资料时无法理解来源,签名和引流编辑页增加“通道组数/通道数/字段数/必填数”摘要、字段级来源说明和“为什么需要这些资料”解释弹窗;弹窗按企业应用、通道组、通道逐级展示字段用途及必填口径。每次保存同时在签名 JSON 中固化 reportRequirementSnapshot,记录当时的字段与来源通道,供配置变化后的历史追溯。
  • Prisma migration20260712150000_link_report_field_library。已执行 Prisma generate/validate、channels.service.spec.ts + sms-config.service.spec.ts2 suites、44 项通过)、API build 和前端 build;前端仅有既有 chunk size warning。
  • 已提交并 push 87ae4a20,随后以该提交生成发布快照并部署生产;部署前备份 PostgreSQL 和运行源码,migration 20260712150000_link_report_field_library 已成功应用。生产 .deployed-commit=87ae4a20cmpp-apicmpp-gateway、Nginx、MinIO 均为 active12026/17890/8090/3000 监听,API/Gateway health 和外部 HTTP 均通过。
  • 生产数据库已确认 ChannelReportField.drainageFieldId/reportTypeDrainageReportMaterial 存在。当前生产 DrainageField=0ChannelReportField=0,因此不会凭空展示动态资料区;需要先按真实业务配置创建字段库和通道字段后再做页面来源弹窗的有数据验收。
  • 浏览器可打开生产登录路由并识别页面标题“CMPP 短信平台”,但读取 DOM/控制台时浏览器连接连续超时,未将解释弹窗点击交互标记为已通过;待生产产生真实字段配置后补测。
  • 2026-07-12 追加:报备字段库字段类型收窄为字符串、图片、文件三种;前端筛选和新增弹窗移除整数、网址、电话、日期,API 严格拒绝三种之外的类型。migration 20260712170000_normalize_report_field_types 将历史其他类型及其通道字段副本统一归并为字符串。
  • 2026-07-12 追加:按设计基线 131f344a^ 恢复“通道列表 → 报备详情”页面结构,不再把报备详情错误简化为字段配置表。页面按当前通道查询真实 ChannelSignatureReportTask/ChannelSignatureReportRecord/SmsSignature.drainageInfo,展示签名任务、报备状态和时间,签名下引流信息默认收起并可展开;查看详情使用真实企业、应用和动态资料。发送统计没有数据库事实时明确显示“暂无统计”,不复用基线演示百分比。签名报备字段和引流信息字段配置保留为页面顶部两个入口,均从真实报备字段库选择。
  • 本地验证:通道/字典定向测试 2 suites、31 项通过,API 全量 13 suites、134 项通过,API build、前端 build、git diff --check 通过。浏览器确认本地构建可加载且无框架错误覆盖,但本地未启动真实 API,认证验证码请求返回 502 并停留登录页,因此未把目标报备页面的登录后视觉交互标记为通过;没有绕过认证或注入 mock 数据。
  • 2026-07-12 追加:报备状态改为通道任务唯一事实来源。新增统一批量状态变更 API,企业签名按应用当前通道组展示具体通道矩阵,通道详情修改当前任务,报备任务页人工修正任务;三个入口统一更新/创建 ChannelSignatureReportTask、写 ChannelSignatureReportRecord,并重算三网汇总和 SmsSignature.reportStatus。回执导入不再直接覆盖全局状态,同样调用汇总算法;新增但无任务的目标通道按未报备计入汇总分母。
  • 已执行相关定向测试 2 suites、46 项及 API 全量测试 13 suites、135 项,API build、前端 build、git diff --check 均通过;前端仅有既有 Vite chunk size warning。
  • 已提交并 push eab05958 后部署生产,部署前完成 PostgreSQL 与运行源码备份;migration 20260712170000_normalize_report_field_types 成功应用。生产 .deployed-commit=eab05958cmpp-apicmpp-gateway、Nginx、MinIO 均为 active12026/17890/8090/3000 监听,API/Gateway health 和外部 HTTP 200。新统一状态接口对空 items 返回预期 400,证明路由已注册。生产当前 DrainageField/ChannelReportField/ChannelSignatureReportTask/ChannelSignatureReportRecord 均为 0,未为验收注入虚假字段、任务或人工状态;运营人员可从企业签名通道矩阵对真实目标通道首次设置状态并创建任务。

2026-07-13 部分通道报备通过的发送路由

  • 修复发送链路先以 SmsSignature.reportStatus=approved 一票否决、导致部分通道通过仍无法发送的问题。全局状态改为运营汇总展示;签名审核仍必须通过。
  • 首次发送和失败补发均在路由阶段解析真实签名,只保留对应 ChannelSignatureReportTask.status=approved 的候选通道,再结合运营商、省份、优先级、通道状态和实时连接选择通道。主通道未报备而备用通道已报备时允许走备用通道;没有已报备通过且在线的候选通道时明确失败。
  • Gateway 提交前继续保留最终通道报备任务二次校验,覆盖路由完成后任务状态发生变化的竞态。
  • 已执行 send-chain.service.spec.ts 40 项通过,覆盖全局 reporting 可发、主通道未通过而备用通道通过时选备用,以及所有候选均未通过时拒绝;API build 和前端 build 通过。
  • 已提交并 push ade06058 后部署生产;部署前完成 PostgreSQL 与 eab05958 运行源码备份,无待执行 migration。生产 .deployed-commit=ade06058cmpp-apicmpp-gateway、Nginx、MinIO 均为 active12026/17890/8090/3000 监听,API/Gateway health 与外部 HTTP 200。生产源码已确认包含 approved 通道候选过滤;【安徽航天信息】当前仍为全局 reporting、一个通道 approved、一个通道 pending,未主动发送计费短信,交由用户使用真实业务流量验证只走 approved 通道。

2026-07-13 企业签名审核与通道报备状态展示分离

  • 生产核查【安徽航天信息】确认状态保存成功:两个 carrier=all 通道分别为 approved、reporting,三网真实汇总均为 reporting 且 1/2 通过;Bug 在于前端将 reporting 转换成旧 pending,再显示成“审核中”,并丢失通过数/总数。
  • 企业签名列表和报备详情改为直接使用 API carrierReportSummary.status/approved/total:展示未报备、报备中、部分通过(x/y)、全部通过(x/y)、资料待补充、报备失败和不适用;签名 auditStatus 另列显示草稿、待审核、已通过、已驳回。详情同时列出每个目标通道的真实状态,不再读取 drainageInfo.carrierStatus 冒充当前汇总。
  • 按用户授权,本次将工作区其他会话的字段代码校验、Select 搜索、应用列表及样式等改动一并测试和发布;API 全量 13 suites、137 项通过,API build、前端 build、git diff --check 通过。
  • 已将完整工作区提交 344b2afe 部署生产,部署前完成 PostgreSQL 与 ade06058 运行源码备份,无待执行 migration。生产 .deployed-commit=344b2afe,四项服务 active12026/17890/8090/3000 监听,API/Gateway health 与外部 HTTP 200;发布产物已确认包含“部分通过(x/y)”“全部通过(x/y)”“签名审核”。生产【安徽航天信息】仍为 auditStatus=draft、reportStatus=reporting、1/2 通道 approved,刷新后应展示签名审核“草稿”和三网“部分通过(1/2)”。

2026-07-13 企业页面可用性与报备展示修正

  • 企业短信模板卡片改为自适应列宽,卡片和操作区允许换行,避免中等视口下固定三列造成水平滚动。
  • 企业应用管理列表隐藏 AppID 列;共用 Select 对标签中包含“企业”或“应用”的下拉自动提供名称搜索,选项仍来自各页已接入的真实 API。
  • 报备字段代码在前端和 NestJS API 双层限制为 A-Z/a-z/0-9;API 会拒绝下划线、中文、空白等非法代码,防止绕过页面写入 PostgreSQL。
  • 运营端浏览器标题更新为“聆界短信管理平台”。通道报备详情和签名详情弹窗在展示前剔除数据中已存在的外层中/英文括号,统一只渲染一层中括号。
  • 本地验证:API 全量 13 suites、137 项通过,API build、前端 build 和 git diff --check 通过;前端仅有既有 chunk size warning。应用内浏览器确认本地运营端登录路由、非空 DOM、无框架错误覆盖,且标题为“聆界短信管理平台”;因本地未启动真实 API,验证码请求返回 502,无法进入登录后页面完成模板响应式、下拉搜索和签名实数据的视觉点击验收,未注入 mock 或绕过认证。截图阶段应用内浏览器页面挂载超时,未将截图标记为通过。

2026-07-13 运营端企业模板与企业签名布局优化

  • 确认上一次自适应修正落在客户端 /client/templates,而运营端 /admin/enterprise-templates 仍使用累计最小宽度约 1820px 的表格,操作列必须水平滚动才能看到。
  • 企业模板管理改为响应式列表行:将模板名称/审核状态、企业/应用/签名归属、两行内容摘要/变量数、更新时间和操作分区展示。在 1180px 以下重排为三列,860px 以下变为单列,预览/编辑/删除始终保留在当前视口。分页仍基于真实 API 结果,每页 10 条。
  • 企业签名管理将三网报备标签与 approved/total 数量拆开,容器可换行但文字和数量各自保持完整;报备详情/报备状态/编辑/删除固定为两列两行。同时修正签名摘要网格少一列导致“引流信息”和操作区被挤到下一行的布局问题。
  • 本地验证:API 全量 13 suites、137 项通过,API build、前端 build、git diff --check 通过;前端仅有既有 chunk size warning。Chrome 当前无已登录生产标签,部署前未绕过图形验证码或注入 mock 数据。
  • 已将功能提交 19d47b45 push 到 origin/main 并部署生产。部署前备份 PostgreSQL 为 /opt/cmpp-platform/backups/cmpp-20260713-103205.sql(约 61MB),备份运行源码为 /opt/cmpp-platform/backups/source-20260713-103205.tar.gz(约 63MB);发布快照本地/服务器 SHA-256 一致。生产无待执行 migration,.deployed-commit=19d47b45cmpp-apicmpp-gateway、Nginx、MinIO 均为 active12026/17890/8090/3000 监听,API/Gateway health 和外部 HTTP 200。生产 index.html 已引用新资源 index-HtuLnrXL.js/index-C5Tf8YiT.css,源码已确认包含企业模板响应式行和签名操作区两列布局。
  • 生产浏览器确认路由可加载、标题为“聆界短信管理平台”、DOM 非空、无 console error/warn 和框架错误覆盖。由于浏览器没有已登录运营端会话,访问受保护页面按预期落到登录界面;未经用户确认不代解图形验证码,因此登录后真实数据截图和点击交互留待用户刷新生产页面验收。

2026-07-13 签名审核与引流信息通道报备闭环

  • 生产只读核查确认:运营端新建的【安徽航天信息】仍为 auditStatus=draft;引流资料保存在 SmsSignature.drainageInfo.links,动态字段可写 DrainageReportMaterial,但缺少引流项维度的真实通道报备任务和记录。
  • /admin/signatures 从占位页替换为真实签名审核页,支持状态查询、资质/动态资料详情、通过和带原因驳回,调用现有 NestJS 审核 API 并写 AuditRecord。运营端新建签名直接写 auditStatus=approved,同时写 admin_create_approved 审核记录;客户端提交审核流不变。
  • ChannelSignatureReportTask 增加 reportType=signature/drainagedrainageItemId。保存引流资料时,根据企业应用的真实路由通道及其 drainage/both 字段自动生成 pending 任务和 create 记录;删除引流项时同步清理对应材料和任务。
  • 企业签名引流列表、通道报备详情、报备任务页均按引流项和通道读取/修改同一任务,共享报备记录、导出和回执链路。企业签名三网状态改为引流任务真实汇总,不再使用 drainageInfo.links.mobile/unicom/telecom 静态值。
  • 短信发送选路和最终通道二次校验明确增加 reportType=signature,引流通过任务不会误放行未报备签名。Prisma migrations20260713153000_add_drainage_report_tasks20260713154000_backfill_drainage_report_tasks20260713155000_unique_report_task_scope;后两者分别回填已有引流材料的 pending 任务/记录,并保证同一报备对象和通道仅一个任务。
  • 本地真实 PostgreSQL 已成功应用 3 条新 migrationAPI 全量 13 suites、139 项通过,Gateway 全量 Go 测试、Prisma validate、API build、前端 build 和 git diff --check 通过,前端仅有既有 chunk size warning。应用内浏览器确认本地运营端登录路由标题正确、DOM 非空、无框架错误覆盖且 console 无 error/warn;真实图形验证码阻止进入受保护页,未代解验证码、未绕过认证、未注入 mock。
  • 功能提交 551b99cb 已 push 并部署生产。部署前 PostgreSQL 备份为 /opt/cmpp-platform/backups/cmpp-20260713-174148.sql,运行源码备份为 /opt/cmpp-platform/deploy-backups/full-19d47b45-20260713-174148;三条 migration 成功应用。生产 .deployed-commit=551b99cb,四项服务 active12026/17890/8090/3000 监听,API/Gateway health 和外部 HTTP 200;前端产物已包含“短信签名审核”“按通道修改引流信息报备状态”“签名与引流信息报备任务”。生产现有 4 条任务均已回填为 reportType=signatureDrainageReportMaterial=0,因此没有伪造引流任务,待真实引流字段资料保存时自动生成。
  • 部署后交付复核发现历史运营端新建的 draft 签名虽可在审核页筛选,但操作按钮只对 pending 开放。已改为 draft/pending 都可由运营直接通过或驳回,用于处理【安徽航天信息】等存量草稿;新增签名仍按新规则自动通过。修正提交 ff3e5607 已部署,二次备份时间戳 20260713-174512;生产 .deployed-commit=ff3e5607,四项服务、端口、API/Gateway health 和外部 HTTP 200 再次验证通过,部署后 API stderr 无新错误。

2026-07-13 引流信息独立审核与报备任务门禁

  • 生产只读核查确认当前 DrainageReportMaterial=0reportType=drainage 任务为 0、包含引流数组的签名为 0,因此本轮可安全引入规范化模型,不需要改写活跃引流业务数据。生产运行代码仍为 ff3e5607,本轮暂未部署。
  • 新增独立 PostgreSQL 实体 SmsDrainageInfo,客户端在已审核签名下新建或修改引流信息均进入 pending,并写 AuditRecord(targetType=sms_drainage_info);运营端新增/修改自动通过。运营端审核中心新增“引流信息审核”页,支持真实 API 查询、详情、通过和带原因驳回,首页和侧栏待审数量同步纳入引流信息。
  • 通道报备增加审核门禁:审核通过前不创建新任务或可导出材料;已通过引流信息再次修改时删除旧材料并将已有任务冻结为 waiting_review。审核通过后按应用当前生效路由及通道引流字段重建材料,创建或重置 ChannelSignatureReportTask(reportType=drainage),并写 audit_approved_create/reset 报备记录。
  • 企业端签名页面补充引流信息新建、修改、删除、动态字段和真实对象存储上传;运营端企业签名页改为调用独立引流 API,并显示引流审核状态。报备任务和报备记录页增加类型筛选,直接关联真实引流实体显示站点、地址和所属签名。
  • 本地真实 PostgreSQL 已成功应用 migration 20260713190000_add_drainage_audit_workflowPrisma validate/migrate status 通过。真实 NestJS API 验收使用现有已审核签名、应用路由和通道临时增加报备字段:客户端创建后为 pending 且任务数 0;运营审核通过后生成 1 条 drainage 任务和报备记录;客户端修改后任务冻结为 waiting_review;驳回原因可从 API 返回。验收数据、临时报备字段、材料、任务、审核及报备记录已在本地数据库清理,不污染业务样本。
  • API 全量测试 13 suites、141 项通过,API build、前端 build、git diff --check 通过;前端仅有既有 Vite chunk size warning。应用内浏览器确认本地构建标题、非空登录 DOM、无框架错误覆盖且 console 无 error/warn;访问 /admin/drainage-audits 按真实权限跳转登录页,因图形验证码未获授权代解,登录后的新增审核页点击和视觉验收未执行。该批改动纳入 2026-07-14 发布批次统一提交和部署。

2026-07-14 运营列表组合搜索与报备记录可追溯性

  • 企业模板管理将企业名称、企业应用、模板名称、模板内容拆成独立查询参数;企业签名管理拆分企业名称、企业应用、签名名称/用途和引流信息。引流信息查询命中后按签名父级分组,并只展开显示命中的站点、URL 或备注。
  • 企业应用管理新增应用名称和状态条件;企业黑名单搜索区重做为企业名称、企业应用、手机号码、入库原因、状态五个独立条件。上述条件均由 NestJS 接收并通过 Prisma AND 组合查询真实 PostgreSQL,不再拼接为单个模糊关键字。
  • ChannelSignatureReportRecord 新增 sourceEntry,企业签名、报备任务、通道报备详情三个入口分别持久化 enterprise_signature/report_task/channel_report。报备记录列表展示真实通道名称、签名或引流信息主体、完整主体内容、中文动作和状态变化,并将入口翻译为“企业签名修改 / 报备任务修改 / 通道信息修改”。
  • 历史 manual_status_change 记录无法从旧数据可靠反推出入口,迁移统一标记为 legacy,页面显示“历史记录(入口未记录)”,不得误标为系统自动处理或猜测入口。
  • 充值记录、短信记录表头统一左对齐;搜索区使用自适应网格,增加条件后不挤压操作按钮。
  • 本地真实 PostgreSQL 已应用 20260714100000_add_report_record_source_entry,并通过编译后的 NestJS 服务对现有应用、签名、模板执行真实组合查询。API 全量测试 13 suites、141 项通过;Prisma validate、API build、前端 build、Gateway 测试和 git diff --check 通过。应用内浏览器确认真实鉴权跳转、页面标题、非空 DOM、无框架错误覆盖及 console 无 error/warn;因图形验证码未获授权代解,登录后页面点击验收未执行。
  • 功能提交 64216712 与历史入口修正提交 70991478 均已 push,生产最终运行代码为 709914787196072b66d293ee9290d7cd41b46990。首次备份为 /opt/cmpp-platform/backups/cmpp-20260714-095958.sqlsource-20260714-095958.tar.gz,最终修正部署前备份为 /opt/cmpp-platform/backups/cmpp-20260714-100658.sqlsource-20260714-100658.tar.gz;发布包本地与服务器 SHA-256 一致。
  • 生产 36 条 migration 全部应用,四项服务 active,12026/17890/8090/3000 监听,API/Gateway health 和外部 HTTP 200,部署后 journal 无新 error。真实报备记录 API 返回 16 条且通道名称缺失数为 0;7 条系统记录为 system9 条旧人工记录为 legacy。用生产现有数据调用独立组合查询,企业应用、模板、签名和引流信息分组均各返回 1 个精确匹配结果;企业黑名单当前为 0 条,未注入演示数据。

2026-07-14 CMPP 入站完整括号签名与部分通道放行修复

  • 生产只读核查手机号 18821203795 的最近一次提交:Gateway 已接收入站,但 NestJS 在路由前以 SIGNATURE / 短信内容未识别到已审核且已报备的签名 拒绝,未生成通道提交记录。实际短信前缀和签名库名称均为完整的 【航天信息信诺网】;签名审核已通过、全局报备状态为 reporting,主通道任务 approved、备用通道任务 pending。
  • 根因是入站签名解析正则取捕获组后剥离了中括号,却用无括号名称查询保存完整括号的签名库;同时查询错误要求全局 SmsSignature.reportStatus=approved,与“部分通道通过即可发送、路由只选通过通道”的既定规则冲突。
  • 修复为从短信开头提取完整 【签名】 并原样查询,仅在入站候选阶段校验 auditStatus=approved。全局 reportStatus 不再作为入口门禁,具体通道的 ChannelSignatureReportTask(reportType=signature).status=approved 仍由路由和最终提交二次校验。
  • 新增真实故障形态回归用例:完整括号签名、审核通过、全局 reporting 时可进入模板不匹配人工审核聚合,并验证查询不再携带全局报备条件、不产生签名失败回执。定向 API 测试 1 suite、41 项通过;API 全量 13 suites、142 项通过,API build、前端 build、Gateway 全量 Go 测试和 git diff --check 通过,前端仅有既有 Vite chunk size warning。
  • 功能提交 f08a73e1 已 push 并部署生产。部署前 PostgreSQL 备份为 /opt/cmpp-platform/backups/cmpp-20260714-112012.sql(约 64MB),运行源码备份为 /opt/cmpp-platform/backups/source-20260714-112012.tar.gz(约 15MB);发布包本地与服务器 SHA-256 均为 38b3fa6282a06648dabc048fbebca7a6579a6a7ef1f8eee514ecf14fb9d69790
  • 生产 36 条 migration 无待执行项,.deployed-commit=f08a73e19129f5249a5a9e0035c7ab63b80422d4cmpp-apicmpp-gateway、Nginx、MinIO 均 active12026/17890/8090/3000 监听,API/Gateway health 和外部首页、运营端登录页 HTTP 200。线上源码确认按完整括号 match[0] 查询且不带全局 reportStatus 条件,部署后 API/Gateway 近期日志无 error。未擅自向客户号码重发短信;新提交将按应用现有模板不匹配人工审核策略进入真实审核与后续通道路由。

2026-07-14 服务端安全会话与自动锁定

  • 将可预测的 dev-token:userId:sessionVersion 和 localStorage 访问令牌替换为 256 位随机会话标识;浏览器只通过 HttpOnly、SameSite Cookie 携带,Redis 使用会话标识 SHA-256 键保存真实状态。生产模式 Cookie 默认 Secure;本次按用户要求部署到现有 HTTP 预发布环境时显式配置 SESSION_COOKIE_SECURE=false,正式生产切换 HTTPS 后必须恢复为 true

  • 运营端/客户端无操作阈值分别为 60/120 分钟,提前 5 分钟提醒;超时进入密码锁屏,4 小时内可用当前密码解锁并轮换会话标识,超过后完整登录。绝对会话时长 12 小时不可滑动续期;敏感操作最近密码认证窗口为 30 分钟。

  • NestJS 中间件对运营端和客户端受保护 API 强制要求 Redis 会话,逐次校验用户状态和 sessionVersionGateway 回调和 health 保持原内部链路,不被浏览器会话门禁拦截。自动轮询只有检测到近期真实浏览器操作时才携带活动标识,不能长期保活无人值守会话。

  • 用户/权限、企业状态、应用密钥、通道和路由、报备状态、手工充值/退款/调整已接后端最近认证 Guard。前端收到 RECENT_AUTHENTICATION_REQUIRED 后要求当前密码,成功后自动重试;普通 JSON、Blob 和文件上传统一处理会话 401。会话创建、锁定、解锁、再认证和退出写 OperationLog,多标签页同步状态。

  • API 自动化测试当前 15 suites、151 项通过;新增 Redis 会话空闲锁定、客户端独立阈值、4 小时恢复期限、解锁轮换旧标识失效、sessionVersion/角色权限变更撤销和敏感操作 Guard 用例。真实本地 PostgreSQL + Redis + NestJS 短阈值验收通过:登录响应无访问令牌且收到 Cookie、无 Cookie 访问返回 401/SESSION_INVALID、空闲后返回 401/SESSION_LOCKED、密码解锁后恢复查询、认证窗口过期后敏感操作返回 403/RECENT_AUTHENTICATION_REQUIRED、重新认证和登出成功;临时用户与会话已清理。该功能已随下游 ACK 批次提交并部署,生产 Redis PONG,携带无效 HttpOnly 会话 Cookie 访问真实会话接口返回预期 401/SESSION_INVALID

2026-07-14 下游 CMPP_DELIVER_RESP 精确确认与双重试开关

  • 生产只读排查 11:40 两条余额失败短信确认:NestJS 已生成 REJECTD 回执,Gateway 对同一 CMPP2.0 会话写出后分别收到 Sequence_Id 37/38 的 CMPP_DELIVER_RESP。原 CmppDownstreamDelivery.status=delivered 仅代表 SendPkt 成功,无法证明客户确认,属于观测口径缺陷。
  • Gateway 新增按连接和 Sequence_Id 跟踪投递,记录实际下发 Msg_Id;写出后回调 downstream/sent,收到 CMPP2.0/2.1/3.0 DELIVER_RESP 后校验 Sequence_Id、Msg_Id 和 Result,再回调 downstream/acknowledged。ACK 超时回调真实失败类型;重启后 NestJS 在客户恢复拉取 pending 时补偿处理过期 awaiting_ack
  • Prisma SmsApplication 新增回执、上行两个自动重试开关,默认开启;CmppDownstreamDelivery 保存策略快照、写出/确认/截止时间、ACK Result/Sequence_Id/Msg_Id 和连接 ID。关闭开关后首次投递仍保留,已写出未确认或被拒绝的对应类型不自动重发;手工重投保留并增加重复处理二次确认。
  • 运营端企业应用编辑页增加两个独立开关;下游投递页区分待首次投递、等待客户端确认、客户端已确认、未确认、拒绝和最终失败,Dashboard 和告警改为真实 ACK 口径。历史 7 条仅确认写出的记录迁移为 unconfirmed,不伪造 ACK。
  • 新增 API ACK 状态与关闭重试策略单测、Gateway 真实 CMPP 会话 ACK 回调/超时单测;同步更新需求和 TC-GW-ACK-001004。API 全量 15 suites、153 项通过,Gateway 全量 Go 测试、Prisma validate 与本地真实 PostgreSQL migration、API build、前端 build 和 git diff --check 通过;前端仅有既有 Vite chunk size warning。应用内浏览器确认本地构建标题、登录 DOM、无框架覆盖及 console 无 error/warn;因真实图形验证码未获授权代解,受保护页面内的两个开关点击验收未执行。
  • 功能提交 8c03663f 已 push 并部署生产。部署前 PostgreSQL 备份为 /opt/cmpp-platform/backups/cmpp-20260714-142059.sql(约 65MB),运行源码备份为 /opt/cmpp-platform/backups/source-20260714-142059.tar.gz(约 21MB);发布包本地和服务器 SHA-256 均为 3e969aaf00e828da4167018bc349795413743414bc827d452859f0fd45776cd1
  • 生产 migration 20260714130000_add_downstream_delivery_ack_tracking 成功应用,37 条 migration 全部齐全;历史 7 条 delivered 已按新口径迁移为 unconfirmed,204 个企业应用的回执和上行自动重试开关均为默认开启。生产 .deployed-commit=8c03663f245c12cd5e6aab28ad9eeb68ea60ed57cmpp-apicmpp-gateway、Nginx、MinIO 均 active12026/17890/8090/3000 监听,API/Gateway health、Redis、外部首页和运营端登录页均正常,部署后近期日志无新增 error;前端产物已确认包含“回执自动重试”和“客户端已确认”。未擅自发送或重投客户短信。
  • 生产验证站点当前为 HTTP,已按发布约束显式设置 SESSION_COOKIE_SECURE=false,ACK 超时设置为 30 秒;无 Cookie 和无效 Cookie 访问受保护/会话接口均返回预期 401。服务器凭据文件对存量管理员只记录 password=unchanged,不是可用明文密码,因此未继续进行真实登录和开关点击,且已清除本次诊断产生的一次失败计数;登录后的页面交互由用户使用现有账号验收。

2026-07-14 下游回执 Msg_Id=0 与 SubmitResp 时序修复

  • 生产核查 15:07、15:10 两条余额失败短信:CmppDownstreamDelivery 均记录 Result=0,但 ACK Msg_Id 都是 0Gateway 日志中的原 SubmitResp Msg_Id 分别为 96774149322108413259687782471788644609。这只能证明下游协议栈收到了 Deliver,不能证明下游平台已将状态回执关联到原短信,与下游页面仍显示“未回执”一致。
  • 根因为 NestJS 在处理入站 Submit 时同步生成失败回执,而 Gateway 尚未建立 messageId 映射;原查找逻辑在精确消息未命中时回退账号会话,使用 bind 会话的零值 Msg_Id 提前写出 Deliver。上午 11:40 的回执手工重投后才显示,是因为重投时对应 Submit 映射已经存在,能携带正确 Msg_Id。
  • 修复为:精确消息未登记时禁止回退账号会话;Gateway 仅在 ConnectResp/SubmitResp 成功写出后冲刷 pending;新建短信记录持久化原 CMPP Submit Sequence_Id,重启恢复时结合平台 MessageId 重建相同 Msg_Id;发送层拒绝任何 Msg_Id=0 的 DeliverNestJS 也不再把 Result=0/Msg_Id=0 标记为 delivered。
  • migration 20260714153000_fix_downstream_receipt_message_id 新增 SmsMessageRecord.cmppSubmitSequenceId,并把存量 deliveryType=receipt/status=delivered/ackMessageId=0 纠正为 unconfirmed,保留 ACK 证据但不冒充业务确认。
  • 下游投递记录列表改为固定信息分组:投递类型/时间、企业/应用、消息 ID、状态、重试、最后错误和操作各自保持可读宽度,最后错误不再被挤成竖排。delivered 记录开放单条和批量手工重投,继续保留重复业务处理二次确认;awaiting_ack 仍禁止并发重投。
  • 已新增 TC-GW-ACK-005 和 Gateway 回归:首个返回包必须是 SubmitResp,随后失败回执 Deliver Msg_Id 与 SubmitResp 完全相同;另覆盖精确映射不回退、持久化 Sequence_Id 恢复和 Msg_Id=0 拒绝。API 全量 15 suites、154 项、Gateway 全量 Go 测试、Prisma validate、真实本地 PostgreSQL migration、API build、前端 build 和 git diff --check 均通过;前端仅有既有 Vite chunk size warning。经用户授权在应用内浏览器完成一次本地图形验证码登录,使用真实 NestJS API、PostgreSQL 和临时投递记录在 1440×1000 视口验证列表无横向挤压、无 NaN、console 无 error/warndelivered 行的重投按钮可用且点击确实进入真实后端重投链路;因本地未运行 Gateway,请求按预期变为待重试而非伪造成功。临时投递记录和验收账号已清理。
  • 功能提交 1ce02ef2 已 push 并部署生产。部署前 PostgreSQL 备份为 /opt/cmpp-platform/backups/cmpp-20260714-163007.sql(约 65MB),运行源码备份为 /opt/cmpp-platform/backups/source-20260714-163007.tar.gz(约 21MB);发布包本地与服务器 SHA-256 均为 67a79f17bd2f61b5df3057ded500009d5d3ef95bf656728299f3ead0011a763a
  • 生产 migration 20260714153000_fix_downstream_receipt_message_id 成功应用,38 条 migration 全部完成;错误的 receipt/status=delivered/ackMessageId=0 已降为 0,共 9 条历史记录按真实口径纠正为 unconfirmed。生产 .deployed-commit=1ce02ef2066aa1ecd995b0a3b884304218adc008cmpp-apicmpp-gateway、Nginx、MinIO 均 active12026/17890/8090/3000 监听,API/Gateway health、Redis、PostgreSQL 和外部首页/运营入口 HTTP 200;部署后 journal 无 error,真实 CMPP2.0 账号 910887 已重新连接并持续心跳。未擅自发送或重投客户短信,后续真实新提交用于验证 SubmitResp 与 Deliver 的 Msg_Id 关联。

2026-07-15 报表导出、模板规则与通用 Select 优化

  • 运营端对账单、利润报表、发送质量报表增加真实服务端 CSV 导出,复用页面日期、企业、应用、通道和统计维度筛选,导出全部筛选结果且不受当前分页影响。
  • 报备字段库重做为统计概览、签名/引流信息通用配置双栏和自适应字段卡片;继续使用真实字段库及通用字段 API,保留引用锁定删除规则。
  • 运营端、客户端用户管理新增按钮统一调整为标准小尺寸。
  • 本地真实 NestJS API 与 PostgreSQL 登录验收发现并修复两处仅构建无法暴露的布局问题:运营端新增用户按钮曾被 Grid 拉伸至 731px,现为 98×32px;报备字段库在 800px 视口的筛选区曾出现内部横向滚动,现已切换单列且页面与工具栏 scrollWidth=clientWidth。1280px 桌面下三类报表均加载真实聚合数据并显示唯一“导出报表”入口,页面无横向溢出、无 console error/warn。
  • 将下拉裁剪修复收敛到项目通用 Select:所有下拉默认使用 document.body Portal 和 fixed 定位,最高展示 320px 选项,并随视口、页面滚动实时重定位,页面不再逐个配置专用下拉。应用内浏览器以企业签名真实本地数据验证企业搜索、企业选择及应用联动;831px 高视口下列表完整显示在弹窗上方层级,600px 高视口自动向上展开且 top >= 0bottom <= viewport,控制台无 error/warn。
  • 提交前整批验证:API 全量 18 suites、194 项通过,API build、前端 build、Gateway 全量 Go 测试、Prisma validate 和本地 47 条 migration status 均通过;通用 Select 另在利润报表普通筛选区确认 listbox 直接挂载于 BODY、使用 fixed 定位且完整处于视口内。前端仅保留既有 Vite chunk size warningJest 仍需 --forceExit 退出既有异步句柄。
  • 工作区完整改动已提交并 pusha7a4e8d9f6aba00b8137e5b70c59bdef67ed3b57feat: polish reporting templates and shared controls)。部署前确认本地 mainorigin/main 一致,并备份生产 PostgreSQL、运行源码和环境配置至 /opt/cmpp-platform/backups/releases/20260715-163418;三份备份均通过 SHA-256 复核和压缩包完整性检查,其中数据库备份 SHA-256 为 a59d3b7f4538f99cdc73a1092ac31628efa45bc38d4adf20a05d6a1f075ec5da,运行源码备份为 305c529fb94c71fd6e49f6228717b2ce93f14fff84a84e477d1f202f3192ef58
  • 发布快照本地与服务器 SHA-256 均为 489d6c969252403689dfdcca15b87e4f5a93b65187551fa6650451527366942e。生产 .deployed-commit=a7a4e8d9f6aba00b8137e5b70c59bdef67ed3b5747 条 migration 全部齐全;cmpp-apicmpp-gateway、MinIO、Nginx、PostgreSQL、Redis 均为 active12026/17890/8090/3000/9000 正常监听,API/Gateway health、Redis PONG、PostgreSQL readiness 和外部首页/运营端/API HTTP 均通过,部署后 API/Gateway 无 error 级日志。
  • 生产浏览器确认登录页加载成功且标题为“聆界短信管理平台”。服务器凭据文件对存量管理员仅记录 password=unchanged,不是可用明文密码,因此未擅自重置生产密码;通用 Select 的企业搜索、企业与应用联动、弹窗越界和普通筛选区 Portal 交互已在部署前通过本地真实 NestJS API、PostgreSQL 数据和生产同构建验证,未使用 mock、localStorage 或静态数组。

2026-07-15 签名与引流资料批量导入及统一通道报备(已提交、已部署)

  • 新增真实待报备资料工作台:WPS 表格另存 .xlsx 后由 NestJS + ExcelJS 解析多行表头、文本和内嵌图片,原文件及图片走 MinIO,导入批次、可复用映射方案、材料版本和待报备状态走 Prisma/PostgreSQL;导入只更新资料池,不自动生成通道任务。
  • 新增统一报备批次:运营勾选新建/修改的签名与引流信息后,按企业应用当前生效路由展开全部通道,每通道生成一份内嵌图片的 .xlsx,并关联批次材料版本快照、文件行号和真实通道报备任务。无路由、未配置通道字段或缺必填资料不会清除待报备标记。
  • 通道签名/引流字段配置按设计基线恢复为字段池和已选字段双栏,支持通道导出表头、顺序、必填、列宽、图片尺寸、缺省值和文本转换;导出严格使用各通道自己的映射名称与顺序。
  • Prisma migrations 20260715190000_add_report_material_import_export_workflow20260715193000_scope_channel_report_fields_by_type20260715194000_initialize_existing_report_material_pending 已在本地真实 PostgreSQL 成功应用,50 条 migration status 齐全;字段范围迁移将旧 both 配置拆成签名/引流两份,并允许同一标准字段在两类中使用不同表头和顺序;初始化迁移不把上线前所有历史签名误认成本次新建/修改资料。Prisma validate/generate、API 全量 19 suites/198 项、API build、前端 build、Gateway 全量 Go 测试、根目录与 API 生产依赖 audit、git diff --check 均通过;audit 为 0 漏洞,前端仅有既有 Vite chunk size warningJest 仍需 --forceExit 退出既有异步句柄。
  • 应用内浏览器使用本地真实 NestJS API/PostgreSQL 会话验证 /admin/report-materials:真实待报备签名加载成功,勾选后“统一生成通道报备”由禁用变为可用;导入弹窗展示企业/应用、映射方案、表头行和 XLSX 文件控件。进入真实通道报备详情后,签名字段配置弹窗按字段池/导出字段双栏渲染,页面和两次交互均无 console error/warn、无框架错误覆盖。未点击统一生成、未上传客户文件、未写入烟测业务数据。

2026-07-15 通道 TPS 配置口径清理(已提交、已部署)

  • 明确 SmsChannel.rateLimitPerSecond 是单个物理通道的 TPS 上限,不是平台总流速;Redis 限速键包含通道 ID,不同通道独立计数。
  • 同一物理通道即使被多个通道组引用,也共享通道自身的同一限速桶,不按通道组重复获得额度。
  • 删除未参与发送链路的 SmsChannelGroupItem.rateLimitPerSecond:Prisma 模型、通道组成员 DTO、真实 API 持久化和前端类型均已清理,并新增数据库迁移删除对应列;通道管理中的 SmsChannel.rateLimitPerSecond 和现有 NestJS Redis 限速链路保留。
  • 本地真实 PostgreSQL 已应用 20260715200000_drop_channel_group_item_rate_limitPrisma validate/generate/migrate status 通过;通道服务定向测试 29 项、API 全量 19 suites/198 项、API build、前端 build、Gateway go test ./... 均通过。Jest 仍存在测试完成后异步句柄不自动退出的既有提示,前端仍只有既有 chunk size warning。

2026-07-15 Gateway 提交异常处理与最终流速限制(待部署)

  • 运营端新增“Gateway提交异常”页面和真实 NestJS API:支持状态/应用/通道/关键字筛选、服务端汇总、脱敏详情及单条重新入队;浏览器响应不包含原始 payload、通道密码、密钥或鉴权字段,数据库和内部兼容接口暂保留 GatewaySubmitDeadLetter 技术命名。
  • 重新入队增加近期认证、人工原因、明确确认上游未受理、短信状态、通道状态/真实连接状态、最多 3 次以及 pending→requeueing 原子抢占校验;写入 Redis Stream 失败会恢复 pending,成功记录操作人、原因、Stream ID 和时间,后续 SubmitResult 自动闭环 resolved。
  • Go Gateway 新增 Redis 分布式单通道限速。连接命令保存权威通道 TPS,提交取权威值与消息值的较小者;同一通道在多实例和多个通道组间共享额度,不同通道独立。Stream 消息超速时保持未 ACK 并等待,不作为发送失败,重启后继续使用既有 pending 恢复机制;worker 对同批消息并发处理,避免低 TPS 通道等待阻塞其他通道。
  • 定向验证已通过:Gateway internal/ratelimitinternal/controlinternal/submitworkerAPI operations.service.spec.tssend-chain.service.spec.ts 共 73 项。最终本地门禁通过:Prisma validate/generate、51 条 migration status、API 19 suites/200 项、API build、前端 build、Gateway go test ./...git diff --check;前端仅有既有 chunk size warningJest 仍需 --forceExit 退出既有异步句柄。应用内浏览器确认受保护新路由真实跳转运营端登录、标题和 DOM 正常、console 无 error/warn;因真实图形验证码未获授权代解,未绕过认证或注入会话。
  • 首轮生产部署后发现 active 通道在数据库仍显示旧 connected,但新 Gateway 进程没有内存连接池且 Redis 权威 TPS key 为空。根因为发布脚本先重启 API、后重启 Gateway,并且 API 启动未重放 active 通道。已修复为先 Gateway 后 API,API 启动延迟 1 秒后从真实数据库重新下发全部 active 通道;复验结果随最终发布补录。
  • 功能提交 7091a8be 已 push 并完成首轮部署;部署前备份 PostgreSQL、运行源码和环境文件至 /opt/cmpp-platform/backups/releases/20260715-182455,三份备份均通过完整性与 SHA-256 检查。首轮发布包本地/服务器 SHA-256 均为 dc9fce751fce42bcf8ac14a4b9fd6a1d28a489469350904ee395db3ceb9dcab94 条 migration 成功应用,51 条齐全;首轮健康检查、端口、受保护异常 API 401 和静态资源均通过。由于随后发现并修复上述 Gateway 重启恢复缺口,最终运行提交和复验结果以修正发布记录为准。
  • 启动恢复修正提交 85ff0376 已 push 并完成最终运行时发布;发布前第二次备份至 /opt/cmpp-platform/backups/releases/20260715-183017,数据库、源码、环境文件 SHA-256 分别为 8d632d63db1afcad37889b445e3989819c15053d544f3a63239dca20cd0baecd5ffc421046f436d5f8ed8178c7a884c4e476567826740d469f4560360304744d87ab2efd509b39849b0ee22ead1b4cf0568fba4ab8525c59b5c78da51c73bc86;最终运行发布包本地/服务器 SHA-256 均为 930ac2a24bf6c1ee24cdfb2f90dff26d89bf7e1f9d84425aa800e66aa8ef4b9a
  • 生产 51 条 migration 全部齐全;cmpp-apicmpp-gateway、MinIO、Nginx、PostgreSQL 和 Redis 正常,12026/17890/8090/3000/9000 监听,API/Gateway health、Redis PONG、外部首页和运营入口均通过,受保护异常列表无会话返回 401Redis Stream consumer group pending=0、lag=0,部署后近期 API/Gateway 无 error 级日志。
  • 两个 active 上游通道在本次 Gateway/API 启动后均产生新的 cmpp_connection.connect_requestedcmpp_connection.connected 审计,currentConnections=1Redis 生成 rate:gateway:channel:config:<channelId> 两个独立 key,值均为各自真实配置 100,证明 Gateway 内存连接池与最终 TPS 上限已由当前进程恢复。生产前端资源包含“Gateway提交异常”;应用内浏览器访问新路由按真实鉴权跳转运营端登录,标题、DOM 正常且 console 无 error/warn,未绕过图形验证码。

2026-07-16 签名颜色、手机号段布局与跨入口登录失败隔离(已提交、已部署)

  • 企业签名卡片建立审核优先、报备汇总次优先的统一颜色规则:全部目标通道通过为绿色、部分通过为蓝色、待审核/报备中/资料待补充为橙色、审核或报备失败为红色、草稿/未报备/不适用为灰色。三网标签将“报备中”从蓝色改为橙色,与“部分通过”明确区分;总体色条增加可访问状态说明。
  • 手机号段库通用 Tab 移到页面标题下、搜索条件上;手机号段和运营商区分规则的统计卡分别放入各自 Tab,只展示当前类型的真实服务端总数。搜索、分页、新增和删除仍调用原 NestJS/Prisma API。
  • 修复同浏览器跨入口错误登录误踢已有会话:/admin/auth/login/client/auth/login 的 401 仅作为本次凭据失败返回,不再进入通用“现有会话失效”分支,不清理展示会话、不广播 logout、不跳转原入口。受保护 API 自身返回的 401 仍按 Redis 会话失效、锁定或撤销规则处理。
  • 本地 PostgreSQL、Redis、正式构建的 NestJS API 和 Vite 生产构建已启动;API 19 suites、200 项全部通过,API build、前端 TypeScript/Vite build 和 git diff --check 通过,前端仅有既有 chunk size warning。应用内浏览器确认本地真实 API 登录页、标题、DOM 和验证码请求正常;因未获本轮图形验证码代填授权,未绕过 HttpOnly Cookie 或 localStorage 进入受保护页面,签名颜色、Tab 切换及“已有管理端会话 + 客户端错误密码”可视交互待授权后补测。

2026-07-16 HTTP 单条发送、回执/上行回调与上行查询(已提交、已部署)

  • 已新增独立 HTTP 接入数据模型与 migration 20260716110000_add_http_open_api:应用能力配置、独立 IP 白名单、AES-256-GCM 凭据、数据库幂等请求、Webhook 端点/事件/投递/尝试记录,以及应用内唯一 clientMessageId
  • 已实现 HMAC-SHA256 机器鉴权、Redis nonce 防重放和应用级 QPS、单条发送、短信状态查询、上行游标查询/详情。单发复用真实 SendChainService 的模板、风控、余额、计费和 Redis 入队链路;相同幂等键同内容重放、不同内容冲突。
  • 已将现有 Gateway 回执和上行落库后投递扩展为 cmpp/http/both/none 分流,HTTP Webhook 使用 BullMQ、事件 ID、签名、超时、尝试记录和退避重试;保存与投递前执行 HTTPS/SSRF 校验且不跟随重定向。
  • 运营端企业应用编辑页已将 CMPP 和 HTTP 改为独立开关,并增加 HTTP 子能力、白名单、QPS、凭据数、投递模式和回调策略配置。客户端新增“接口对接”五个页签,企业应用卡片显示 HTTP 状态;上行短信页改为 NestJS/Prisma 服务端条件查询。
  • 本地真实 PostgreSQL、Redis、MinIO 已启动,migration 成功应用,52 条 migration 全部齐全。临时企业应用通过真实 API 完成 HMAC/时间戳/IP、错误签名、签名后 nonce 防重放、单发业务拒绝、失败幂等重放和上行查询验收:错误签名 401 且不占 nonce,正确签名后同 nonce 重放 401,上行空集合 200;无审核签名的单发首次及相同幂等键重放均为 422,数据库未产生批次、短信、Submit 或回执,因此未向验收手机号发送。临时数据已清理。
  • API 全量 20 suites、211 项通过,Prisma validate/migrate status、API build、前端 TypeScript/生产 build、Gateway 全量 Go 测试和 git diff --check 通过;前端仅有既有 chunk size warning。Browser 插件不可用,使用工作区 Playwright fallback:真实图形验证码登录客户端和运营端,客户端五个页签、真实凭据/请求日志、运营 HTTP 开关及能力字段均渲染并可交互;桌面 DOM 非空、无框架覆盖、console 无 error/warn。移动端仍受既有 AppShell 侧栏布局影响,本轮未扩展修改全局响应式框架。
  • 工作区完整改动已提交并 pushdcb6162dcf93a70e9886c978b07fdccee19dd657feat: add HTTP API and complete client workflows)。部署前确认本地基线与最新 origin/main 一致;生产 PostgreSQL、运行源码和环境文件备份目录为 /opt/cmpp-platform/backups/releases/20260716-113511,三份备份均非空并通过 gzip/tar 完整性及 SHA-256 校验,SHA-256 分别为 e384e1f041c0638943a0eee4da1877169b3aa89c4b0da95e55908be598ed31e01e28149b8b9d068f797a68d66ea074c88a0a43f0efd0b26f0b2d94afc259db3f87ab2efd509b39849b0ee22ead1b4cf0568fba4ab8525c59b5c78da51c73bc86
  • 发布包本地与服务器 SHA-256 均为 b49b51ef1acd2a0bb709ca91fbe0b98c16c80bc86f24b35b5dba141907cc7116;生产原缺失的 HTTP_API_MASTER_KEY 已生成并以 600 权限保存,密钥内容未输出。migration 20260716110000_add_http_open_api 已应用,52 条 migration 全部齐全且 schema 最新;生产运行提交为 dcb6162dcf93a70e9886c978b07fdccee19dd657
  • cmpp-apicmpp-gateway、MinIO、Nginx、PostgreSQL 和 Redis 正常,12026/17890/8090/3000/9000 监听,API/Gateway health、Redis PONG、PostgreSQL readiness 和外部首页、运营端、客户端、客户 Swagger 文档均通过。两个 Redis 通道权威 TPS key 均恢复为真实值 100gateway.submit.commands consumer group 为 pending=0、lag=0,数据库连接状态有 3 条 connected,部署后 10 分钟内 API/Gateway 无 error 级日志。
  • 客户文档 JSON 仅包含约定的 4 个路径:单条发送、短信状态查询、上行列表和上行详情;未鉴权访问真实 HTTP 接口返回 401。Browser 插件不可用,使用现有 Playwright/Chromium 复核生产运营登录、客户端鉴权跳转和 Swagger 文档:页面非空、标题/表单/4 个接口正常,输入控件交互成功,无框架错误覆盖或 console error/warn;未重置账号、未绕过验证码、未发送真实短信。

2026-07-16 运营端与客户端 P1/P2 移动端适配(已提交、已部署)

  • AppShell 在不大于 780px 的视口改为 56px 顶部栏与覆盖式左侧抽屉,抽屉默认关闭,支持遮罩、关闭按钮、Esc 和路由切换后自动收起;运营端长菜单和客户端菜单在抽屉内部独立滚动,不再作为 260px 高的页面顶部区域挤压业务内容。桌面折叠侧栏保持原行为。
  • 修复两端登录面板宽度计算;运营端报表、企业查询和审核筛选、手机号段库、通道组、通道报备详情、企业签名报备目标、客户端 HTTP 凭据等多列/固定宽度区域在小屏下改为单列或可换行布局。
  • 通用 Table 为每个单元格输出字段标签,小屏统一转为纵向记录卡片;客户端签名和引流信息列表、通道报备业务列表补专用卡片规则。状态、失败原因、密钥和操作按钮无需依赖横向滚动查看。
  • 应用内浏览器使用本地真实 NestJS API/PostgreSQL 的既有客户端会话在 390×844 视口验证:关闭态 document.scrollWidth=390、侧栏完全移出视口;打开态抽屉约占 82% 宽度且菜单独立滚动;点击“签名与引流信息”后路由切换并自动关闭。签名列表由原 1050px 横向内容收敛为 343px 卡片,账户账单表格容器和表格均为 293px 且无内部横向滚动;客户端登录页正文和文档宽度均为 390px,登录面板边界为 16~374px。未注入 mock、未绕过认证、未写业务数据。
  • 前端 TypeScript/Vite 生产构建、API build 和 git diff --check 均已通过;前端仅有既有 Vite chunk size warning。桌面规则位于 780px 媒体查询之外,既有侧栏折叠和桌面表格结构保持原行为。
  • 客户端导航隐藏尚未完成真实后端闭环的整个“彩信服务”分组及六个彩信子菜单;内部占位路由暂时保留,避免把未完成能力暴露给客户。
  • 运营端手机号段库按确认设计重做:复用平台通用 Breadcrumb、Button、Input、Tabs、Table、Tag、Pagination 和 Modal;标题区增加用途说明,Tab 下使用当前数据类型的紧凑真实总数信息带,搜索工具栏与数据表形成单一工作区,手机号段使用等宽强调,运营商使用语义标签,删除改为克制的文本危险操作。未增加批量导入、额外筛选或虚构覆盖统计。
  • 应用内浏览器使用真实本地运营管理员会话和 NestJS API 验收手机号段库:1536×1024 下页面与表格 scrollWidth=clientWidth=12301280px 下均为 959px,无横向滚动;390×844 下文档、面板、Tab、统计、筛选和表格容器均未超出 390px。已验证 Tab 切换同步“新增号段/新增规则”和当前统计,新增规则 Modal 可打开/关闭,关键词 138 查询后输入值保留、重置后清空,console 无 error/warn。设计图中的示例总数、31 省覆盖说明和示例行未照搬,页面只展示本地 PostgreSQL 的真实 0 条数据;分页和标题采用平台通用组件样式。

2026-07-16 企业应用 CMPP/HTTP 配置区域拆分(已提交、已部署)

  • 运营端企业应用新增/编辑页将原来混排的“接口配置”拆成独立 CMPP 接入配置和 HTTP 接口配置区块。CMPP 区集中账号、扩展码、接入号、密码、连接数、CMPP 白名单和下游重试;HTTP 区集中能力、HTTP 白名单、QPS、凭据限制、投递方式及 Webhook 安全重试,保存仍沿用现有真实 NestJS API 字段。
  • 两个协议使用独立开关和视觉标识;关闭时只收起本协议参数并展示关闭说明,不改变另一协议的开关或表单状态。HTTP 能力静态定义移出组件渲染,避免每次渲染重复创建配置数组。
  • Browser 插件不可用,使用已有 Playwright/Chromium、真实本地 NestJS API、PostgreSQL、Redis 和临时平台管理员完成 1440×1000 验收:HTTP 从关闭切换为开启后只展开 HTTP 参数;CMPP 关闭后账号等字段消失但 HTTP QPS 保持可见;页面标题、DOM、控制台均正常。390×844 复核 body.scrollWidth=viewportWidth=390,无页面级横向滚动。临时管理员、登录操作日志和会话均已清理,未创建企业应用、未发送短信。
  • 使用 Node.js 24 执行前端 TypeScript/Vite 生产构建通过,仅有既有 chunk size warning;默认 Node.js 14 不支持当前 Vite 的 ??= 语法且会错误返回退出码 0,因此未将旧 Node 结果计为有效构建。

2026-07-16 全平台金额四位小数精度(已提交、已部署)

  • 根因确认:企业应用编辑页原先按 Math.round(元 × 100) 保存,0.0325 元只能落为 3 分;PostgreSQL 的余额、流水、单价、计费和利润字段也均为 Int 分,无法表达万分之一元。现统一调整为 1 元 = 10000 金额单位,字段名中的 Cents 仅为兼容既有 API 保留。
  • Prisma 金额列统一升级为 BigIntmigration 20260716150000_expand_money_precision_to_four_decimals 将历史整数分乘以 100。迁移前已备份本地真实 PostgreSQL;抽查 AccountTransaction、SmsApplication、SmsMessageRecord、TenantAccount 汇总,迁移后整数值均精确为迁移前 100 倍,按新除数换算后的人民币金额不变。53 条 migration 已全部应用,Prisma schema validate 和 migrate status 均通过。
  • 企业应用客户价、通道成本价、授信和人工充值输入均允许最多 4 位小数并转换为整数金额单位;该阶段曾统一固定展示 4 位小数,现已由 2026-08-12 的统一金额样式需求调整为最多 4 位并裁剪末尾无意义的 0,通道成本费率除外。利润 CSV 仍以“元”为表头并保留业务所需精度。
  • NestJS 对客户价、通道价、充值、授信、计费规则和计费结果增加安全整数校验;Prisma BigInt 响应仅在 JavaScript 安全整数范围内序列化为 number,超限直接报错,避免静默精度损失。计费单测新增 325 × 2 = 650 金额单位,企业应用更新单测使用 customerUnitPrice=325
  • 使用真实本地 NestJS API、PostgreSQL、Redis 和 Playwright/Chromium 编辑一条已配置通道组的企业应用:页面填写 0.0325 后保存,数据库核对 SmsApplication.customerUnitPrice=325,再次进入编辑页仍为 0.0325,控制台无 error;随后已恢复原单价并清理临时管理员、角色关联和操作日志。
  • API 全量 20 个 Jest 测试套件通过,其中金额与企业应用目标套件 45 条用例通过;API TypeScript build、前端 TypeScript/Vite 生产 build、Gateway go test ./...、Prisma validate/status 和 git diff --check 均通过。

2026-07-16 企业应用参数复制与下游 CMPP 约束修复(已提交、已部署)

  • 根因确认:运营端 CMPP 参数 API 原先误取最新上游 SmsChannel.gatewayHost/gatewayPort,不是客户接入平台的地址;页面直接调用 navigator.clipboard.writeText,在生产 HTTP 非安全上下文可能无提示失败。现改为读取 CMPP_PUBLIC_HOST/CMPP_PUBLIC_PORT,并增加 Clipboard API 失败后的 textarea 降级复制和错误提示。
  • 运营端企业应用列表补充 HTTP 参数查看/复制;客户端接口对接页补充 HTTP 参数复制。客户端未开通 CMPP 时按钮禁用,客户端 CMPP 参数 API 同时返回 403,避免仅靠前端隐藏后仍可读取密码等接入参数。
  • Gateway 登录响应接入真实 cmppMaxConnections,按应用活动 TCP 会话计数并拒绝超限 bind;底层连接关闭回调会清理会话和回写断开。API 连接事件再次校验应用状态、接口开关、IP/CIDR 白名单和连接数,存量连接在下一次心跳不再符合配置时由 Gateway 主动关闭。
  • 生产只读核查发现应用 715011 最大连接数为 1,当前来源 IP 为 183.194.97.158,白名单后来改为 2.2.2.2;连接建立早于白名单修改,印证旧实现不会主动清理存量连接。核查期间未修改生产配置、数据库或进程。
  • API 目标测试 2 个套件 97 条以及全量 20 个套件 213 条断言通过,API TypeScript build、Gateway go test ./...、前端 TypeScript/Vite build 和部署脚本语法检查通过;全量 Jest 完成后仍提示既有异步句柄未关闭,断言结果不受影响,测试进程已单独结束。使用真实本地 NestJS API、PostgreSQL 和 Playwright/Chromium 验证运营端两类参数复制、客户端未开通 CMPP 的页面禁用与 API 403,以及 HTTP 页面复制降级;临时数据已清理。
  • 生产首轮发布复核发现 Gateway 进程重启时无法保证回写旧 TCP 会话断开,数据库陈旧连接可能占用应用连接名额,而原超时清理只在查询连接列表时触发。现将 90 秒陈旧连接清理前置到每次非断开连接事件校验,确保新 Gateway 无需等待运营人员打开页面即可自动恢复连接名额。
  • 工作区完整功能提交 faa716b8d07ea77fae3ec41c858b52f6a341e6b9 和重启恢复修正提交 23a1f6fa15445dbe6d2e4738b10b545b7c657472 已 push。两次发布前备份分别位于 /opt/cmpp-platform/backups/releases/20260716-175500/opt/cmpp-platform/backups/releases/20260716-180244,PostgreSQL、运行源码和环境配置均通过 gzip/tar 完整性及 SHA-256 校验;最终发布包本地与服务器 SHA-256 均为 c34c0fb627b77aa0c1a3d08169b3aff8d04587544ed9c1d83d8c0cd41b007272
  • 生产 migration 20260716150000_expand_money_precision_to_four_decimals 已应用,53 条 migration 齐全,SmsApplication.customerUnitPrice 等金额列已为 BIGINT。生产 API/Gateway health、PostgreSQL、Redis PONG、MinIO、Nginx 及 12026/17890/8090/3000/9000 监听均正常;两个真实通道 TPS key 均为 100gateway.submit.commandspending=0、lag=0,部署后 API/Gateway 无 error 级日志。
  • 预发布公网 CMPP 参数已配置为 8.160.169.106:17890。不符合白名单的 715011 / 183.194.97.158 陈旧连接在超时窗口后自动清除,合法账号 910887 由新 Gateway 建立新连接并持续更新心跳,证明白名单和重启后连接名额恢复逻辑真实生效。Chrome/Playwright 复核运营登录、390px 客户端登录和客户 Swagger 文档均为 200、无横向溢出、无 console/page error;未绕过验证码、未修改账号、未发送短信。

2026-07-18 CMPP 多号码 Submit 首号码静默丢弃修复(未提交、未部署)

  • 生产只读复现确认:账号 695829 的 CMPP 3.0 Submit 日志记录 dest_count=2Gateway 返回 result=0,但只将首号码 188****3795 传入 NestJS 并创建一条 SmsMessageRecord;随后单独提交第二个号码 131****0092 才产生第二条记录。核查期间未修改生产配置、数据或进程。
  • 根因为 Gateway 已完整解码 DestTerminalId[],但处理时固定读取下标 0Gateway→NestJS 契约和 submitInboundMessage 也只有单数 phoneNumberNestJS 固定以 phoneTotal=1 创建内部批次和短信记录。当前行为属于“返回成功但静默丢失后续号码”,不是可接受的单号码范围限制。
  • Gateway 入站契约新增完整 phoneNumbers,保留首号码字段兼容;NestJS 在任何业务落库前校验全部目标号码,并以最多 10 个并发的有界批次逐号码复用现有真实模板/签名、风控、余额、计费、队列和失败回执链路。每个号码创建独立 sourceType=cmpp 内部批次和 SmsMessageRecordAPI 返回全部内部 messageId 映射。
  • 一个客户 Submit 仍只返回一个 CMPP SubmitResp/Msg_Id。Gateway 将该 Msg_Id 同时关联到本包全部内部 messageId,后续每个号码的 Deliver Receipt 使用相同原 Submit Msg_Id,并通过自己的 DestTerminalId 区分;连接断开时同步清理同一连接下全部消息映射。新增 migration 20260718130000_add_cmpp_submit_group_message_id,为每条拆分记录持久化同一 cmppSubmitGroupMessageId;Gateway 重启恢复时结合该分组 ID 与原 Sequence_Id 重建相同 Msg_Id,不再按各内部 messageId 算出不同结果。
  • 新增 API 回归覆盖两号码分别落库、分别生成失败回执,以及任一号码非法时整包落库前拒绝;Gateway 真实 CMPP 3.0 TCP 集成用例改为一次提交两个号码,并验证第二个内部消息的 Deliver 携带第二个号码且 Msg_Id 与原 SubmitResp 相同,另覆盖重启恢复时两个内部 messageId 仍重建同一 Msg_Id。API 定向测试 1 suite/60 项、API 全量 20 suites/215 项、Gateway internal/inbound 定向测试、Gateway 全量 go test ./...、API TypeScript build、前端 TypeScript/Vite build、Prisma generate/validate 均通过;本地 PostgreSQL 已应用 54 条 migration 且 schema 最新,前端仅有既有 chunk size warning。
  • 使用真实本地 NestJS API、PostgreSQL 和 Redis 创建临时接口关闭应用,向 /api/gateway/events/inbound/submit 一次提交两个合法号码:API 返回 phoneCount=2 和两个内部 messageId,数据库真实生成 2 个 sourceType=cmpp 内部批次、2 条短信记录、2 条失败回执和 2 条下游投递;两条记录的 Sequence_Id 与 cmppSubmitGroupMessageId 分别一致,下游 payload 只有 1 个分组 ID。再提交“一个合法号码 + 一个非法号码”返回 HTTP 400,记录数保持不变。临时企业、应用、白名单、批次、短信、回执和投递已全部清理,未连接上游 Gateway、未发送短信。

2026-07-18 手工验收瑕疵修复(未提交、未部署)

  • 已实现图片 2MB/其他文件 10MB 前端与 NestJS 双层校验,通用文件和报备材料上传不再允许 20MB/100MB;企业信用代码收紧为英文字母与数字,营业执照操作样式和长文件名换行已修复。
  • 企业应用 HTTP 开通时默认开启六项能力并使用 HTTP Webhook,参数复制改为中文业务文案;应用列表查询/重置每次重请真实 API,CMPP 连接详情改为无水平滚动的自适应卡片;桌面侧栏强制隐藏移动端关闭按钮。
  • 审核 API 从当前登录会话写入审核人,列表时间格式化,审核人/时间收入“更多信息”弹窗,审核成功即时刷新导航角标。短信记录查询/重置重请 API,详情新增客户提交接入号与上游发送接入号。
  • 引流列表移除重复的“引流信息”列并改名“引流url或号码”;运营商规则改为中文标签,新增真实 NestJS/Prisma DELETE 链路。成功登录由用户服务写入 auth.login_success,其他会话用户成功写操作由统一 OperationLog 中间件兜底,不记录请求体和密钥。
  • 定向验证通过:API TypeScript build;文件、企业、风控审核、用户登录与人工操作日志 5 个 Jest suites/27 项;前端 TypeScript/Vite buildPrisma validategit diff --check。前端仅有既有 chunk size warning。API 全量 Jest 已尝试,21 suites 中 20 suites、219 项中 218 项通过;唯一失败是另一会话正在修改的 send-chain.service.spec.ts 用例在本地 Redis 127.0.0.1:6379 未运行时连接超时,本次未改动该套件。未在生产写入业务数据,未发送短信。
  • 生产只读排查:MSG-22a27cd0-b671-4ae8-8beb-6608eaf04517 已有真实未达回执,但无 CmppDownstreamDelivery/HTTP Webhook 事件;该问题与另一会话正在修复的 CMPP 多号码 Submit/Msg_Id 分组链路相互耦合,本次未修改 send-chain、Gateway inbound、Prisma schema 及其 migration,避免覆盖并行修复。“今日返还”数据核查发现当前包含发送链在路由/模板校验前的冻结后释放,余额、日限、校验顺序与返还口径待并行发送链修复后再联合回归。

2026-07-20 LG 缺陷修复与本地真实链路验证(未提交、未部署)

  • 保留并识别并行会话的 CMPP 多号码 Submit、分组 Msg_Id 和 Gateway 入站差异,本轮未覆盖或重写其 Gateway 文件;既有两号码、混合非法号码及重启恢复测试随 Gateway/API 全量测试通过。
  • 回执关联改为内部消息 ID 或 channelId + gatewayMessageId + phoneNumber 的唯一提交记录,新增稳定 receiptKey 数据库唯一约束和并发冲突兜底。主记录同步保存真实通道、通道消息号、原始状态、文本和到达时间,重复 DELIVRD 不再重复客户投递。
  • 对账、应用/通道利润和质量报表统一补充失败数、退款、真实成本、利润及到达时长,并由既有 T-4 至 T-1 重算覆盖延迟回执。真实 PostgreSQL 重算样本为发送 2、成功 1、失败 1、收入 352、退款 352、成本 400、利润 -48、平均到达 5000ms;重复执行一致,临时数据已清理。
  • 用户接口增加运营端/客户端安全 DTO,移除密码散列、会话版本和认证内部字段;后端阻止自删除/自停用、最后一个平台/企业管理员删除或降权,并将 Prisma 唯一冲突映射为 409。逻辑删除后的用户名继续保留,确保历史审计关联稳定。
  • HTTP 单发改为仅凭 mobile/content 自动识别已审核签名、模板和变量,复用 CMPP 发送规则;修复 API 来源批次创建后按客户端来源读取导致的 404,OpenAPI 增加稳定请求 Schema 和示例。客户端发送候选默认只返回 approved 签名/模板,变量拒绝未闭合、空、中文、重复、非法或超长名称。
  • 报备资料新增官方 XLSX 模板和按筛选导出接口,导入拒绝公式及公式注入单元格;分析、提交、导出日志保存当前操作人、文件名、筛选和成功/失败数。黑名单重复唯一冲突返回 409,逻辑删除记录按既定规则恢复。
  • 本地 Redis PING=PONG,真实 NestJS API health 返回 ok。使用真实 PostgreSQL、Redis 与 /api/gateway/events/receipt 验证同一通道 Msg_Id 双通道场景:A 保持 submittedB 正确 delivered,重复回执返回同一消息且仅一条回执记录。回执目的号码已持久化并建立三字段匹配索引;Prisma 本地 57 条 migration 已应用且 schema 最新。
  • 验证通过:API 全量 Jest 21 suites/237 tests、回执与报备材料定向 2 suites/68 tests、用户安全与报备材料定向 2 suites/17 tests、API TypeScript build、Gateway go test ./...、前端 TypeScript/Vite build。Jest 仍有既有异步句柄退出提示,断言全部通过;前端仍有既有大 chunk 警告。生产未写入数据、未发送短信,代码未提交、未 push、未部署,生产仍需获批发布后复测。
  • npm run verify:phase8 两次完整尝试都在同一个 BullMQ 15,000 条性能门槛停止,分别为 375.00 TPS 和 404.53 TPS,未达到 500 TPS;同一脚本隔离复测为 907.93 TPS 并通过。因此功能与契约断言未失败,但完整阶段命令受本机共享 Redis/瞬时负载影响,按“环境性能不稳定”记录,不能标记为完整通过。
  • Browser 插件已打开真实本地运营端,登录页、验证码和前端到 NestJS API 代理正常;登录后报表页面验收受图形验证码安全约束阻塞,本轮未代解或绕过验证码,不能标记为页面通过。本地临时管理员、角色及关联数据已清理,临时 API/前端进程已关闭。
  • 另通过真实本地登录 API、HttpOnly 会话、PostgreSQL 与 NestJS 路由完成后端验收:GET /admin/users 找到临时用户且 passwordHash/sessionVersion/failedLoginCount 泄漏字段为空;当前用户自删返回 403;官方签名资料模板下载返回 200、XLSX 6952 字节;利润查询返回真实聚合行。数据库 OperationLog 记录 report_material.template_downloaded、正确操作人、文件名、成功数和非空 IP;所有临时用户、角色、关联和日志随后已清理。

2026-07-20 平台LG二轮UI/UX阶段A启动与LG2-P0-01修复(未提交、未部署)

  • 已完整读取二轮最终报告、执行进度、基线、页面矩阵、设计规范、可访问性、五视口、性能稳定性、高风险、会话导航、角色边界,以及阶段A相关客户端组件/核心流程、运营核心流程、表单、列表和弹窗专项报告;查看了375/390手机阻断截图与1280桌面列宽截图。在测试文档目录建立45项唯一问题整改台账和阶段A源码/测试/风险映射。
  • 根因确认:公共Table在≤780px已经转为卡片,但客户端用户页四个动作继续使用不可换行.inline-actions,父卡片overflow:hidden把末尾删除裁掉。修复仅修改ClientUsersPage.tsx并新增页面专用CSS;手机/平板操作区变为2×2网格、按钮高度44px,未修改已有并发变更的公共global.css或用户后端。
  • 真实本地链路验收:启动NestJS、Vite preview、PostgreSQL和Redis,创建唯一临时租户/企业管理员,经真实验证码、登录会话、/api/client/users读取数据。375视口点击删除只打开含目标用户名的确认层并取消,记录未删除;随后退出并精确清理临时租户、用户、角色关联和操作日志,复核cleaned=true。未发送短信、未充值、未修改生产数据。
  • 五视口Browser验收:375×667、390×844和768×1024四项操作全部可见、中心可命中、高度44px且页面无横向溢出;1440×900全部首屏可见;1366×768保留既有55px表格内部横向滚动,滚动后删除完整可达,该桌面列宽问题继续归入LG2-P1-03/P2-04。控制台error/warn=0。截图保存在测试项目平台LG_UIUX二轮走查证据/整改_20260720_LG2-P0-01/
  • 自动化:API用户服务1 suite/11 tests、API TypeScript build、前端TypeScript/Vite build、Prisma validate/migrate status、Redis PONG和git diff --check通过;本地共有56条migration且schema最新。项目当前没有前端lint或组件测试脚本,未虚报通过。首次前端build被另一会话新增includeHistory:boolean查询类型拦截,已在adminApi.ts做字符串序列化的最小兼容,不改变业务语义。
  • LG2-P0-01在整改台账标记“已通过”;代码未提交、未推送、未部署,生产仍运行旧版本,生产P0尚未发布。

2026-07-20 工作区汇总生产发布(f02c33cb

  • 按用户授权汇总提交全部有效源码、migration、测试和文档改动,共61个文件、1834行新增和281行删除;提交为f02c33cbb7248410c189f75502d6e497fff7b355feat: harden CMPP delivery and platform workflows),已push至origin/main。按约束排除api/tsconfig.build.tsbuildinfologs/
  • 提交前门禁:API全量21 suites/237 tests通过,API TypeScript build、前端TypeScript/Vite build、Gateway go test ./...、4份Gateway队列契约、Prisma generate/validate及本地57条migration status、真实PostgreSQL报表重算集成验证、部署脚本语法和git diff --check均通过。Jest断言完成后仍有既有异步句柄提示,测试残留进程已精确结束;前端仍有约1.9MB大chunk警告。项目未配置前端lint或组件测试脚本,未虚报通过。
  • BullMQ 15000条/500并发门槛在本机共享Redis复测为429.50和404.43 TPS,临时独立Redis复测为379.39 TPS,未达到500 TPS;同一代码此前隔离复测达到907.93 TPS。本次不修改门槛、不伪造结果,按共享主机瞬时负载风险继续记录,后续应在固定规格、空载环境建立稳定基线。
  • 部署前生产PostgreSQL、运行源码和环境配置备份至/opt/cmpp-platform/backups/releases/20260720-180906。三份备份均非空并通过gzip/tar完整性及SHA-256校验:数据库824be663552da2d2ce99184ec464a6e72d2f25c0c16dee234bfc47c7d371f433、源码2598a9b6dd9b6a40002b877316cf23aef48447678915450381f76dcb99d14b54、环境189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。发布包本地和服务器SHA-256均为a6582da4de5c7161b480f4b5695099accb247071ec825e0b697c9f8d60762342
  • 使用tools/deploy/production-deploy.sh完成部署,成功应用20260718130000_add_cmpp_submit_group_message_id20260720110000_add_receipt_identity20260720113000_add_report_business_metrics20260720114500_add_receipt_phone_number,生产57条migration齐全且schema最新;CMPP多号码分组、回执唯一身份/目的号码、报表失败退款指标等目标列均已存在。
  • 预发布运行提交为f02c33cbb7248410c189f75502d6e497fff7b355cmpp-gatewaycmpp-api、Nginx、PostgreSQL、Redis和MinIO均active12026/17890/8090/3000/9000监听;API/Gateway health、Redis PONG、PostgreSQL readiness、外部首页、运营登录、客户端登录、API health和Swagger JSON均通过,公网CMPP 8.160.169.106:17890可连接。根目录/API运行依赖audit均为0漏洞。
  • 两个active上游通道均为connected/currentConnections=1,权威TPS配置已恢复;Redis Stream gateway.submit.commands consumer group为pending=0、lag=0。部署后API/Gateway error级日志均为0。未发送或重投真实短信,未执行充值、审核、删除或生产业务数据修改。
  • 本地Browser五视口LG2-P0-01证据已通过;生产浏览器烟测被企业网络策略禁止访问该公网HTTP地址,未使用其他浏览器或自动化方式绕过。生产外部HTTP/TCP、真实服务、数据库、Redis和运行产物均已核验,但本次不把生产浏览器交互标记为通过。

2026-07-21 北向连接名额、历史回执与报表回填复查(未提交、未部署)

  • 生产只读复查确认北向普通/长短信无 SUBMIT_RESP 的直接阻塞发生在企业应用下游接入侧:账号 695829 的旧连接登记为 connected,但 TCP 和 Redis 均无对应在线连接;lastHeartbeatAt=NULL 使既有 lastHeartbeatAt < cutoff 条件永远不成立,陈旧记录持续占用 cmppMaxConnections,新连接在业务层登记时被关闭,Submit 因而未被 Gateway 读取。经用户授权只清理该条已确认无真实连接的陈旧登记,未修改账号、应用或短信数据,连接名额恢复为 0;仍须部署本轮代码后重新做生产普通、长短信和多号码端到端验证。
  • markTimedOutDownstreamConnections 已增加安全的 NULL 心跳清理:仅当 lastHeartbeatAt IS NULLconnectedAt 也早于超时窗口时才删除,避免误清刚建立但首个心跳尚未到达的连接。回归测试先在旧实现上失败,修复后 sms-config.service.spec.ts 46 项全部通过。
  • 生产历史数据只读核对找到 3 条“已有唯一 DELIVRD、主记录仍 submitted”的旧记录,均为同一上游账号复用两个通道时历史回执 channelId 归属反转;2026-07-21 新回执已按唯一提交记录正确归属并聚合,说明当前实时匹配代码已生效,遗留缺口是旧数据回填而不是继续发生的实时抢占。
  • 新增 migration 20260721150000_backfill_misattributed_delivery_receipts:仅在“同一内部消息、同一 Gateway Msg_Id、同一目的号码恰好只有一条提交记录”时修正回执通道并把 DELIVRD 聚合到短信主记录;零匹配或多匹配保持原样,避免猜测修复。迁移可重复执行;本地真实 PostgreSQL 构造同账号双通道错归属样本后应用及重放均通过,主记录变为 delivered,回执状态、原始码/文本、到达时间、通道和通道消息号一致。
  • 在上述真实样本上执行既有 T-4 至 T-1 报表重算,发送数/成功数/失败数为 1/1/0,利润成功数为 1,质量成功率为 100%,平均到达时长为 5000ms;证明 7 月 18、19 日历史报表缺口应按“先迁移回填主记录,再重算对应日期”处理。生产尚未应用 migration 或重算,历史页面当前仍会保持旧结果。
  • HTTP 正向发送旧结论经 2026-07-21 较新生产证据纠正:仅传 mobile/content 的合法请求已返回 202、自动关联正确签名和模板、返回 MessageId,并通过真实路由和计费;不能再归类为当前未修复。重复用户名生产接口也已返回 409。黑名单 P2002 映射代码原已存在,本轮补充全局/企业及逻辑删除占用的 BLACKLIST_DUPLICATE 409 回归测试。
  • 完整验证:API 21 suites/240 tests、Gateway go test ./...、API build、前端 TypeScript/Vite build、Prisma generate/validate/status58 条 migrationschema 最新)均通过;前端仅有既有约 1.9MB chunk warningJest 仍需 --forceExit 结束既有异步句柄。git diff --check 在文档收尾后另行复核。
  • npm run verify:phase8 的契约和 Gateway 阶段通过,但共享 Redis 的 BullMQ 15,000 条/500 并发结果为 enqueue 3577.89 TPS、端到端 431.29 TPS,未达到 500 TPS,因此完整命令未通过;临时隔离 Redis 同参数端到端为 567.37 TPS 并通过。该项按共享环境性能阻塞记录,不把共享 Redis 结果标为通过。
  • 本地正式链路启动真实 NestJS API、PostgreSQL、Redis 和 Go GatewayAPI /api/health、Gateway /health 均为 okRedis PONGGateway 监听 127.0.0.1:7890 且恢复候选数为 0;验收后精确停止本轮 3000/8090/7890 端口进程。未向生产号码发送短信,未部署、未提交、未 push。

2026-07-21 UI/UX A1双门户会话隔离与深链恢复(未提交、未部署)

  • 修复LG2-P1-01/02/03/05:前端会话存储、DOM事件和BroadcastChannel按admin/client命名空间隔离;NestJS使用cmpp_admin_session/cmpp_client_session(安全Cookie环境使用对应__Host-名称),中间件按目标门户路径只读取对应Cookie;所有touch/lock/unlock/reauthenticate/logout/password接口改为门户专用路径。
  • 新增真实会话初始化边界和安全returnUrl:受保护路由先读取后端当前会话,未登录时保存同源、同门户白名单目标;登录后回原深链。当前会话接口只返回安全用户DTO和时序状态,不输出令牌。锁定刷新时暂停首次业务路由和运营看板请求,解锁后原URL重新挂载真实数据;当前标签已加载的路由不会被另一门户广播卸载。
  • 自动化:认证会话2 suites/10 tests、API TypeScript build、前端TypeScript/Vite build及git diff --check通过;项目没有前端lint/组件测试脚本,未虚报。前端仍有既有约1.90MB大chunk警告。本批无Prisma schema变更。
  • 真实链路:本地PostgreSQL建立隔离验收用户,Redis真实保存不透明会话;同一Cookie容器同时得到cmpp_admin_session,cmpp_client_session。锁定admin时client仍activeadmin解锁轮换Cookieclient退出后admin当前会话仍返回a1_admin
  • 浏览器:客户端13/13受保护路由逐条打开和刷新均保持目标URL及客户端身份,console error/warn为0;同浏览器双门户并存、客户端退出后运营端刷新继续有效。运营用户页在1440×900、1366×768、768×1024、390×844、375×667实际视口均显示真实用户且console为0;390×844锁定、刷新、解锁后仍在/admin/users且真实用户重新出现,锁定阶段console为0。证据在测试项目平台LG_UIUX二轮走查证据/A1会话隔离-20260721/
  • 未修改生产业务数据,未发送短信、充值、审核、删除或报备;代码未提交、未push、未部署,生产仍运行旧会话实现。生产发布后旧共享Cookie需要重新登录,故台账暂记“待验证”。本地临时API由本会话启动,收尾时精确停止;PostgreSQL/Redis/既有前端进程不属于本会话,不停止。

2026-07-21 UI/UX A2客户端安全上传与日志导出(未提交、未部署)

  • LG2-P1-04改为客户端专用上传/下载接口:租户从当前会话用户反查,不再信任x-tenant-id;企业认证、签名报备、引流报备用途和目录白名单由后端强制,跨企业下载返回404。前端客户端预览/下载也不再调用admin端点。
  • LG2-P1-06新增两端共用日志导出状态组件:提交中防重复、完成数量/截断提示/操作单号、CSV下载、失败原地重试,并按门户在sessionStorage仅保存瞬时恢复筛选。后端从PostgreSQL真实筛选导出;客户端租户由会话反查且CSV只保留时间、级别、模块、操作人、动作、资源ID,另有10000条上限和公式注入防护。
  • 自动化通过:文件/运营服务2 suites、24 testsAPI TypeScript build,前端TypeScript/Vite buildPrisma validate/migrate status(本地58条、schema最新)和git diff --check。项目仍无前端lint/组件测试脚本;前端仍有既有约1.9MB chunk告警。
  • 真实链路:本地NestJS、PostgreSQL、Redis和MinIO在线;客户端真实验证码登录后,携带伪造租户头上传仍落当前企业a2-local-tenant,MinIO对象经客户端接口读回55字节。客户端日志导出真实返回安全6列表头、5条记录;Browser在1440×900点击导出显示3条和操作单号2aa2521d-111d-48a6-87c2-27cdbcf680be。本轮未完成console专项读取,不虚报console通过。
  • Browser上传因隐藏file input点击超时未完成页面级验收;1366×768、768×1024、390×844、375×667截图也尚未补齐,因此两项台账均保持“待验证”,不标记已通过。未改生产数据,未提交、未push、未部署;并行会话的短信配置、字典、回执migration及其文档未改动。

2026-07-21 UI/UX A3审核通过风险治理(未提交、未部署)

  • 新增独立审核治理服务和RiskAction组件,签名/模板“通过”从直接终态调用改为“后端资格预检→对象/影响确认→提交中锁定→结构化结果”。签名预检覆盖应用绑定、公司/信用代码、法人、责任人/手机号和资质文件;模板覆盖内容、签名绑定及签名审核状态。
  • 后端从当前会话写审核人,使用pending + updatedAt条件更新和Serializable事务阻止并发覆盖;AuditRecord ID作为操作单号,幂等键随审计持久化,同键重试返回原结果。旧批准路由也统一进入治理服务。未修改并行会话占用的sms-config.service.ts/spec.ts
  • 自动化通过:审核治理1 suite/5 tests、API TypeScript build、前端TypeScript/Vite build、Prisma validate及git diff --check。前端仍有既有约1.91MB chunk告警;Jest断言通过后仍需--forceExit结束既有异步句柄。
  • 真实本地API/PostgreSQL:完整签名预检为approve,reject且0阻断,首次批准写入操作单号cmruefurl0002msyuftczvswt并变为approved;相同幂等键重放返回同一单号和replayed=true。验收企业、应用、签名、审核记录、用户和日志已精确清理。
  • Browser实际打开运营登录页并读取验证码,但登录后受A1未提交会话链的“登录会话已失效”恢复提示阻断,未打开A3确认层;console专项返回空数组。未改生产数据。驳回统一协议、有限撤销/双人复核和五视口页面证据未完成,因此台账记“部分通过”,代码未提交、未push、未部署。

2026-07-21 定时短信自动派发与多实例幂等(未提交、未部署)

  • 根因:到期任务此前只有 POST /api/admin/send/scheduled/dispatch-due 手工入口,API 启动后没有自动扫描;派发前也没有数据库条件更新认领,多实例同时扫描会重复冻结和入队。
  • API 启动后默认 1 秒首次扫描、每 5 秒继续扫描,可通过 SMS_SCHEDULED_DISPATCH_SCAN_ENABLEDSMS_SCHEDULED_DISPATCH_SCAN_INTERVAL_MS 配置;进程内重入保护避免同一实例扫描重叠。
  • 派发使用 id + status (+ stale updatedAt)updateMany 条件更新原子认领。正常任务进入 scheduled_dispatching;超过默认 2 分钟的陈旧认领在 scheduled_dispatching/scheduled_recovering 间交替认领,保证多实例仅一个恢复者胜出。
  • 恢复时按 tenantId + transactionType=frozen + relatedType=sms_batch_task + relatedId 查询既有冻结流水,存在则不再冻结;BullMQ 继续使用消息记录 ID 作为 jobId。0 元任务在资源和余额检查通过后若 Redis 入队失败,也保留调度中状态等待恢复,不会被错误终结。
  • 回归测试先覆盖旧代码失败,再完成实现;send-chain.service.spec.ts 共 67/67 通过,新增自动启动扫描、并发扫描唯一认领、陈旧认领恢复不重复冻结和 0 元任务入队失败可恢复用例。API TypeScript build 通过。
  • 该 Jest 套件断言约 24 秒完成,但仍需 --forceExit 结束仓库既有 BullMQ/Redis 异步句柄;未把句柄问题标记为通过。本批没有 Prisma schema/migration 变化,尚未执行真实 PostgreSQL/Redis 双实例故障注入,留待本地链路总验收。
  • 代码和文档均未提交、未 push、未部署;生产仍需发布后验证无需手工接口即可自动派发到期任务。

2026-07-21 下游人工重投与Gateway提交异常恢复(未提交、未部署)

  • 根因一:requeueDownstreamDelivery 原先先读取再普通 update,没有状态版本条件;并发请求可重复递增人工次数并多次调用 Gateway。若直接把认领结果写为 pending,Gateway 恢复扫描还可能与同步控制面调用形成双发窗口。
  • 下游人工重投改为 id + status + updatedAtupdateMany 原子认领,认领态为 manual_requeueingGateway pending 查询不会选中该状态。成功写出后进入 awaiting_ack,失败走既有明确状态机;超过默认 2 分钟的陈旧认领自动恢复为 pending,阈值可通过 CMPP_DOWNSTREAM_MANUAL_REQUEUE_STALE_MS 配置。
  • 根因二:Gateway提交异常虽然已有 pending→requeueing 抢占,但 Redis XADD 成功、数据库更新 requeued 失败时会永久停留 requeueing;直接重放又可能产生第二条 SubmitCommand。重复异常上报还会无条件把已解决记录重置为 pending。
  • 提交异常重入队现在使用 gateway:submit:requeue:{deadLetterId}:{nextAttempt} 稳定键和 Redis Lua,原子执行幂等检查、XADD 和 30 天 Stream ID 保存;陈旧 requeueing 由后台扫描抢占为 requeue_recovering,并复用同一键完成数据库落账。SubmitResult 可从 pending/requeueing/requeue_recovering/requeued 任一在途状态直接闭环 resolved,恢复不会覆盖 resolved;重复上报只更新失败详情,不回退处理状态。
  • 回归测试先在旧实现失败,修复后 send-chain.service.spec.ts 71/71 通过;新增重复异常上报不回退、陈旧提交重入队恢复、下游并发唯一认领和陈旧人工认领恢复用例。API TypeScript build 通过;Jest 仍需 --forceExit 结束仓库既有 BullMQ/Redis异步句柄。
  • 真实 Redis 验证:同一幂等键并发发布两次返回相同 Stream IDStream entry 数为 1,幂等键 TTL 为 2592000 秒;测试 Stream 和 key 已删除。
  • 真实 PostgreSQL 并发验证:两个请求在读取同一版本后同时重投,结果为 1 成功、1 冲突,Gateway 控制面仅调用 1 次,manualRetryCount=1,成功记录进入 awaiting_ack;陈旧 manual_requeueing 记录自动恢复为 pending。另以真实 PostgreSQL+Redis 验证陈旧提交异常恢复后 status=requeued、人工次数=1、重复幂等发布仍只有一条 Stream entry。所有本地临时企业、应用、投递、异常、日志、Stream 和 key 均已清理。
  • 本批无 Prisma schema 或 migration 变化,没有修改 Go Gateway。未发送短信,未修改生产数据;代码未提交、未 push、未部署。

2026-07-21 UI/UX A4报备生成资格、幂等与结果治理(未提交、未部署)

  • LG2-P1-15后端新增POST /api/admin/report-materials/batches/preflight,逐资料/通道检查审核与待报备状态、应用启用、版本、路由、通道状态、字段配置和必填值;非法资料ID返回可读400,0可生成目标在创建批次前返回REPORT_BATCH_NOT_ELIGIBLE
  • 生成接口要求幂等键,通过PostgreSQL advisory transaction lock认领操作;资料类型/ID/版本/应用/通道/运营商形成持久化业务键。相同请求重放返回原操作单和结果,不同范围复用键返回409;成功响应包含成功、跳过、失败分项及每项阻断原因。
  • 运营端列表由真实预检控制选择资格,明确显示“待补充”及首个阻断原因;生成前再次预检,确认层展示企业、应用、版本、预计通道、运营商和分项计数,提交中锁定,完成后显示批次与操作单号。
  • 自动化:report-materials.service.spec.ts 7/7、API TypeScript build、前端TypeScript/Vite build、Prisma validate及migrate status(本地58条、schema最新)均通过,git diff --check通过。API build首次被并行会话尚未完成的send-chain.service.ts变量错误阻断,未修改该文件;对方完成后收尾重试已通过。项目没有独立前端lint/组件测试脚本;前端仍有既有约1.91MB单chunk告警。
  • 真实API/PostgreSQL:临时已审核但未绑定应用的资料经真实管理员登录、待报备和预检接口返回eligible=false、0目标、“未绑定短信应用”;临时企业、用户、签名和日志清理后均为0。没有调用生成接口。
  • Browser只打开到确认层并取消:完整临时应用、路由、通道和字段显示1个可生成组合;1440×900、1366×768、768×1024、390×844、375×667均无横向溢出且弹窗在视口内,console error/warn为0。截图位于测试项目平台LG_UIUX二轮走查证据/A4_LG2-P1-15_报备预检_*.png;所有临时数据清理为0。
  • 未修改生产业务数据,未生成报备、发送短信、审核、充值或删除生产对象;代码未提交、未push、未部署,生产仍运行旧实现。

2026-07-21 UI/UX A5通道/签名/模板删除治理(未提交、未部署)

  • LG2-P1-20新增统一DeletionGovernanceService、admin/client预检与删除接口及共享DeleteRiskAction。确认层展示对象名称/ID、活动依赖数量和对象摘要、阻断原因、影响范围、可恢复说明、原因、提交态及结构化操作结果;客户端查询由会话企业强制裁剪。
  • 后端对通道组/路由/活动连接/报备、签名关联模板/引流/报备、模板发送/批量任务做真实依赖检查。删除使用updatedAt乐观锁、Serializable事务、幂等键、逻辑删除和OperationLog操作单,旧通道删除及旧签名/模板删除状态入口统一委托治理服务。
  • 正向真实链路首次暴露PrismaService.operationLog代理属性不可配置导致事务客户端访问代理时报500;将属性改为可配置并新增prisma.service.spec.ts,修复后同一页面请求成功。真实PostgreSQL模板状态变为deleted并写入governance.delete日志、原因、依赖、影响和幂等键。
  • 自动化通过:deletion-governance.service.spec.tsprisma.service.spec.ts共2 suites / 7 tests、API TypeScript build、前端TypeScript/Vite build、Prisma migrate status(本地58条、schema最新)和git diff --check。项目没有独立前端lint/组件测试脚本;前端仍有既有约1.91MB单chunk告警。
  • Browser真实页面:通道被活动组引用时,1440×900、1366×768、768×1024、390×844、375×667均展示1项引用和后端阻断原因,确认按钮断言disabled;无依赖模板填写原因后页面列表变空,数据库和审计同步落账。console error/warn为0。证据位于测试项目平台LG_UIUX二轮走查证据/整改_A5_LG2-P1-20_20260721/
  • 本轮只写入并精确清理本地验收数据,未操作生产对象。代码未提交、未push、未部署;通用Dialog焦点/背景/dirty保护归A7,前端拆包与缓存归C阶段。

2026-07-21 UI/UX A6人工充值草稿、确认与幂等治理(未提交、未部署)

  • LG2-P1-21将充值记录页和企业管理页两个入口收敛到共享ManualRechargeDialog。取消、右上角关闭和完成都会销毁金额、备注、预检、结果及幂等键;浏览器分别填写123.45/88.88和备注后取消/关闭,重开字段均为空。
  • 新增POST /api/admin/billing/manual-recharges/preflight,从真实企业账户返回版本、现金余额、授信、方向和预计余额。确认层显示企业名称/编码/ID、方向、当前余额、变动、预计余额及备注,提交期间防重复,成功显示订单号、余额、操作单和幂等重放状态。
  • 最终接口由当前会话注入操作者,要求8—128位幂等键和账户版本;advisory transaction lock串行同键请求,updatedAt条件更新阻止覆盖新余额。订单、余额增量、账户流水和OperationLog在Serializable事务中原子写入。
  • 真实API/PostgreSQL:本地临时账户10.0000元,经页面充值1.2345元后为11.2345元;订单、流水、审计各1条。相同幂等键再次调用真实API返回同订单、同操作单、replayed=true,三个计数仍各1。充值记录页和企业管理页均回读11.2345元。
  • Browser五视口1440×900、1366×768、768×1024、390×844、375×667通过;375短屏底部操作可达,console error/warn为0。截图和API日志位于测试项目平台LG_UIUX二轮走查证据/整改_A6_LG2-P1-21_20260721/
  • 自动化通过:billing.service.spec.ts 1 suite / 11 tests、API TypeScript build、前端TypeScript/Vite build、Prisma migrate status58条、schema最新)及git diff --check。项目没有独立前端lint/组件测试脚本;约1.92MB单chunk告警归C阶段性能项。
  • 仅修改并精确清理本地验收数据,未操作生产充值。代码未提交、未push、未部署;生产仍运行旧实现,通用Dialog焦点/背景隔离/dirty guard继续由A7处理。

2026-07-22 UI/UX A7公共Dialog整改(未提交、未部署)

  • 修复LG2-P1-23:公共Modal新增初始焦点、顶层焦点栈、Tab/Shift+Tab约束、背景inert/aria-hidden、滚动锁、aria-labelledby和关闭后焦点恢复;遮罩由可聚焦button改为非交互div。
  • 新增dirty关闭协议:右上角、取消、Escape和遮罩统一进入具名alertdialog;父弹窗暂时inert,继续编辑保留草稿并恢复原字段焦点,明确放弃后才关闭并销毁。人工充值、删除风险动作和两端模板表单接入该协议。
  • 真实浏览器:本地NestJS/PostgreSQL/Redis会话分别登录运营与客户端;运营企业模板留存1440×900、1366×768、768×1024、390×844、375×667五张截图,客户端模板在1440×900和390×844完成DOM/键盘实测。五视口无横向溢出,主弹窗与确认层焦点循环、草稿保留、背景恢复、触发按钮焦点恢复均通过;两端console error/warn为空。
  • 验证:前端TypeScript/Vite build、API TypeScript build、Prisma validate/migrate status和git diff --check通过。项目无独立前端lint/组件/axe脚本,未虚报;构建仍有既有约1.92MB单chunk告警。
  • 未创建模板、未执行审核/删除/充值/发送或其他生产业务写入;本地临时用户、企业、日志和Redis会话已精确清理。代码未提交、未push、未部署,生产仍为旧Dialog实现。

2026-07-22 UI/UX A2/A3收口(未提交、未部署)

  • LG2-P1-04通过真实Browser文件选择完成客户端企业认证材料上传;PostgreSQL FileObject归属当前会话企业,MinIO对象回读93字节。复验发现并修复手机端文件名、步骤条和省市选择的卡片内裁切,五视口重新截图后文件名完整且页面无横向溢出。
  • LG2-P1-06在客户端系统日志页真实点击导出,五视口均显示5条和操作单号;独立客户端会话API再次导出7条,表头严格为时间,级别,模块,操作人,动作,资源ID,测试注入的详情/IP/供应商内部字段均未泄露。
  • LG2-P1-14在运营签名和模板审核页分别打开通过确认层,仅取消时数据库状态仍为pending且审计为0。真实API随后首次批准签名并用相同幂等键重放,两次返回同一操作单cmrvlgtrq000gakyumhm1iuiv,重放标志为true且只写一次审核。
  • 浏览器证据覆盖上传页和日志导出页五视口、签名确认层五视口截图,以及模板确认层1440×900截图和390×844 DOM尺寸测量;两端console error/warn为空。证据位于测试项目平台LG_UIUX二轮走查证据/整改_A2_A3收口_20260722/
  • 自动化通过:files、operations、review-governance 3 suites / 31 tests;前端build、API build、Prisma validate/status58条、schema最新)和git diff --check。前端仍有约1.92MB单chunk告警,项目无独立前端lint/组件/axe脚本。
  • 客户端日志列表仍展示内部详情/IP,继续归LG2-P1-07,未因导出安全而标记完成。临时数据、MinIO对象和Redis会话已清理;未触碰预发布环境,未提交、未push、未部署。

2026-07-22 工作区汇总提交与预发布发布(0f223f7f

  • 按用户授权汇总提交当前全部有效平台源码、migration、测试、依赖锁文件和项目文档,共80个文件、4959行新增和765行删除;功能提交为0f223f7f91d1bd24e7a2cc0ce6ce9ae3e3258b10feat: harden platform workflows and UI governance),已push至origin/main。按仓库约束未提交api/tsconfig.build.tsbuildinfo和任何.log;独立的outputs/phone-prefix-area-code-20260721/为号码地区表生成交付物而非平台运行源码,未纳入生产提交。
  • 发布前发现API锁文件中的Prisma 7.8开发依赖链产生6个审计漏洞,且api/package.json存在重复overrides键。已将@prisma/client@prisma/adapter-pg和Prisma CLI同步升级至7.9.0,移除过时Hono强制版本并合并override;干净npm ci --include=dev后根目录和API的npm audit --audit-level=low均为0漏洞。Prisma Client 7.9.0生成、schema validate及本地58条migration status均通过。
  • 本地发布门禁:API全量24 suites / 282 tests通过,API TypeScript build、前端TypeScript/Vite build、Gateway go test ./...、Prisma generate/validate/migrate status和git diff --check通过。Jest断言完成后仍需--forceExit结束既有异步句柄;前端仍有约1.92MB单chunk警告,继续归入后续性能整改,不虚报解决。
  • 部署前预发布PostgreSQL、运行源码和环境配置备份至/opt/cmpp-platform/backups/releases/20260722-142102。数据库备份postgresql.sql.gz为4396893字节、SHA-256 598e0b624b69c85f707a5c8f769a00fe2118f44e1491f872aa62e1f72d43890f;源码备份runtime-source.tar.gz为28537401字节、SHA-256 552633474c7888eb2c1a17902430fa385054ef7f5b5e654faf3e2934e94caec4;环境备份cmpp-platform.env为850字节、SHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三份文件均非空、权限600,数据库gzip和源码tar完整性校验通过。
  • 发布包由提交快照生成,本地与服务器SHA-256均为4aa2188b943885d73558b8e04014fd559d421981071cbcddca72ba379780478e。使用tools/deploy/production-deploy.sh完成部署,成功应用20260721150000_backfill_misattributed_delivery_receipts,预发布58条migration齐全且schema最新;脚本按Gateway在前、API在后的顺序重启并恢复运行状态。预发布.deployed-commit=0f223f7f91d1bd24e7a2cc0ce6ce9ae3e3258b10
  • 发布后cmpp-gatewaycmpp-api、Nginx、PostgreSQL、Redis(实际unit为redis)和MinIO均active12026/17890/8090/3000/9000/6379/5432监听;API/Gateway health、Redis PONG、PostgreSQL readiness均通过。两个active上游通道CH-1783566107506CH-1783566107506-COPY-MRCXAK2W均恢复为connected/currentConnections=1,Redis中7个通道权威TPS配置存在;gateway.submit.commandscmpp-gateway consumer group为pending=0、lag=0
  • 服务器本机及外部访问首页、运营登录、客户端登录和API health均返回HTTP 200,公网CMPP 8.160.169.106:17890 TCP连接成功。预发布根目录/API依赖audit均为0;部署后20分钟内API和Gateway journal error均为0API近期stderr错误匹配为0。
  • Browser真实打开预发布客户端登录页/#/client/login,页面标题为“聆界短信管理平台”,Logo、用户名、密码、图形验证码和登录按钮完整渲染,DOM非空、无框架错误层,页面console error/warn为0并取得截图。空表单登录按钮交互在Browser控制层两次超时并触发连接重置,因此本次仅将预发布页面渲染烟测记为通过,不虚报登录交互通过;未输入或传输账号密码。
  • 本次未发送或重投真实短信,未充值、审核、删除、禁用账号、改密或修改真实通道配置。预发布业务数据变更仅来自已审查并随发布执行的历史回执确定性回填migration。

2026-07-22 预发布发布中断窗口复盘

  • 本次约1小时19分钟为端到端发布作业时长,并非业务持续中断时长;旧服务在依赖安装、构建、备份和上传期间持续运行,实际服务切换集中在14:27:53附近。
  • systemd日志显示:Gateway从开始停止到重新启动约43毫秒,Nginx约126毫秒;API在14:27:53.283开始停止,Nest于14:27:54记录启动成功,API不可用窗口约1秒,按日志秒级精度保守上界小于1.72秒。
  • Nginx访问日志在14:20—14:32共记录8次请求且均为HTTP 200、无5xx;但14:27:45—14:28:10没有请求样本,因此只能确认“未观察到HTTP失败”,不能据此声称HTTP业务零影响。
  • Gateway重启会断开全部既有CMPP TCP会话。账号910887约3秒后重连;账号991405受客户端重试周期和连接名额暂未释放影响,首条可用连接约78秒后恢复,两条连接全部恢复约108秒后完成。若同样方式用于正式生产,应按受影响CMPP客户最长约1分48秒的业务中断评估,而不能只按Gateway监听端口的43毫秒计算。
  • 该方式不是零停机发布。正式生产应采用API/前端蓝绿或滚动切换、Nginx reload、Gateway双实例与连接排空、受控关闭时及时释放连接名额,以及持续探针和健康门禁后再切流。

2026-07-22 应用日发送上限与HTTP参数复制修复(未提交、未部署)

  • 根因:SmsApplication.dailyLimit原先仅保存/展示,发送链没有任何读取或拦截;HTTP开通默认值只改了前端表单,Prisma/数据库仍以cmpp为回执/上行默认投递模式,已有HTTP应用未回填;复制文本还漏了AppID和第六项“客户端自助密钥”。生产只读核查唯一已开通HTTP应用六项能力均为true,但两个投递模式均为cmpp,与现象一致。
  • 新增SmsApplicationDailyUsage(applicationId, usageDate, usedCount)及唯一索引,按北京时间自然日使用PostgreSQL条件upsert原子抢占去重后号码配额。新建应用和历史NULL默认100000;迁移同时回填发布当日已创建的短信数,避免午间升级后额外获得一整份配额。
  • 客户端/HTTP超限整批返回429和DAILY_SEND_LIMIT_EXCEEDED,不创建任务/记录/冻结;CMPP整包预留失败后每个号码仍创建可审计rejected记录与DAILY_LIMIT失败回执,不冻结或扣费。
  • HTTP Schema和后端首次开通均默认六项能力为true、两个投递模式为http;迁移仅将“HTTP已开通+对应Webhook已开启+旧模式cmpp”的历史行定向回填为http。复制文本新增AppID和客户端自助密钥能力。
  • 回归:目标SendChain/SmsConfig/OpenAPI 3 suites / 138 tests通过;API全量24 suites / 289 tests通过;API build、前端build、Gateway go test ./...、Prisma generate/validate通过。前端仍有既有1.92MB chunk警告;Jest断言完成后仍需--forceExit结束异步句柄。
  • 独立临时PostgreSQL数据库从零应用60条migration并通过status;实链并发验证上限3条时两个2条请求仅1个成功,usedCount=2;新HTTP配置六项均true且投递模式为http。临时数据库已删除,共享本地库未应用本轮migration,避免触碰另一会话同时新增的签名迁移。
  • npm run verify:phase8未通过:契约和Gateway通过,BullMQ完成15000条真实Redis消息,但本机端到端336.82 TPS低于脚本500 TPS门槛,命令链在此中止;未将环境性能不达标写成通过。
  • Browser本地页面验收未完成:应用内Browser对127.0.0.1和工作站LAN地址均连接被拒,随后浏览器连接超时重置。未使用mock、生产旧页面或伪造截图冒充修复后交互通过。

2026-07-22 短信签名完整黑括号口径统一(未提交、未部署)

  • 产品口径统一为:客户端和运营端新增、编辑签名时均填写完整中文黑括号名称,例如【某某科技】;缺少括号、英文方括号、重复括号、空括号或括号外文本均不得提交。所有列表、详情、审核、报备、模板和发送预览只显示一层完整括号。
  • 客户端移除“无需填写【】”提示,两端表单按完整格式控制提交;NestJS新增、编辑API执行相同强制校验并保存完整名称,防止绕过前端。新增migration统一修复历史非规范名称,签名API读取时也按单层格式输出。
  • 客户端发送预览改用共享签名替换函数,不再在已经带括号的数据库名称外再次拼接,避免【【签名】】。签名资料导入继续走同一后端校验,不能成为绕过入口。
  • 验证结果:SmsConfig定向1 suite / 53项、报备资料导入1 suite / 7项、API全量24 suites / 290项通过;API TypeScript build、前端TypeScript/Vite build、Prisma validate通过。本地PostgreSQL已应用第59、60条migration且schema最新;第60条签名migration另在真实PostgreSQL事务内验证测试[英文]【【重复】】分别规范化为【测试】【英文】【重复】,随后回滚临时数据。Jest仍需--forceExit结束既有异步句柄,前端仍有既有约1.92MB单chunk警告。
  • 应用内浏览器使用本地真实PostgreSQL临时企业、平台管理员和企业管理员,分别读取并计算真实算术验证码登录客户端/#/client/signatures和运营端/#/admin/enterprise-signatures。两端新增表单输入某某科技时均出现“必须填写完整中文黑括号签名”错误且提交按钮禁用,改为【某某科技】后按钮启用;未点击保存。另插入本地草稿【编辑验收签名】,客户端“修改”和运营端“编辑”弹窗均原样显示完整一层括号且提交可用,两端console error/warn均为0,并取得可见截图。
  • 浏览器验收结束后已精确删除1条临时签名、2个临时用户、1个临时企业、4条登录操作日志和2个Redis会话;复核企业、用户、签名计数均为0。本会话启动的本地API和前端预览进程已停止,未留下测试业务数据或后台进程。
  • 本轮未提交、未push、未部署;未写入预发布业务数据。工作区同时存在其他会话的应用日限额/HTTP默认配置修改,本轮仅在同一文件的签名逻辑区域增量修改并完整保留其改动。

2026-07-22 应用日限额与签名格式提交、推送及预发布发布(a09036c6

  • 合并功能提交a09036c67bd24ce7e4b9372aa24918fec9d8386ffix: enforce application limits and signature format)首次由另一会话推送时遇到Git HTTP认证失败;本次重新执行git fetchgit push origin main成功,发布前HEADorigin/main均为该提交。未提交api/tsconfig.build.tsbuildinfooutputs/;发布期间另一会话新增的api/src/send-chain/send-chain.service.spec.tsgateway/internal/inbound/server_test.go未提交修改也保持原样,未纳入本次发布快照。
  • 发布门禁:API目标SmsConfig/OpenAPI/SendChain 3 suites / 139 tests通过,API TypeScript build、前端TypeScript/Vite build、Gateway go test ./...、Prisma validate/migrate status(本地60条、schema最新)和git diff --check通过。Jest断言后仍有既有异步句柄,使用--forceExit取得明确汇总;前端仍有约1.92MB单chunk告警。
  • 迁移前只读预检:211个应用dailyLimit为空、发布日已接收短信为0;已启用HTTP配置中回执/上行仍使用cmpp的各1条;40个签名会被规范化。另发现规范化后6组同企业同名签名,但当前模型无名称唯一约束,不阻断迁移;按用户要求不继续清洗或合并历史签名。
  • 部署前PostgreSQL、运行源码和环境配置备份至/opt/cmpp-platform/backups/releases/20260722-165721。数据库备份4396340字节、SHA-256 dc4ffef70f04c800330ed8ab2b470ea6d6d1b1d4566c034bcafcc7b7c190cd9e;源码备份28609359字节、SHA-256 804bfff7a246ac73494a6195c3d9eb417203ede458722893fcdd52a3dd0425ca;环境文件850字节、SHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三份文件权限均为600,数据库gzip和源码tar完整性校验通过。
  • 发布包由a09036c6提交快照生成,本地与服务器SHA-256均为1e1409250c24cd57c1682d39ac0bb4e54d140ea3c10f26ff47ff8544136fa8d9。使用tools/deploy/production-deploy.sh完成部署,成功应用20260722170000_enforce_application_daily_limit_and_http_defaults20260722173000_normalize_sms_signature_brackets,预发布60条migration齐全;脚本按Gateway在前、API在后的顺序重启。部署命令从16:58:04至16:58:38共34秒,Gateway、API和Nginx均在16:58:35进入active.deployed-commit=a09036c67bd24ce7e4b9372aa24918fec9d8386f
  • 数据库发布后复核:应用空日限额降为0,日用量表当前0行/0条(发布日无已接收短信),目标HTTP配置的旧cmpp投递模式均降为0。49条历史签名中仍有21条不满足严格单层黑括号正则;用户明确要求忽略现有签名,本次未追加生产数据清洗、合并或删除。
  • 发布后cmpp-gatewaycmpp-api、Nginx、PostgreSQL、Redis和MinIO均active12026/17890/8090/3000/9000/6379/5432监听;API/Gateway health、Redis PONG均通过。2个active上游通道均恢复connected/currentConnections=1,Redis中7个通道权威TPS配置存在;gateway.submit.commands consumer group为pending=0、lag=0,部署后API/Gateway error journal均为0。
  • 外部首页、运营登录页、客户端登录页和API health均返回HTTP 200,公网CMPP 8.160.169.106:17890 TCP连接成功。应用内Browser两次在导航/DOM读取阶段控制超时并重置,因此只记录外部HTTP入口通过,不虚报浏览器DOM、交互或console验收通过。
  • 本次业务数据变更仅来自两条已审查migration;未发送或重投短信,未充值、审核、删除、禁用账号、改密或修改真实通道配置。

2026-07-22 CMPP日限额同步整包拒绝口径修正(55019443已发布)

  • 产品确认日额度按任务正式受理的北京时间自然日占用,待审核和定时任务计入受理日;后续审核拒绝、取消或发送失败不返还。号码基础校验不以号段库是否识别作为合法性条件,未知号段继续走全国或三网兼容通道。
  • 修正CMPP整包日限额语义:API为每个目的号码建立rejected/DAILY_LIMIT审计主记录,但返回accepted=false/result=8Gateway同步返回唯一一个非0 SUBMIT_RESP且Msg_Id为0,不建立下游会话映射、不生成SmsReceiptRecord、不创建CmppDownstreamDelivery,不冻结或扣费。
  • 新增API回归覆盖双号码整包超限、每号码审计记录及无回执/无冻结;新增Gateway真实CMPP2.0协议回归覆盖Bind后的result=8响应和不新增pending回执拉取。失败测试先在旧实现上分别暴露accepted=true和Gateway响应结构缺少业务结果码,修改后SendChain定向78项及Gateway inbound包通过。
  • 功能提交55019443c0015c65da94f0ad17ed274d77e6290afix: reject CMPP daily limit synchronously)已push至origin/main。发布前API全量24 suites / 290项、API build、前端build、Gateway go test ./...、Prisma validate/migrate status60条、schema最新)和git diff --check通过;前端仅保留既有约1.92MB单chunk告警,Jest仍需--forceExit退出既有异步句柄。
  • 部署前PostgreSQL、运行源码和环境配置备份至/opt/cmpp-platform/backups/releases/20260722-171101。数据库4396934字节、SHA-256 305f3e5a95e0b850eacc8f4c0ff016880f496c343affac339f74e1a85ba3b8e1;源码28617718字节、SHA-256 223f0058982cd484c70312c1f3e03962a59311d79bf4ea59b560323b4c561790;环境850字节、SHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三份文件权限均为600sha256sum -c、数据库gzip和源码tar完整性校验通过。
  • 发布包本地与服务器SHA-256均为191c41d068b0f418bf04ca44cb4dbd25bcac765961b7b259136102256ba3ba5c。使用tools/deploy/production-deploy.sh完成发布,无待执行migration;脚本先重启Gateway再重启API.deployed-commit=55019443c0015c65da94f0ad17ed274d77e6290a
  • 发布后cmpp-gatewaycmpp-api、Nginx、PostgreSQL、Redis和MinIO均active12026/17890/8090/3000/9000/6379/5432监听;API/Gateway health、Redis PONG、PostgreSQL readiness和60条migration状态通过。gateway.submit.commandspending=0、lag=0,7个通道TPS权威配置存在,部署后API/Gateway error journal均无记录。
  • 2条active上游通道均恢复connected/currentConnections=1。另1条disabled通道的状态行仍显示connected/1,但updatedAt=2026-07-09 03:24:26.242且本次启动无对应重连日志,确认为历史状态残留而非当前连接;5条deleted测试通道均为failed/0连接。本轮未修改或清理该历史数据。
  • 外部首页、运营登录页、客户端登录页和API health均返回HTTP 200,公网CMPP 8.160.169.106:17890 TCP连接成功。生产源码确认API下发result=8且Gateway读取业务结果码;未通过真实短信制造超限条件,未发送、重投、充值、审核或修改生产业务数据。

2026-07-22 SQL_ASCII签名UTF-8损坏修复(e28288f6已发布)

  • 预发布企业签名、报备任务/记录、待报备资料及部分模板读取接口返回500。Nginx与API stderr确认SmsSignature.findMany()等查询触发PostgreSQL 22021 invalid byte sequence for encoding UTF8: 0xe7 0xbd 0xe3,不是前端或权限问题。
  • 生产数据库编码为SQL_ASCII20260722173000_normalize_sms_signature_brackets中的中文正则字符类按字节工作,把名称末尾“网”的UTF-8最后字节0x91误当成黑括号字节删除。49条签名中准确识别2条非法UTF-8;迁移前备份证明二者原值均为【航天信息信诺网】
  • 新增补偿migration,仅当两个已确认ID及损坏hex同时匹配时恢复备份中的正确UTF-8,不覆盖之后的人工编辑;明确禁止回滚到非法字节,并补充SQL_ASCII与关联接口回归用例。
  • 本地真实SQL_ASCII临时库从零应用61条migration后插入生产同款损坏hex,补偿SQL首次执行恢复两条正确UTF-8、第二次执行保持不变,随后删除临时库;本地共享库也已应用第61条migration。API全量24 suites / 290项、API build、前端build、Gateway go test ./...、Prisma generate/validate/status和git diff --check均通过。
  • 功能提交e28288f6911da002dce39e0e5208609a40bc0e30fix: repair SQL_ASCII signature encoding)已push至origin/main。首次push遇到Git Credential Manager瞬时认证失败,原命令重试后成功;未提交api/tsconfig.build.tsbuildinfooutputs/
  • 部署前PostgreSQL、运行源码和环境配置备份至/opt/cmpp-platform/backups/releases/20260722-185147。数据库备份4398661字节、SHA-256 d0513ca2321bbd73859fd9e28d06380bda78e40383de50d919b13022fefc1976;源码备份28618928字节、SHA-256 aca65f5ac304063da476f56baaf1277a3c3487a0e1aefd6fa6f2d2dffebb87c7;环境文件850字节、SHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三份文件权限均为600,gzip、tar及sha256sum -c完整性校验通过。
  • 发布包本地与服务器SHA-256均为74bc28ad2b9f48661eba133ccddc433a2e3201c1f88808fb8970b7d7c3cf7fd8。使用tools/deploy/production-deploy.sh完成发布,成功应用20260722190000_repair_sql_ascii_signature_utf8,现有61条migration齐全且schema最新;脚本按Gateway在前、API在后的顺序重启,预发布.deployed-commit=e28288f6911da002dce39e0e5208609a40bc0e30
  • 发布后以字节级扫描复核49条签名,非法UTF-8为0;两个目标ID均精确恢复为hex e38090e888aae5a4a9e4bfa1e681afe4bfa1e8afbae7bd91e38091【航天信息信诺网】)。生产Prisma真实执行签名、报备任务、报备记录、待报备资料四类关联查询均成功,分别返回49、34、82、4条,不再触发P2039/22021。
  • API/Gateway health、外部首页、运营登录页、客户端登录页和外部API health均返回HTTP 200Redis PONGgateway.submit.commandspending=0、lag=0,7个通道TPS权威配置存在。两个active上游通道均为connected/currentConnections=1disabled通道的一条connected/1仍是2026-07-09历史状态残留,本次启动没有把它作为活动通道恢复。
  • 部署后API日志新增P2039/22021为0,Nginx中企业签名及相关报备接口新增5xx为0。应用内Browser因Chrome标签被另一Codex会话占用且控制连接超时,未完成登录态页面交互验收;本次以真实NestJS所用Prisma关联查询、PostgreSQL字节扫描和Nginx/API日志作为后端修复证据,不虚报浏览器交互通过。未发送短信,未审核、删除、充值、改密或修改其他生产业务数据。

2026-07-23 预发布运营商区分规则同步(配置变更,未提交、未部署代码)

  • 在线证据以华为云2026年2月《消息&短信》号码规则为主,并以工信部关于190/197/196/192公众移动通信网网号核发信息交叉核对。规则覆盖三大基础运营商、移动转售号段及必要的上网卡/物联网/卫星前缀;按用户明确要求将中国广电192归入中国移动路由。
  • 变更前预发布PhoneCarrierRule有30条,存在190重复、移动195仅覆盖1951—1952、电信191/193等缺失。完整PostgreSQL及原规则CSV已备份至/opt/cmpp-platform/backups/config/20260723-164357-phone-carrier-rules;数据库备份SHA-256为239c4c669d55e8ccf6bfc5458e92fab507e1af8cb928e7f4ace5cd7f53c1e6f1,规则CSV SHA-256为8e437138f0e1a526519b01c6ddc4e95ce58e1a76fb623dc2a3ab0f6616630e86,两者权限600且gzip校验通过。
  • 使用单个PostgreSQL事务锁定并原子替换规则,最终30条全部active:移动12条、联通9条、电信9条。19200000000唯一命中mobile / ^19[2578],备注明确“含中国广电192,按业务要求归中国移动”。
  • 真实管理员验证码登录成功(201),GET /api/admin/dictionaries/phone-carrier-rules?page=1&pageSize=100返回200和30条;对68个基础、转售及新号段代表号码按发送服务同款JavaScript正则验证,全部唯一命中、0个错配,随后真实登出成功。首次验证误把凭据文件的password=unchanged当作密码产生一次401,未锁定账号、未修改规则,修正为已授权密码后通过。
  • 本次只修改预发布字典配置,不改代码、不重启服务、不发送短信,也不回写历史短信运营商。号段规则反映原始码号分配;携号转网后的当前签约运营商无法只靠前缀判断,若业务要求实时识别需另接MNP/HLR能力。

2026-07-23 下游 CMPP UDH 长短信持久化重组修复(发布前验证)

  • 根因确认不是近期回归,而是既有下游入站链路从未实现重组:Gateway 将每个 CMPP Submit 的完整 MsgContent(包含 UDH)直接按 UCS2/GB18030 解码并逐片调用 NestJS,NestJS 因而把两片当成两条独立短信,控制字节污染首部签名匹配。此前台账通过的是“平台完整正文向上游拆分”和“上游 Deliver 长上行重组”,未覆盖“企业客户端已拆分的下游 Submit 重组”。
  • Gateway 新增标准 8 位 05 00 03、16 位 06 08 04 UDH 解析,校验 PkTotal/PkNumber 与 UDH 总片数/片序号一致,先剥离 UDH 再按 MsgFmt 解码,并向 NestJS 传递引用号、总片数、片序号和编码。真实 CMPP2.0 TCP 回归确认两片均获得成功 SubmitResp,API 收到的片正文不含 UDH。
  • NestJS/Prisma 新增 CmppInboundLongMessageCmppInboundLongMessageSegment 及 migration 20260723120000_add_cmpp_inbound_long_message_reassembly。分组键包含应用、账号、Src_Id、目标号码、引用号、总片数和编码;使用 PostgreSQL advisory transaction lock 与同组同片唯一索引保证并发幂等。分片齐全前不创建批次/短信,齐全后按片序合并并只创建一条完整正文记录;持久化稳定 messageId 和第一片 Sequence_Id,支持乱序、重复片、冲突拒绝、进程重启恢复及超时转 expired。
  • 本地真实 PostgreSQL 16 已应用 62 条 migrationschema 最新。事务验证成功写入2片并按序拼成 【测试】第一片第二片正文,同组同片重复索引被唯一约束拒绝,验证事务最终回滚为0条残留。真实本地 NestJS API + PostgreSQL + Redis 调用两次入站接口后,分组为 completed、持久化2片、只创建1条主记录,完整正文和第一片 Sequence_Id 均正确;未启动 Go Gateway 上游连接,未发送真实短信。
  • 新增长短信相关 API 回归5项(合并、乱序/重复/冲突、处理中断恢复、主记录已落库后的幂等恢复、超时终止)和 Gateway 回归3项(8位UDH、16位UDH、真实CMPP2.0两片转发)。API发送链83/83、API全量24 suites/295项、Gateway go test ./...、API build、前端build、Prisma generate/validate/status均通过。verify:phase8首次与本地API并发时BullMQ为438.93 TPS而失败;关闭仅由本轮启动的API后单测为909.56 TPS,完整重跑为872.43 TPS并通过。前端仅保留既有约1.92MB单chunk告警。
  • 预发布两次测试正文使用的 【深圳市合正物业服务有限公司】 在该应用签名库中不存在;本次修复能消除UDH污染并完整重组,但不会绕过签名审核。部署后复测前需先按正常产品流程为应用配置并审核该签名/模板,或改用应用已有的审核通过签名。数据库升级只新增两张重组表和外键/索引;如必须回滚,应先停止新版本 API/Gateway,再删除子表和父表,未完成分片审计会丢失,既有短信主记录不受影响。
  • 发布前功能代码、迁移、回归测试和文档已完成并获用户授权提交、推送和部署;本节先保留发布前验证证据,实际提交、备份、migration、服务重启和发布后验收结果在部署完成后追加记录。

2026-07-23 下游 CMPP UDH 长短信持久化重组发布(b29576fc

  • 功能提交 b29576fcd118bea04416be0c9fc1bc2a4213d830fix: reassemble inbound CMPP long messages)已推送至 origin/main。首次 git push 遇到远端 HTTP Failed to authenticate user,在不改写提交和工作区的情况下使用原命令重试成功;提交未包含 api/tsconfig.build.tsbuildinfooutputs/ 和未关联的 docs/project-daily-log.md
  • 发布门禁通过:API 全量 24 suites / 295 tests、API TypeScript build、Gateway go test ./...、前端 TypeScript/Vite build、Prisma generate/validate/status、git diff --checknpm run verify:phase8 均成功;BullMQ 端到端 890.61 TPS,前端仅保留既有约 1.92 MB 单 chunk 告警。一次从仓库根目录直接调用 Prisma 因工作目录错误找不到 schema,随后从 api 目录使用本地可执行文件重跑 generate/validate/status 全部通过,不将错误命令计为验证通过。
  • 部署前 PostgreSQL、当前运行源码和环境配置备份至 /opt/cmpp-platform/backups/releases/20260723-210601。数据库 4409540 字节、SHA-256 c2af72f670f4352723c9ff9e259d52316ed63fe15b28d8aa5b705ed7cfd18dec;源码 28610639 字节、SHA-256 61679bdb6efb236d1739c2d1780e010bfb38e7e8d5fb07b52e56a555f8e4a3c2;环境文件 850 字节、SHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三份文件权限为 600,数据库 gzip、源码 tar 和 sha256sum -c 完整性校验通过。
  • 发布包由 b29576fc Git 快照生成,本地与服务器 SHA-256 均为 6d8a70bee437d6583e2e719ee9c17f8f981a5775d8ed9a7e9cbd96ebd4f7874b。使用 tools/deploy/production-deploy.sh 完成发布,依赖审计为 0 漏洞,成功应用 20260723120000_add_cmpp_inbound_long_message_reassembly,预发布现有 62 条 migration 齐全;CmppInboundLongMessageCmppInboundLongMessageSegment 两张表存在,发布后尚无长短信分组数据。.deployed-commit=b29576fcd118bea04416be0c9fc1bc2a4213d830
  • systemd 日志确认 21:07:16 先停止、启动 cmpp-gateway,随后停止、启动 cmpp-api。Gateway、API、Nginx、PostgreSQL、Redis 和 MinIO 实际运行,12026/17890/8090/3000/6379/5432/9000 均监听;本地 API/Gateway health 返回 okRedis PONGgateway.submit.commandspending=0、lag=010 个 rate:gateway:channel:config:* TPS 权威配置键存在,Prisma migration status 为最新。
  • 5 条 active 上游通道在重启后的真实结果为 3 条 connected/currentConnections=1CH-1784797581833 及其复制通道 CH-1784797581833-COPY-MRXBBARL 被上游明确返回 connect response status: auth failed。发布前数据库显示 5/5 connected 属于重启前状态,真实重连暴露了这两条通道的凭据/上游鉴权问题;本次长短信代码未修改上游通道鉴权,未擅自改密或停用通道,需由运营确认凭据后另行恢复。
  • 外部首页、运营登录页、客户端登录页和 API health 均返回 HTTP 200,公网 8.160.169.106:17890 TCP 连接成功。部署后 API/Gateway 未出现 Prisma、panic、fatal、Unhandled 或 Exception 程序错误,Nginx 仅有历史响应缓冲警告和本次正常重启 notice。未发送真实短信、未创建生产测试短信记录;由于目标测试正文的 【深圳市合正物业服务有限公司】 尚未配置为该应用的审核通过签名,仍需先完成签名/模板配置,再由用户进行真实企业 CMPP 长短信复测。

2026-07-23 供应商CMPP主动心跳与自动重连(本地未提交)

  • 现状根因:活动通道仅在创建、启用和API启动时连接一次;Gateway在首次失败后删除连接池,运行中断链只上报状态且不重新拨号。供应商出站连接只响应对端ACTIVE_TEST,不主动检测静默半开连接。停用/删除只修改数据库状态,没有关闭Gateway连接;修改连接参数也不会立即替换旧池。
  • Gateway新增每通道连接监督器、主动ACTIVE_TEST、按Sequence响应跟踪、连续未响应断链、网络退避和鉴权慢速重试。断链读循环立即退出,短信、回执响应和心跳共用串行写锁;连接监督器持续补足期望连接数。新增DisconnectChannel控制接口,停用/删除会取消监督器并关闭连接池。
  • API新增30秒供应商连接协调任务,以Redis租约避免多实例重复下发;活动通道连接不足、心跳陈旧或失败到期时重新下发,非活动通道存在活动/连接中状态时强制断开。修改连接相关配置立即重建连接,BullMQ连接任务使用每次尝试唯一ID并保留受控历史。
  • Prisma新增lastReconnectAttemptAtnextReconnectAtlastErrorCategorystatus + nextReconnectAt索引,migration为20260723220000_add_upstream_reconnect_schedule;另以20260723225000_enforce_supplier_connection_state_identity清理潜在重复供应商状态并增加applicationId IS NULL部分唯一索引,P2002并发创建会复用既有状态。回滚需先停止新版API/Gateway,先删除部分唯一索引,再删除调度索引和三列后启动旧版本;回滚只丢失调度可观测字段,不影响短信、提交和回执记录。
  • 运营端通道表单新增心跳间隔和失败阈值,连接日志展示重连次数和下次重连时间。默认30秒/3次,可按供应商通道覆盖。
  • 当前验证:Gateway定向及go test ./...通过,并含真实CMPP服务端闭环“首次拒绝连接→端口恢复→自动重连→平台主动心跳收到响应”;合并并行工作区后API通道定向38项、API全量24 suites / 304项均以--no-cache通过,API TypeScript build、前端TypeScript/Vite build、Prisma generate/validate通过。本地升级前供应商重复状态组为0,两条自动重连migration均已应用;当前合并工作区66条migration全部应用且status最新。一次将send-chain.service.spec.ts与通道套件联合运行在184.8秒超时且无汇总,随后在Redis PONG环境取得明确全量通过汇总;Gateway race检测因本机CGO未启用而未执行。
  • 本地真实协调验证使用临时通道贯通Prisma/PostgreSQL、Redis租约、BullMQ和HTTP控制请求,确认failed活动通道写为connecting并发送ConnectChannel/automatic_reconnect,改为disabled后写为disconnected/0连接并发送DisconnectChannel/inactive_channel_reconcile,Redis租约释放。首次执行还暴露BullMQ禁止含冒号的jobId,修正为合法唯一ID后复测通过。协调器同时命中两条既有本地陈旧活动通道;已依据验证前操作日志精确恢复二者为原failed/0/connect_timeout状态,删除3条本轮日志和2个本轮队列任务,临时通道、状态和日志也已清理。
  • npm run verify:phase8中的Gateway和契约阶段通过,但BullMQ性能阶段两次分别为284.16和376.52 TPS,低于500 TPS门槛,因此完整phase8仍记为环境性能失败而非通过;本轮功能正确性不依赖降低该门槛。
  • 本地前端预览可加载且无框架错误覆盖层,但访问运营端通道页因本地API未启动跳转登录页,验证码接口返回502;按安全规则未绕过验证码、未提交浏览器中已有凭据,因此新增心跳字段和连接日志的登录后页面交互验收仍未完成。预览进程及浏览器测试页已关闭。
  • 本轮未提交、未push、未部署,也未修改预发布通道或发送真实短信。生产/预发布仍运行旧版本,不具备本节新增自动重连能力。

2026-07-23 通道、应用、详单与报表整改(未提交、未部署)

  • 已实现:新建通道默认端口 7890、协议强制 CMPP、业务代码 serviceId 默认 SMS;短信测试弹窗白色顶部栏。
  • 已实现:短信详情展示发送号码,分片审计改为响应式卡片;短信记录列表压缩间距并限制长内容为两行。
  • 已实现:企业应用任务号码默认上限 10000;列表操作换行、客户连接状态改名、未开通参数按钮禁用并区分颜色、CMPP 参数弹窗移除冗余摘要框。
  • 已实现:安全控制三个真实 API 默认和显式 deleted 查询均排除逻辑删除数据;添加/编辑二级路由保持所属菜单选中。
  • 已实现:三张日报表及导出增加提交数、未知数,使用 billingUnits 统计长短信分片,并从发送数中排除平台拦截。
  • 已实现:企业认证审核隐藏申请单号、短信审核隐藏任务编号、模板审核隐藏审核编号。
  • 自动化验证:prisma validate 通过;相关 4 个 Jest 套件 108/108 通过;API build 通过;前端 TypeScript/Vite build 通过;git diff --check 通过。
  • 真实本地链路验证:本地 PostgreSQL 已应用并核对全部 66 条 migrationprisma migrate status 返回 schema up to date;使用真实登录/API 验证安全控制三个列表即使显式传入 status=deleted 也不返回已删除数据;重新生成 2026-06-30 至 2026-07-03 报表后,利润、对账、质量报表均满足 发送数 = 未知数 + 成功数 + 失败数提交数 >= 发送数,三个真实报表 API 均返回新增字段。
  • 浏览器验收:使用真实本地 API/PostgreSQL/Redis 页面完成 1440×900、1366×768、768×1024、390×844、375×667 验收。短信记录详情展示发送号码且弹窗无横向溢出;企业应用操作区换行、客户连接状态表头、接口参数按钮状态色及 CMPP 参数精简均生效;新增应用默认每任务 10000 个号码;三个报表新增提交数和未知数;三个审核页面不再展示内部编号;新增应用深链保持“企业应用”菜单选中。
  • 验收边界:本地数据库暂无包含分片审计明细的短信记录,因此已验证真实空状态和各视口无横向溢出,分片卡片的有数据视觉仍需在存在真实分片记录的环境补验。当前修改保持未提交、未推送、未部署。

2026-07-24 合并发布前门禁与 TPS 隔离复测

  • 本轮按用户授权合并供应商 CMPP 主动心跳/自动重连、通道与应用整改、详单与报表口径及全部并行工作区代码。origin/main 与本地基线提交 2f781ebb8af656bdb2a0395fa742538961febf21 一致,无远端新提交需要合并;api/tsconfig.build.tsbuildinfooutputs/ 按发布规则排除。
  • 发布前 API 全量 24 suites / 304 tests、Gateway go test ./...go vet ./...、API build、前端 TypeScript/Vite build、Prisma generate/validate/status、git diff --check均通过;本地 PostgreSQL 共 66 条 migration 且 schema up to date。
  • 依赖审计发现新公告:前端 react-router-dom/react-router 7.17.0 存在中危开放重定向等问题,升级至 7.18.1API 的 Prisma CLI 间接依赖 find-my-way 9.6.0 存在高危 HTTP/2 DDoS 问题,以兼容覆盖固定为 9.7.0。升级后根项目与 API npm audit 均为 0 漏洞,构建和 Prisma 命令复测通过。
  • 本机 3000 端口存在其他会话自 2026-07-23 23:02 起运行的 API 进程,若直接使用共享 Redis 压测会与业务服务争用事件循环、CPU 和 Redis 连接。为保留该会话进程并消除队列干扰,本轮在独立临时 Redis 6389 上运行完整 npm run verify:phase815000 条消息入队 3679.70 TPS,提交结果与回执完整闭环 549.52 TPS,达到 500 TPS 门槛;临时 Redis 已停止。
  • 预发布部署前只读基线:.deployed-commit=b29576fcd118bea04416be0c9fc1bc2a4213d830,服务器 4 核、7499MB 内存、可用内存 6519MB、负载 0Gateway/API/Nginx/PostgreSQL/MinIO 正常,Redis PONG,发送 Worker 并发 50gateway.submit.commandspending=0、lag=0。实际发布、备份、迁移、服务重启和预发布 TPS 结果待部署后补记。

2026-07-24 供应商连接恢复、运营整改与安全依赖合并发布(afd3c960

  • 合并提交 afd3c960709b1660c18d028499c811321983cb22feat: improve channel resilience and operations)包含 43 个文件、1969 行新增和 299 行删除,已推送至 origin/main。第一次 push 仍遇到 Git HTTP 鉴权失败,未改写提交或 remote,直接重试后成功;api/tsconfig.build.tsbuildinfooutputs/ 未纳入提交。
  • 部署前 PostgreSQL、运行源码和环境配置备份至 /opt/cmpp-platform/backups/releases/20260724-081857。数据库备份 4414185 字节、SHA-256 e69e1ea4c40871d2b213783cabe581f4f8697cac7c3d6e4fd62696508ad6a6e1;源码备份 28621409 字节、SHA-256 59d93f67be13d92d677b70ba6e0ee4b49797d7c1068304a548562a95e55defbc;环境文件 850 字节、SHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三份文件权限均为 600,数据库 gzip、源码 tar 和 sha256sum -c 校验通过。
  • 发布包由 afd3c960 Git 快照生成,本地及服务器 SHA-256 均为 a721b60750ff891ed9c43a203c2f82c113337f1b3ad34be5938705d643e39a59,大小 1657178 字节。服务器未安装 rsync,首次同步在覆盖源码前安全停止,运行目录和服务未改变;随后按已核对的 Git 顶层路径精确替换源码,保留 backups/node_modules/dist/logs/.deployed-commit 等运行数据,再使用 tools/deploy/production-deploy.sh 发布。
  • 发布成功应用 20260723220000_add_upstream_reconnect_schedule20260723223000_default_application_task_phone_limit20260723224000_add_report_submission_unknown_units20260723225000_enforce_supplier_connection_state_identity,预发布 66 条 migration 全部应用且 schema up to date。部署脚本依次重启 Gateway 和 API.deployed-commit=afd3c960709b1660c18d028499c811321983cb22;根项目和 API 生产机 npm audit 均为 0 漏洞。
  • Gateway、API、Nginx、PostgreSQL、Redis 和 MinIO 运行正常,12026/17890/8090/3000/6379/5432/9000 监听;本机 API/Gateway health、Redis PONG、公网页面、运营登录入口、客户端登录入口及 API health 均为 HTTP 200,公网 CMPP 17890 TCP 可连接。应用内浏览器连续两次在登录页加载阶段控制超时,因此不虚报 DOM、控制台或登录后页面验收。
  • 5 条 active 供应商通道均恢复为 connected/currentConnections=1/desiredConnections=1,主动心跳持续刷新且无 lastError/lastErrorCategory;禁用通道为 disconnected。发布后 API/Gateway 的 panic、fatal、unhandled、exception、error 匹配均为 0gateway.submit.commands 保持 pending=0、lag=0,压测专用 BullMQ 键清理后为 0。
  • 预发布在真实 API/Gateway 保持运行的条件下,使用不触碰业务 Stream、不访问供应商且最终清理的专用 BullMQ 队列连续执行 3 轮 15000 条测试:完整提交结果与回执闭环分别为 3570.33、3650.92、3587.31 TPS,平均 3602.85 TPS;入队平均 18781.28 TPS。该指标只表示 Redis/BullMQ 与 Node Worker 的内部队列能力,不包含 Prisma 业务事务、计费、路由或真实 CMPP 网络。
  • 既往 284.16、376.52、438.93 TPS 的下降主要是测试环境争用而非已证实的代码回归:本机 3000 端口有另一会话从 2026-07-23 23:02 起运行的 API,压测与其争用 Redis 和 CPU;此前停止 API 后曾恢复至约 872—910 TPS。本轮未终止其他会话进程,改用独立 Redis 后完整 Phase 8 为 549.52 TPS并通过。预发布同一代码三轮约 3603 TPS且方差很小,进一步说明旧低值不能作为平台容量结论。
  • 当前真实发送配置的上限不是 3603 TPS:5 条 active 通道各配置 100 TPSGateway 总配置上限为 500 TPS;每条通道 1 个连接、窗口 16API Send Worker 并发 50。真实持续吞吐还受供应商授权 TPS、网络往返、回执速度、数据库和计费事务影响,因此当前预发布应按“内部队列约 3600 TPS、配置发送上限 500 TPS、真实供应商持续能力仍需协议测试环境或供应商配合压测”理解。本次未发送真实短信、未修改生产业务数据。

2026-07-24 回执缺失复核与通讯交互日志(本地未提交、未部署)

  • 预发布只读复核确认当前仍部署afd3c960709b1660c18d028499c811321983cb2213127620092今日两次提交经“赛邮行业-王斯评中转”获得上游Msg_Id后停留submitted;该通道最后一条回执为2026-07-21 17:39:58(北京时间)。18821203795今日09:26“富泷物业-移动”测试提交上游Msg_Id 7360250353450475545分32秒抓包期间只有SubmitResp和心跳,没有供应商DELIVER。
  • 回执链路并非全局失效:同一“富泷物业-移动”通道在7月23 17:02收到DELIVRD,在本次afd3c960部署并重连后仍于7月24 08:49收到UT:0010失败回执;其他通道7月23、24也有回执落库。因此“7月24心跳/重连代码导致所有回执不能处理”与事实不符。Gateway的handleDeliver核心解析、匹配和API转发自7月8/9以来未改;最强证据仍指向特定提交或特定供应商账号未下发DELIVER,赛邮账号则需重点核查重启后的回执会话绑定。
  • 新增独立ProtocolInteractionLog及migration 20260724113000_add_protocol_interaction_logs,记录CMPP/HTTP业务交互的协议、方向、事件、状态、消息/请求标识、脱敏手机号、结果码、耗时和安全详情。默认500ms/100条批量异步写入、10000条缓冲上限和30天保留;不逐包记录心跳,不保存正文、密码、密钥、Token、鉴权签名或完整请求体。
  • NestJS Gateway事件入口记录收到、成功和失败;公开HTTP发送记录受理/失败;HTTP Webhook记录成功、重试或失败。Go Gateway对DELIVER回执解包失败、上行解码失败、收到事件及转发API结果输出结构化日志,消除原先静默丢失盲点。
  • 运营端系统日志新增“通讯交互日志”页签,支持协议、方向、事件、结果、关键字和时间筛选,分页展示并提供安全详情弹窗;手机号脱敏说明可见,详情操作列固定。
  • 本地真实PostgreSQL已应用67条migration并为最新。使用新建的本地平台管理员、真实算术验证码和真实NestJS API提交无效CMPP认证,接口按预期返回400,查询API从PostgreSQL读到同一connect事件的receivedfailed两条记录,失败耗时17ms;未发送短信。
  • 自动化验证已通过:API全量25 suites / 306 tests(含通讯日志脱敏/过滤和公开HTTP回归)、Prisma generate/validate、API TypeScript build、前端TypeScript/Vite build、Gateway go test ./...。全量Jest使用--forceExit结束并保留既有异步句柄提示;前端仍有既有约1.93MB单chunk/578.69KB gzip警告。
  • 浏览器使用真实本地账号和验证码登录运营端,两个日志页签切换、真实数据表、筛选控件、分页和详情入口可见;桌面控制台0条error/warn,截图确认页面正常。最终构建在390×844和375×667复验均无页面级横向溢出,详情操作区分别完整位于x=18..372x=18..357,控制台均为0条error/warn;截图保存在outputs/protocol-interaction-logs/
  • 当前改动保持未提交、未推送、未部署。预发布尚无新通讯日志表和页面,后续发布前必须执行备份、migration、Gateway先于API重启及发布后真实回执链路观察。

2026-07-24 通讯交互日志预发布发布(0bfeb083

  • 功能提交0bfeb0839ee6b67611e13796f46c19fc05b88de9feat: add protocol interaction observability)已推送至origin/main。首次推送被内部Git服务以Failed to authenticate user拒绝,第二次因网络超时且远端未更新,第三次重试成功;提交未包含api/tsconfig.build.tsbuildinfooutputs/
  • 发布门禁通过:API全量25 suites / 306 tests、API TypeScript build、前端TypeScript/Vite build、Gateway go test ./...go vet ./...、Prisma generate/validate/status、git diff --check。本机根项目审计为0漏洞;本机API审计因npm Registry TLS建连失败未取得结果,预发布部署机npm ci随后对根项目59个包和API 717个包审计均为0漏洞。
  • 部署前PostgreSQL、运行源码和环境配置备份至/opt/cmpp-platform/backups/releases/20260724-105310。数据库备份4422054字节、SHA-256 bb48d3f2fcd4b291398700e66db6078130b36c519e06de007095e23f52ed7618;源码备份28656320字节、SHA-256 11085039b8f305883ec8082a9a45ff69f3f65919ad09bbe7a29f4ef6631f2be2;环境文件850字节、SHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三份文件权限均为600,数据库gzip、源码tar和sha256sum -c全部通过。
  • 发布包由0bfeb083精确Git快照生成,大小1667341字节,本地与服务器SHA-256均为c3db81b662167fa23a46cee65828265d94e89057e8234a9b97443daf4d86748b,tar完整性通过。精确替换运行源码时保留backups/node_modules/dist/logs/.deployed-commit,随后使用tools/deploy/production-deploy.sh完成发布。
  • 标准脚本成功应用20260724113000_add_protocol_interaction_logs,预发布67条migration全部齐全且schema最新;前端、API和Gateway构建成功,脚本明确先重启Gateway、再重启API,最终.deployed-commit=0bfeb0839ee6b67611e13796f46c19fc05b88de9
  • API、Gateway、Nginx、PostgreSQL、Redis和MinIO实际运行;12026/17890/8090/3000/6379/5432/9000监听,API/Gateway health为okRedis PONG。gateway.submit.commands消费者1、pending=0lag=010个rate:gateway:channel:config:* TPS配置键存在。
  • Gateway重启后5条启用上游通道中3条立即连接,“富泷物业-联通/电信”共享账号C59748首次被供应商返回auth failed;自动重连按nextReconnectAt=11:00:58执行后两条均恢复。最终5/5通道全部connected/currentConnections=1/desiredConnections=1,最近心跳持续刷新,lastErrornextReconnectAt清空。
  • 公网首页、运营登录、客户端登录和API health均HTTP 200,公网CMPP 17890 TCP连接成功。真实运营账号通过算术验证码登录,在“系统日志→通讯交互日志”看到预发布CMPP连接的received/success事件、耗时和固定详情列;浏览器控制台0条error/warn。
  • 发布后API/Gateway日志未出现panic、fatal、unhandled、exception、通讯日志批量写入失败、回执解包失败或API转发失败;Nginx无error/crit/emerg。未发送真实短信、未充值、未审核、未删除或修改业务对象。

2026-07-24 通讯日志方向与重复记录修正(本地未提交、未部署)

  • 复核预发布号码18821203795对应消息MSG-TEST-1784863949078-b28e828d确认:原页面四条记录全部显示“通道→平台”,不是四个完整协议报文,而是仅采集了Gateway转入NestJS的CMPP_SUBMIT_RESPCMPP_DELIVER,并把每个报文各拆成received/success两行;真实下行CMPP_SUBMITCMPP_DELIVER_RESP此前未采集,因此箭头虽符合现有事件入口方向,但不足以表达完整交互并造成重复观感。
  • 改为“一条数据库记录对应一个真实业务报文”:NestJS不再为同一入站报文分别写receivedsuccess,只落最终成功或失败结果;Go Gateway在真实SendReqPkt(CMPP_SUBMIT)SendRspPkt(CMPP_DELIVER_RESP)写包完成后异步上报平台→通道事件。正常短短信完整成功闭环将显示CMPP_SUBMIT → CMPP_SUBMIT_RESP → CMPP_DELIVER → CMPP_DELIVER_RESP四条真实报文及实际传输方向;历史received行保留并标记为历史,不修改既有预发布数据。
  • Gateway遥测使用独立goroutine和既有HTTP超时,不阻塞发送/回执读循环;API仅接受cmpp + platform_to_channel + submit/deliver_resp + success/failed白名单事件,不接收正文、密码或密钥。
  • 本地使用真实NestJS API、真实算术验证码管理员会话和真实PostgreSQL写入两条安全的合成出站协议事件(未发送短信),再从运营端查询MSG-DIRECTION-SMOKE,页面正确显示“平台→通道 / CMPP_SUBMIT / 已发送”和“平台→通道 / CMPP_DELIVER_RESP / 已发送”;浏览器控制台0条error/warn。
  • 自动化验证:新增Controller单元测试覆盖入站单报文单记录和Gateway白名单,新增Go测试覆盖出站遥测payload;API全量、API/前端构建、Prisma validate、Gateway全量测试及git diff --check结果见本次会话最终记录。
  • 当前修改保持未提交、未推送、未部署;预发布仍运行0bfeb0839ee6b67611e13796f46c19fc05b88de9,发布前不得把本地验证结果误认为预发布已生效。

2026-07-24 跨连接回执、长短信聚合与通讯日志闭环修复(发布前)

  • 对号码13127620092的预发布只读证据确认:两分片均已由供应商受理,第二片回执从同账号复制通道连接返回。Gateway内存映射按物理连接隔离,未找到原提交后上报了receipt-736070230367350788和当前连接通道;NestJS又要求channelId + gatewayMessageId严格一致,最终通讯日志显示SMS message record not found。首片DELIVRD同时提前把主记录改成delivered,没有等待第二片,是独立的长短信聚合缺陷。
  • 回执匹配增加分片审计路径,并把“同供应商”固定为账号、Gateway主机、端口、协议和CMPP版本全部一致。只有gatewayMessageId + DestTerminalId在该供应商范围内唯一时才允许跨物理连接认领;回执、幂等键和主记录仍归属原提交逻辑通道。不同供应商或候选不唯一继续拒绝,避免串单。
  • 长短信每片回执先写SmsMessageSegmentAudit。部分成功时主记录保持submitted且不向企业应用投递最终回执;全部分片成功后才聚合为delivered并投递一次。任一明确失败进入既有最终失败/补发路径,重复回执继续由逻辑通道回执键幂等。
  • 通讯日志改为一条真实业务报文一条记录:供应商长短信每片真实SUBMIT/SUBMIT_RESP分别采集,内部submit-result聚合回调不重复落协议日志;Gateway补充供应商SUBMITSUBMIT_RESPDELIVER_RESP和企业应用SUBMIT_RESP出入方向。运营端方向名称统一为“企业应用→平台、平台→供应商通道、供应商通道→平台、平台→企业应用”,回执成功处理后用真实主消息ID替换临时receipt-*标识。
  • 新增回归覆盖:同供应商副连接唯一匹配、不同供应商拒绝、两分片未齐不提前送达、全部到齐一次聚合、内部回调不重复记录、入站服务真实SubmitResp遥测及安全白名单。API定向2 suites/90项、API全量26 suites/313项、Gateway全量go test ./...go vet ./...、API/前端build、Prisma generate/validate/status(本地67条migration最新)、git diff --check均通过。
  • 使用当前构建启动独立本地NestJS API,连接真实PostgreSQL和Redis执行tools/smoke/receipt-cross-connection-smoke.mjs:第二片从副连接进入后回执行的逻辑通道为原通道、主记录保持submitted;第一片补齐后主记录为delivered,恰好2条回执和2个已送达分片,脚本最终清理全部合成业务数据。
  • verify:phase8首次使用共享Redis且本机已有API争用时为373.05 TPS,低于500阈值,明确记为失败;改用独立临时Redis完整重跑为764.69 TPS并通过,临时Redis随后停止。前端仅保留既有约1.93MB单chunk警告。
  • 本次不新增Prisma模型或migration。发布后仍需只读确认服务、67条migration、Redis Stream、5条供应商通道重连、通讯日志新方向和近期错误;未经单独授权不发送真实短信,也不改写13127620092历史业务记录。

2026-07-24 跨连接回执、长短信聚合与通讯日志闭环发布(ca12f14b

  • 功能提交ca12f14b0007ee75f727d18e66791a669838b66efix: reconcile shared-channel receipts and protocol logs)已推送至origin/main,首次推送即成功。提交包含另一会话留下的通讯日志方向/去重改动及本轮回执聚合修复;未提交api/tsconfig.build.tsbuildinfooutputs/
  • 部署前备份位于/opt/cmpp-platform/backups/releases/20260724-125251PostgreSQL gzip 4426218字节、SHA-256 0ae8714a29f753e4d313179e2471f6bff15d1d7dc996ef57d7052bb7ddd8a61d;运行源码tar.gz 28655559字节、SHA-256 40065d00c72273771abf63b430069332351586b02ac2462345eca045997a838c;环境文件850字节、SHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三份文件权限均为600,gzip、tar和sha256sum -c全部通过。
  • 精确Git归档大小1678722字节,本机与服务器SHA-256均为ba9dc5f2f823eea810e2ef89798ae55e90f832e2e50a99d50295064eea4a31f6,tar完整性通过。运行目录以该归档替换并保留backups/node_modules/api/node_modules/dist/logs/.deployed-commit;部署前目录额外保留在/opt/cmpp-platform.previous-20260724-125251作为短期恢复副本。
  • tools/deploy/production-deploy.sh成功完成依赖安装、Prisma generate、migration deploy、前端/API/Gateway构建,并明确先重启Gateway、再重启API。根项目59个包和API 717个包审计均为0漏洞;67条migration全部齐全,无待应用migration.deployed-commit=ca12f14b0007ee75f727d18e66791a669838b66e
  • Gateway、API、Nginx、PostgreSQL、Redis和MinIO均active12026/17890/8090/3000/6379/5432/9000监听,API/Gateway health为okRedis PONG。gateway.submit.commands消费者1、pending=0lag=010个通道TPS配置键存在。
  • Gateway重启后5条活动供应商通道有4条立即在线,“富泷物业-联通”首次鉴权失败并按数据库nextReconnectAt=2026-07-24 12:59:31+08自动慢重试;到13:00只读复核时5/5均为connected/currentConnections=1/desiredConnections=1,最近心跳持续刷新、nextReconnectAtlastError清空。
  • 公网首页、运营登录、客户端登录和API health均HTTP 200,公网CMPP 17890 TCP连接成功。真实浏览器加载运营端登录页,标题正确、页面无横向溢出、控制台0条业务error/warn;因图形验证码保护,本轮未绕过登录,登录后通讯日志页面仍需下一次人工登录结合真实短信复测。
  • 发布后API/Gateway日志未出现panic、fatal、unhandled、exception、通讯遥测失败或SMS message record not found。本次未发送真实短信、未修改或回填13127620092历史业务数据;跨连接真实供应商回执和长短信两片最终聚合仍需下一次授权测试短信或自然业务回执验证。

2026-07-24 运营端账户充值回执(本地未提交、未部署)

  • 运营端充值记录每行新增“查看回执”操作,弹窗直接使用真实RechargeOrder、企业信息及订单关联的balanceAfterCents,据此计算入账前余额;历史记录缺少可追溯余额时显示-,不使用当前账户余额或前端假数据补齐。
  • 回执左上只展示系统现有/logo/logo1.png真实Logo;展示入账状态、本次金额、企业名称和编码、订单号、入账时间、前后余额、入账方式与备注,适合客户截图留存。
  • “本次充值金额”采用实际精度:整数不显示小数,存在小数时移除末尾无效零;该阶段前后余额曾固定显示四位,现已随 2026-08-12 统一金额样式调整为最多四位并裁剪末尾无意义的0。正数显示“已入账”,负数冲正显示“已冲正”。
  • 金额边界验证结果:10000.0000 → 10,00010000.2500 → 10,000.2510000.0001 → 10,000.0001、负数冲正-123.4500 → 123.45,符合主金额按实际精度展示口径。
  • 使用Node.js v24.14.0执行前端TypeScript和Vite生产构建通过,保留既有约1.93MB单chunk/579.51KB gzip警告;git diff --check通过。首次由系统旧Node执行时Vite不支持??=且错误返回0,已明确排除,未将其计为通过。
  • 浏览器加载真实本地前端/API后进入运营登录页,页面标题正确、控制台0条error/warn;由于当前浏览器无有效会话且存在图形验证码,本轮未绕过验证码,登录后的“查看回执”点击与视觉验收仍需人工登录后补测。
  • 本轮按要求保持未提交、未推送、未部署;预发布仍运行既有版本,不包含充值回执功能。

2026-07-24 长短信失败终态、自动双通道投递与企业侧通讯日志(发布前)

  • 预发布只读复核号码18821203795的消息MSG-e4ded553-8f08-4f7d-85ae-06a30b163e86:主记录保存首片上游消息号736078096474128384,第二片736078096490905600收到undelivered/YL:1014,首片无回执。原逻辑只按主记录首片消息号查提交记录,导致第二片虽写入分片审计,但被误判为非当前尝试,主记录卡在submitted且未建立最终下游投递。
  • 修复为优先通过SmsMessageSegmentAudit.gatewayMessageId取得该分片所属submitRecordId/submitId/channelId,再执行当前尝试判断。长短信任一分片明确失败即可沿既有补发、退款和最终回执链路使整条短信终态化,不等待缺失分片;供应商原始非成功码(包括YL:1014)保持原样,不增加码表。
  • HTTP和CMPP投递改为按接口能力自动派生:CMPP开通即建CMPP下游投递,HTTP开通且对应Webhook地址有效即建HTTP事件,两者同时开通时双投。运营端不再提供回执/上行投递方式选择,HTTP关闭时仍显示并允许维护两个Webhook地址,保存空地址会删除对应端点并停止该类HTTP推送。
  • Gateway补充企业侧真实CMPP_DELIVER发送成功/失败以及CMPP_DELIVER_RESP接收结果通讯日志,API白名单允许platform_to_client + deliver_receipt/deliver_uplinkclient_to_platform + deliver_resp。通讯日志只描述真实协议报文;CmppDownstreamDelivery继续保存排队、发送、ACK、失败和重试业务状态,两者不合并。
  • 新增migration20260724143000_derive_application_delivery_modes,按当前CMPP/HTTP开通状态回填历史配置的派生模式,避免旧人工模式继续影响展示或参数复制。
  • 已完成定向回归:OpenAPI、短信配置和Gateway事件3 suites/67项通过;SendChain新增长短信非首片失败、仅HTTP投递和CMPP关闭3项通过;Gateway inbound全量通过并覆盖企业侧DELIVER/DELIVER_RESP日志。另一个会话的运营端账户充值回执源码和文档已一并纳入本发布分支,原工作区未覆盖。

2026-07-24 通道今日质量、看板签名统计与日期通道占比(本地未提交、未部署)

  • 根因确认:运营端通道列表的mapApiChannel把今日总数、成功/未知/失败数量和比例全部固定为0,页面从未请求后端质量数据;预发布只读SQL确认当天实际已有3个通道共10条accepted提交,并非数据库无数据。
  • 新增只读GET /api/admin/operations/send-quality?date=YYYY-MM-DD,按北京时间单日从真实SmsSubmitRecord/SmsReceiptRecord聚合通道提交质量,并从真实SmsMessageRecord/SmsSignature/Tenant聚合签名发送质量;日期无效返回受控400。
  • 通道列表接入当天真实质量;运营看板移除通道运行表格、在线连接指标和平台连接健康度,恢复设计基线2f3c274a中的“不含引流/含引流”双签名统计结构,展示发送总数、成功、未知、失败、成功率和平均到达时长。
  • 数据统计的通道占比默认北京时间当天,支持选择单个历史日期查询,图例使用真实通道名称而非内部ID。
  • 预发布只读核验当天事实:富泷物业-移动5条、赛邮行业-王斯评中转4条、富泷物业-联通1条;另有4个签名存在当天发送记录,证明原页面全0为前端硬编码缺陷。
  • Node.js v24.14.0下API Operations定向1 suite / 21项通过;整合远端最新回执链路后,API全量26 suites / 319项、API TypeScript build、前端TypeScript/Vite build、Gateway go test ./...go vet ./...、Prisma generate/validate及git diff --check通过;前端保留既有约1.93MB单chunk/580.26KB gzip警告,Jest仍用--forceExit结束既有异步句柄。
  • 本机PostgreSQL未监听,真实服务类本地集成因ECONNREFUSED未通过;应用内浏览器中的预发布管理员会话已安全锁定,未输入密码或绕过认证,因此未将修复后登录页面交互记为通过。新接口尚未部署,预发布只读SQL仅用于证明真实数据和根因。
  • 本轮按要求不提交、不推送、不部署;工作区中另一会话的充值回执改动继续原样保留。

2026-07-24 通道今日质量、看板签名统计与日期通道占比发布(e12bdf01

  • 功能提交e12bdf010e52584288effc626dc3b84a82dbc15ffix: restore daily operations quality metrics)已推送至origin/main。首次推送遇到内部Git服务瞬时Failed to authenticate user,原命令重试后成功;提交未包含api/tsconfig.build.tsbuildinfooutputs/
  • 发布前门禁通过:API全量26 suites / 319 tests、API TypeScript build、前端TypeScript/Vite build、Gateway go test ./...go vet ./...、Prisma generate/validate及git diff --check。本机API审计因旧npm内部错误未取得有效结果;预发布部署机随后对根项目59个包和API 717个包完成审计,均为0漏洞。
  • 部署前PostgreSQL、运行源码和环境配置备份至/opt/cmpp-platform/backups/releases/20260724-181542-before-e12bdf01。数据库备份SHA-256为9d8c7e1699741d2e952598635b3d512a80a192443744be7a9cb86a3d9727d842,源码备份SHA-256为e2768949c92f568f36e487fd32159693895a0e77ec7f98203c971445112e5cce,环境文件SHA-256为189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7;权限、gzip、tar和sha256sum -c完整性校验通过。
  • 发布包由e12bdf01精确Git快照生成,共567个条目、1690738字节,本机与服务器SHA-256均为f3501053df9d6eec47f10059138dbb1de4e6c1d0badaa5af80ee3986e4265a6c。精确替换受版本控制源码时保留备份、依赖、构建产物和日志目录,随后使用tools/deploy/production-deploy.sh完成依赖安装、Prisma generate/migrate、前端/API/Gateway构建及服务重启;68条migration齐全且无待执行项,最终.deployed-commit=e12bdf010e52584288effc626dc3b84a82dbc15f
  • 发布后Gateway、API、Nginx、PostgreSQL、Redis和MinIO均active12026/17890/3000/6379/5432/9000监听,API health正常、Redis PONG。gateway.submit.commands消费者1、pending=0lag=03条active供应商通道均为connected/currentConnections=1/desiredConnections=1
  • 新路由未登录访问返回受控401,证明路由已加载且认证保护有效;直接调用预发布已部署OperationsService并查询真实PostgreSQL返回日期2026-07-24、3行通道和4行签名统计。通道总量为10:富泷物业-移动5条(成功0、未知3、失败2),赛邮行业-王斯评中转4条(成功1、未知3、失败0),富泷物业-联通1条(成功1、未知0、失败0),修复后不再是前端硬编码全0。
  • 公网首页、运营登录页、客户端登录页和API health均返回HTTP 200,公网CMPP 17890 TCP连接成功。发布以来API、Gateway和Nginx无warning及以上日志。服务器留存的旧管理员凭据已与当前账户密码不一致,接口验收首次登录返回一次401后停止重试,未触发锁定;本轮未绕过认证,登录后页面交互仍需持有当前密码的人工会话复核,未虚报通过。

2026-07-24 提交失败与送达失败口径拆分(本地未提交、未部署)

  • 预发布只读核对确认三条上游结果均为rejected / 103:企业CMPP正式短信18821203795由平台生成PLATFORM:MSG-* / REJECTD失败回执并已完成企业侧投递;运营端通道测试1312762009215821447161没有企业和应用归属,无需生成客户回执。三者业务结果统一归为“提交失败”,是否存在平台通知回执不再改变列表分类。
  • 短信记录列表、CSV、详情和状态筛选按阶段拆分:submit_failedsubmitStatus=rejected/timeout显示“提交失败”;只有供应商已受理且最终失败才显示“送达失败”。详情根据真实平台失败回执和CmppDownstreamDelivery状态显示“平台已生成失败回执并通知企业”,独立通道测试显示“运营端通道测试,无需生成客户回执”。
  • 通道当天质量纳入accepted/rejected/timeout终态提交,“今日提交”包含全部实际提交结果,并新增“提交失败”;送达成功、回执未知、送达失败只以供应商已受理数为分母。分片回执优先按SmsMessageSegmentAudit.submitRecordId聚合,任一分片明确失败即归为送达失败,避免非首片失败被误算为未知。
  • 通道页“查询”按钮绑定loadChannels()。风险复核确认该函数只调用通道列表、当天质量和连接状态三个GET接口,服务端均为只读findMany/聚合,不会连接、断开、重连通道,不会修改配置或写操作日志;不增加自动轮询。
  • 新SQL在预发布真实库只读执行成功:会员营销-铁布衫为今日提交3、提交失败3、已受理0;富泷物业-移动为已受理5、送达成功0、回执未知2、送达失败3;富泷物业-联通为已受理1、送达成功0、回执未知1;赛邮行业-王斯评中转为已受理4、送达成功1、回执未知3。
  • Node.js v24.14.0下API Operations定向1 suite / 22项、API全量26 suites / 320项、API TypeScript build、前端TypeScript/Vite build通过;全量测试仅出现既有Redis不可用容错告警并以--forceExit结束既有异步句柄。前端保留既有约1.93MB单chunk/580.73KB gzip告警。系统默认Node 14执行Jest/Vite时因不支持当前依赖语法却错误返回0,已排除该结果并使用工作区Node 24直接调用本地Jest/TypeScript/Vite可执行文件重跑。
  • 本轮按用户要求仅修改代码并验证,未提交、未推送、未部署;api/tsconfig.build.tsbuildinfooutputs/继续作为既有其他会话/构建产物保留。

2026-07-24 运营看板签名分页与单日企业应用统计(发布前)

  • 运营看板“不含引流”和“含引流”两个今日签名发送统计区改为各占整行;每页展示10个签名,分别维护页码,并支持首页、末页、上一页、下一页和指定页跳转。跨页排名按完整结果集连续计算,不会在每页重新从1开始。
  • 数据统计统一使用日期选择器指定的北京时间单日数据,默认当天;发送量、成功率、企业应用排行和通道占比均来自同一次只读send-quality后端快照。指标标题展示实际已加载日期,修改日期但尚未点击查询时不会把旧数据误标成新日期。
  • 数据统计移除“待审核”。发送量和成功率从所选日期全部有效SmsMessageRecord聚合;企业排行改为企业应用维度,后端联表返回真实应用名称和所属企业名称,不再把企业ID或应用编号作为图表名称,也不混入历史累计记录。
  • 后端新增单日汇总及企业应用统计回归数据,继续排除平台预校验rejected记录;已送达优先于失败判定,submit_failed/failed/timeout或失败回执计入失败,其余计入未知,满足发送总数 = 成功 + 未知 + 失败
  • 发布前门禁:Node.js v24.14.0下API Operations定向1 suite / 22项、API全量26 suites / 320项、API TypeScript build、前端TypeScript/Vite生产构建、Prisma generate/validate、Gateway go test ./...go vet ./...git diff --check全部通过。Jest保留既有Redis不可用容错告警和--forceExit异步句柄提示;前端保留既有约1.93MB单chunk/580.79KB gzip告警。浏览器验收、提交、推送与预发布部署结果待完成后补记。

2026-07-24 提交失败口径、签名分页与单日企业应用统计发布(53736c96

  • 功能提交53736c96e817d3310039bcf4cf1d17dfd775c9a4fix: align daily operations statistics)已推送至origin/main。第一次推送仍被内部Git服务以Failed to authenticate user拒绝,保持提交和工作区不变后直接重试成功;api/tsconfig.build.tsbuildinfooutputs/未纳入提交。
  • 部署前PostgreSQL、运行源码和环境配置备份至/opt/cmpp-platform/backups/releases/20260724-220938-before-53736c96。数据库、源码、环境文件SHA-256依次为e48700dee4dfbf4b1e9f66f8eb6e5b9ede8698d6aeedd01d87e5638e35e9747eeca2a1a33dccc6d5bac9cee5bda55a8bc342845831e8609067e4ee6462784000189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7;权限、gzip、tar和sha256sum -c完整性校验通过。
  • 发布包由53736c96精确Git快照生成,共567个条目、1695144字节,本机与服务器SHA-256均为9148c94478dfdff0f1c3dfa0489d98ee98c20738897d9559611901fe99ef77d4。旧运行目录保留在/opt/cmpp-platform.previous-20260724-221057,随后使用标准tools/deploy/production-deploy.sh完成安装、Prisma、三套构建、Gateway先于API重启和健康检查;68条migration齐全且无待执行项,.deployed-commit=53736c96e817d3310039bcf4cf1d17dfd775c9a4
  • 标准部署脚本实测34秒,其中根项目npm ci约3秒、APInpm ci约6秒;其余约25秒用于Prisma生成/迁移检查、前端/API/Gateway构建、管理员检查、systemd重启和固定3秒健康等待。当前每次发布都执行两次干净依赖安装、三套完整构建、备份/校验及发布后验收,因此用户感知的总耗时显著高于34秒的服务端脚本本身。
  • 发布后Gateway、API、Nginx、PostgreSQL和MinIO均activeRedis PONG12026/17890/8090/3000/6379/5432/9000均监听,API/Gateway health正常。gateway.submit.commands消费者1、pending=0lag=03条active供应商通道均为connected/currentConnections=1/desiredConnections=1API、Gateway和Nginx自发布以来关键错误匹配为0。
  • 直接调用已部署的真实OperationsService及PostgreSQL验证新SQL2026-07-24为总量13、成功2、未知6、失败5、成功率15.4%,返回4个真实企业应用名称、4个通道和5个签名;切换2026-07-23为总量8、成功3、未知1、失败4、成功率37.5%,返回2个企业应用、3个通道和1个签名,证明汇总、排行、通道和签名均随所选日期切换。
  • 公网首页、运营登录页、客户端登录页和API health均HTTP 200,公网CMPP 17890 TCP连接成功。浏览器运营登录页标题正确、1280px视口无横向溢出、控制台0条error/warn;当前无已登录会话且页面存在图形验证码,未绕过验证码,因此登录后两张全宽签名表和统计图的最终视觉验收保留为人工登录复核项,不将源码/构建结果冒充登录后页面验收。

2026-07-25 上下游回执可靠性与逐次投递审计(发布前)

  • 下游增加物理连接级 SubmitResp 写出屏障:从客户 Submit 开始处理到对应响应包真正写出前,同一连接产生的及时失败回执保持 pending;长短信在最终分片 SubmitResp 写出后立即补投,避免客户先收到 Deliver、后收到最后一片 SubmitResp。连接关闭会清理屏障,防止异常连接残留。
  • 每次下游 Deliver 单独写入 CmppDownstreamDeliveryAttempt,保存投递次数、连接 ID、Sequence_Id、业务 Msg_Id、发送/ACK 时间、ACK Result、失败类别和错误;主记录继续承载当前状态和退避调度。运营端下游投递详情新增逐次投递记录,便于区分“平台写出、客户 ACK、ACK 超时和重投”。
  • 上游长短信改为每片 SubmitResp 到达后立即回传 API 并写 SmsMessageSegmentAudit,最终聚合结果只作兜底;若早到供应商失败回执已经形成终态,后到 accepted 聚合不得把主记录倒退到 submitted,并对先扣后退场景保持幂等补偿。
  • 供应商 Deliver Receipt 改为 API UpstreamReceiptInbox 幂等持久化成功后才返回 CMPP_DELIVER_RESP Result=0。异步工作器基于保存的通道端点身份匹配短信,失败指数退避,默认最多 30 次/72 小时;API 进程在 processing 中重启时,默认 2 分钟后可重新认领,不依赖单个 Gateway 连接的内存映射。
  • 通讯日志覆盖供应商 Submit/SubmitResp、Deliver Receipt/DeliverResp、客户 Submit/SubmitResp、平台 Deliver/客户 DeliverResp;无法匹配当前 ACK tracker 的客户 DELIVER_RESP 也记录为失败通讯事件。内部逐分片 HTTP 回调失败另写 Gateway 结构化本地日志,不把内部回调伪装成 CMPP 报文。
  • 新增 migration 20260725160000_add_reliable_receipt_delivery_tracking,仅新增下游逐次投递表、上游回执收件箱及索引/外键,不改写既有短信、提交、回执或投递历史。回滚必须先停止新版本 API/Gateway,再删除两张新表;回滚会丢失新版本产生的逐次投递和待匹配收件箱证据。
  • 发布前门禁通过:Prisma format/generate/validateAPI 定向 3 suites / 119 testsAPI 全量 26 suites / 325 testsAPI TypeScript build,前端 TypeScript/Vite生产构建及 Gateway go test ./...。API 全量仅保留既有 Redis 不可用容错告警和 --forceExit 异步句柄提示;前端保留既有约 1.94 MB 单 chunk 警告。git diff --check通过。
  • 本节当前为发布前记录;提交、推送、数据库/源码/环境备份、migration、服务重启和预发布只读验收结果在发布完成后追加。未经额外授权不发送真实短信,不改写历史业务记录。

2026-07-26 npm 依赖安全整改(发布前)

  • 根项目将 PostCSS 从 8.5.15 固定到已修复的 8.5.23,对应任意 .map 文件路径穿越公告已从审计中消失;平台没有接收用户 CSS 并交给 PostCSS 的运行时路径。
  • React Router 保持并精确固定当前最新版 7.18.1。实测按审计建议降到 7.11.0 会重新引入多条 XSS、开放重定向、反序列化和 DoS 公告,因此未采用。当前唯一剩余 high 为实验性 RSC 模式 CSRF,项目实际使用 HashRouter 客户端 SPA;新增 security:verify 门禁递归扫描前端源码,禁止引入 RSC 服务端 API。
  • API 将 ExcelJS 间接使用的 brace-expansion 替换为官方长度受限的 5.0.8,同时增加本地 CommonJS 兼容适配层,使旧版 minimatch 的函数调用方式继续有效。直接覆盖 5.0.8 曾被兼容性测试明确拦截(expand is not a function),未把审计清零冒充功能可用。
  • 独立 Linux 临时目录从锁文件执行两次全新 npm ci --ignore-scripts 成功:根项目 59 个包、API 726 个包;旧版 minimatch 三条真实依赖链花括号匹配和长度上限均通过。整改后根项目审计只剩同一条不适用 RSC 公告的 2 个依赖节点,API high 从 26 降为 0,仅剩 Prisma CLI→Valibot 的 3 个 moderate;该工具链不处理 API 请求且上游暂无修复版本,不降级 Prisma 7。
  • 功能门禁通过:报备 Excel 专项 1 suite / 7 testsAPI 全量 26 suites / 325 testsAPI TypeScript build,前端 TypeScript/Vite生产构建,Gateway go test ./...go vet ./...,以及依赖安全门禁。标准部署脚本也会在干净安装后、Prisma migration 前强制执行该门禁,失败即停止发布。前端保留既有约 1.94 MB 单 chunk 提示;API 测试保留既有 Redis 容错告警和 --forceExit 异步句柄提示。
  • Windows 本地完整 npm ci 因另一进程占用两个原生 .node 文件而无法清理旧目录,未结束未知会话进程;随后非破坏性 npm install 修复本地依赖。锁文件可重建性以隔离 Linux 干净安装结果为准。提交、推送和预发布部署结果待发布后补记。

2026-07-26 用户登录标识复用、组合查询与管理员提示(本地未提交、未部署)

  • 用户逻辑删除仍保留原记录、主键、角色关联及历史审计;用户名、邮箱和手机号改为仅对deletedAt IS NULL记录唯一。新增migration删除原全表唯一索引并创建三个PostgreSQL部分唯一索引,允许新用户以新主键复用已删除用户的登录标识,不继承旧账号身份或权限;登录和用户名查询显式排除已删除记录。
  • 运营端用户管理将用户姓名、登录账号、所属企业、用户角色和状态拆分;客户端拆分用户姓名、登录账号和状态。查询/重置调用真实用户列表API,后端按独立条件组合PostgreSQL查询,客户端条件由当前会话企业强制限域并固定企业管理员角色,不再下载全量用户后只在浏览器过滤。
  • 新增/编辑用户的校验和重复登录标识错误改在当前表单弹窗内显示。删除、禁用或降权最后一个管理员继续由后端实时计数拦截;运营端和客户端确认弹窗捕获HTTP错误、保持打开、显示可访问红色提示和“先创建或启用另一名管理员”建议,请求期间禁用按钮,不再产生未处理Promise。操作成功后才关闭弹窗,再按已应用筛选条件刷新列表;刷新失败不会误报为删除失败。
  • Prisma validate/generate通过;用户服务定向1 suite / 15 tests、API全量26 suites / 328 tests、API TypeScript build和前端TypeScript/Vite生产构建通过。全量测试只保留既有Redis不可用容错告警和--forceExit异步句柄提示,前端保留既有约1.94MB单chunk警告。
  • 本地静态预览访问运营端、客户端用户管理路由时均由真实认证守卫重定向至对应图形验证码登录页;页面标题、登录表单、无框架覆盖和控制台0条error/warn通过。没有绕过验证码,因此分离筛选和管理员拦截弹窗的登录后可见交互仍保留为人工登录复核项。
  • 本轮按用户要求保持未提交、未推送、未部署;未对预发布数据库执行migration或写入测试用户。api/tsconfig.build.tsbuildinfooutputs/及未跟踪空文件=保持隔离,未纳入本次修改。

2026-07-26 企业应用停用回执清算与下游断连(本地未提交、未部署)

  • 企业应用新增disablingAt/autoDisableAt/disableReason持久化字段和disabling状态;停用前统计等待供应商回执、等待推送、等待客户ACK、可重试失败、待推送上行和在线连接。
  • 无待清算数据直接停用;有数据时运营端弹窗可选择“等待回执后停用”或“强制停用并断开连接”。停用中状态支持悬停/聚焦查看原因和数量,并可点击启用恢复。
  • 停用中应用立即拒绝新Submit但允许回执清算连接;清算完成自动停用,进入停用中满72小时仍未完成时自动放弃剩余投递、标记abandoned并断开该账号全部下游CMPP连接。
  • Gateway新增按客户账号关闭全部下游会话的控制接口;历史pending回执读取移除企业/应用当前启用状态限制,修复企业删除后回执已生成但Gateway持续收到400的投递死锁。
  • 企业删除增加active/disabling应用拦截。应用停用后才到达的供应商回执继续更新真实短信终态,但下游投递直接留痕为abandoned且不再重试。
  • 已通过Prisma format/generate/validate、API定向3 suites / 155 tests、API全量26 suites / 333 tests、API TypeScript build、前端TypeScript及Vite生产构建、Gateway go vet ./...go test ./...。API全量仅保留既有Redis不可用容错告警和--forceExit异步句柄提示;前端保留既有约1.94MB单chunk提示。
  • 应用内浏览器访问本地生产预览的企业应用管理路由,被真实认证守卫引导到运营登录页;页面标题和登录表单正常、无框架错误覆盖、控制台0条error/warn。当前没有已登录会话且存在图形验证码,未绕过认证,因此停用选择弹窗、停用中悬停详情和恢复启用的登录后视觉交互仍需持有有效会话后复核。
  • 本轮按要求不提交、不推送、不部署;工作区原有用户管理、依赖安全整改、构建产物及outputs/等其他会话修改保持原样。

2026-07-26 风控规则与短信人工审核整改(发布前)

  • 风控规则收敛为单任务号码上限、可自定义非工作时间营销批量、10分钟客户端任务频控三项;新增全局/企业应用级规则页和真实后端编辑接口。应用级规则稳定覆盖全局,客户端频控直接统计同应用sourceType=client批次,排除CMPP、HTTP、通道测试和预检。
  • 删除企业应用maxPhonesPerTask字段和表单配置,不迁移测试应用旧值;重复号码、非法号码比例、黑名单比例和模板变量规则转deleted保留历史审计但不再生效。模板变量缺失/多传继续作为确定性提交拒绝。
  • 手机号码基础校验放宽为^1\d{10}$,不依赖号段更新。客户端/HTTP混合批次逐号码把非法号码、平台黑名单和企业应用黑名单记为submit_failed/rejected且金额0,合法号码照常冻结、入队;CMPP混合多目的提交对被拦截号码生成平台REJECTD失败回执,合法号码继续处理。
  • 短信审核页只返回待人工审核及人工处理记录,自动放行/拒绝不再混入;号码数量恢复设计基线的查看入口,真实接口仅返回手机号、归属地、运营商和短信状态并支持服务端搜索/分页。
  • 新待审核短信同步保存reviewTaskId,审核决定同时按短信直连和批次riskTaskId查找,修复审核任务已通过而短信仍pending_review。遵照要求不改写现存历史异常数据、不补发历史短信。
  • 用户登录标识改为“仅未删除记录唯一”后,部署管理员初始化与真实环境冒烟脚本同步从username唯一upsert改为先查询未删除用户、再按主键更新或创建,避免迁移后Prisma拒绝旧的唯一查询。
  • 发布前门禁阶段结果:Prisma format/generate/validate通过;风险审核+发送链定向2 suites / 108 tests通过,随后补充应用覆盖、号码分页与逐号码拦截用例;API全量26 suites / 338 tests、API TypeScript build、前端TypeScript/Vite生产构建、Gateway go test ./.../go vet ./...、依赖安全门禁通过。API保留既有Redis不可用容错告警与--forceExit提示,前端保留约1.95MB单chunk/584.70KB gzip提示。

2026-07-26 发送批次号与任务号命名统一(本地未提交、未部署)

  • 运营端短信任务进度、客户端批量任务、客户端首页及发送成功提示统一把SmsBatchTask.taskNo展示为“发送批次号”;同步修改查询标签、占位提示、详情标题和终止失败提示。
  • 短信审核列表新增“审核任务号”列,筛选、详情和号码明细标题统一展示SmsSendTask.taskNo;不新增接口请求或浏览器派生数据。
  • 报备任务和报备记录的列表、筛选及详情统一使用“报备任务号”。本次不修改数据库字段、编号格式、关联关系或协议消息ID。
  • Node.js v24.14.0下前端TypeScript检查、Vite生产构建和git diff --check通过;构建保留既有约1.95MB单chunk/584.75KB gzip提示。应用内浏览器访问本地短信任务进度路由时,未登录会话由真实鉴权守卫引导到运营登录页,标题、表单交互和控制台0条error/warn通过;图形验证码阻止登录后页面验收,未绕过认证或把登录页冒充目标页面。
  • 本轮按要求保持本地未提交、未推送、未部署;api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/及未跟踪空文件=继续作为既有构建/临时产物隔离。

2026-07-26 企业删除拦截提示修复(本地未提交、未部署)

  • 后端原本已在企业仍有active/disabling应用时返回具体数量和“先完成应用停用”提示;运营端此前仅把失败写入弹窗背后的页面级错误,用户几乎不可见。
  • 企业删除/状态变更确认弹窗新增独立错误和请求中状态:失败保持弹窗并就地显示原因;请求期间禁用确认、取消及关闭;成功后才关闭并刷新列表。实现复用用户管理最后管理员拦截的交互口径。
  • Node.js v24.14.0下前端TypeScript检查、Vite生产构建和git diff --check通过,保留既有约1.95MB单chunk/584.92KB gzip提示。应用内浏览器访问本地企业管理路由时由真实鉴权守卫引导到图形验证码登录页,页面完整、输入交互正常且控制台0条error/warn;未绕过认证,登录后的拦截弹窗仍需有效运营会话补充可见验收。
  • 本节仅记录本地修改;未提交、未推送、未部署。

2026-07-26 运营页面细节与通道重连收敛(本地未提交、未部署)

  • 企业签名及引流信息报备状态将运营商映射为中文,并使用目标通道真实名称替代内部通道编号;展示忠实反映实际通道关联,不根据签名名称猜测运营商。
  • 短信上行内容列扩大到360px并最多展示三行,表格最小宽度同步增加;短信记录首次加载及重置默认查询北京时间昨天和今天。
  • 下游投递详情把逐次投递宽表改为纵向时间线卡片,中文展示等待确认、已确认、拒绝和失败状态,并分组展示发送/ACK/截止时间、连接、Sequence_Id、Msg_Id、ACK Result和错误。
  • Gateway提交异常列表新增带间距和分隔的标题区、结果总数及分页分隔,解决标题和边框紧贴的问题。
  • 通道更新改为比较修改前后实际连接参数;仅网关地址、端口、账号/密码、CMPP版本、连接数、窗口和心跳参数变化时请求重连。名称、价格、运营商、地区、服务号、扩展位及TPS等非连接参数不触发连接控制,状态启停逻辑不变。
  • 按最新要求取消日报T-4未知转失败,本轮未修改报表重算、未知口径或历史数据。
  • Node.js v24.14.0下通道服务定向1 suite / 40 tests、API TypeScript build、前端TypeScript检查、Vite生产构建及git diff --check通过。Jest仅保留既有Redis不可用容错告警和--forceExit异步句柄提示,前端保留既有约1.95MB单chunk/585.35KB gzip提示。
  • 应用内浏览器分别以默认桌面和390×844视口访问本地短信记录路由,真实认证守卫均引导至运营登录页;页面非空、无框架错误覆盖、控制台0条error/warn,输入框交互正常,移动端scrollWidth=clientWidth=390。未绕过图形验证码,因此六个登录后目标页面的最终视觉和真实数据验收仍需有效运营会话复核。
  • 本轮按要求保持未提交、未推送、未部署;工作区原有用户管理、编号命名、依赖安全整改、构建产物及临时文件保持原样。

2026-07-26 通道补发归因与发送详情修复(发布前)

  • 预生产只读核对13901860234 / 17:53:46:首轮富泷物业-移动两个分片均提交成功后返回FLBLACK,随后会员营销-铁布衫补发并返回WL:FSNM。详情把两次尝试都显示为铁布衫,是因为接口未返回提交/回执关联通道且前端使用短信主记录最终通道兜底;后续仅显示一个通道,是直接签名短信没有模板时补发签名解析失败并被空catch吞掉,与18:01通道顺序调整只是时间相关而非真实原因。
  • 直接签名和模板短信统一从短信记录解析真实signatureId;补发开始、跳过、选中和失败均输出结构化日志,包含消息、通道组、尝试通道、限制时间和异常原因。
  • Gateway聚合及逐分片提交结果携带原始submitId,API按提交记录主键精确更新。旧Gateway缺少submitId时只允许严格唯一候选兼容;歧义结果拒绝并记录,不再按短信批量覆盖多个尝试。迟到旧尝试结果只更新对应提交审计,不倒写当前短信尝试。
  • 运营短信接口返回提交及回执关联通道;详情优先按分片审计的submitId重建逐次通道、发送时间、提交状态和分片回执,因此既有17:53记录可还原为富泷到铁布衫两次真实尝试。
  • 通道组更新新增修改前后有序成员操作日志,包含通道编号、名称、运营商、地区、优先级、权重和主备,可审计顺序变化。
  • 定向验证已通过发送链1 suite / 98 tests(含直接签名备用通道、聚合及分片歧义拒绝)、通道和运营接口专项以及Gateway消息透传专项。最终发布门禁通过:API全量26 suites / 343 tests、API TypeScript build、Prisma format/validate、前端TypeScript/Vite生产构建、Gateway go test ./.../go vet ./...、依赖安全门禁及git diff --check;前端仅保留既有约1.95MB单chunk提示。
  • 功能及工作区既有UI修改提交0857de09d82aec7233108fb6700c40a6183c21f8fix: harden channel retry attribution and operations UI)已推送至origin/main;首次推送被内部Git服务瞬时返回Failed to authenticate user,保持提交不变后重试成功。构建缓存api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfo及临时outputs/、空文件=未提交。
  • 部署前PostgreSQL、运行源码和环境配置备份至/opt/cmpp-platform/backups/releases/20260726-213641-before-0857de09SHA-256依次为a9ec6f5c96f1dcd2f314e4c63e76b1d348f8320f8852667be5c2f7df933488c901140043ee1c640faa31b870b333771d9c57a6295ffdf0b54637db93321858dd189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7gzip、tar和sha256sum -c均通过。精确Git归档438个文件、1736410字节,本机与服务器SHA-256均为2d6be9044fa2c7070e7af7bb077c324f4e4eb99e03001be390f58875350ddafd;旧运行目录保留在/opt/cmpp-platform.previous-20260726-213641
  • 标准部署脚本完成两套干净依赖安装、安全门禁、Prisma生成/迁移检查、前端/API/Gateway构建和服务重启;72条migration齐全且无待执行项,.deployed-commit=0857de09d82aec7233108fb6700c40a6183c21f8。生产依赖审计仍报告前端2个high(未使用的React Router RSC路径)和API 3个moderatePrisma CLI工具链),自动安全门禁确认既定缓解继续有效,未执行破坏兼容性的audit fix --force
  • 发布后API、Gateway、Nginx、PostgreSQL、MinIO均activeRedisPONG12026/17890/8090/3000/6379/5432/9000均监听,内外健康页及运营/客户端入口HTTP 200,公网CMPP 17890可连接;Redis提交流消费者1、pending=0lag=0,发布后API/Gateway无error级日志。
  • Gateway重启时供应商曾对“会员营销-富泷”首次登录返回auth failed,系统按鉴权失败5分钟慢重试策略等待而未高频重连;21:42:17自动重试成功,最终4个启用通道全部connected/currentConnections=1/desiredConnections=1。历史17:53短信数据库只读验证仍为富泷两个FLBLACK分片、铁布衫两个WL:FSNM分片,证明部署未改写证据且新详情具备正确重建数据。

2026-07-26 MSG-65a47514长短信并发重复补发P0修复(发布前)

  • 预生产只读证据确认MSG-65a47514-7f30-49af-8113-b76747550199正文408字、3个计费/协议分片。12:33:33经会员营销-铁布衫提交一次;12:58:17三个WL:CGMT失败回执在9毫秒内到达,三个处理线程分别触发整条补发,在约13毫秒内创建三个富泷submitId,形成“铁布衫1次+富泷3次”、共4次整条尝试和12个真实Submit分片。所有尝试均为失败回执,没有DELIVRD成功证据。
  • 并发影响还包括三个已被客户Result=0确认的最终失败回执、三条各1053分的退款流水,以及非原子余额覆盖导致的实际多退。通道尝试记录成本为铁布衫993分、富泷3168分;是否形成供应商真实账单需另行对账。本轮不删除历史提交、回执、投递、ACK或账务证据,不自动冲正现有余额。
  • 新migration20260726223000_prevent_duplicate_retry_side_effectsSmsSubmitRecord增加唯一retryOfSubmitRecordId自关联、为AccountTransaction增加唯一idempotencyKey、为CmppDownstreamDelivery增加唯一dedupeKey。历史重复下游回执只给每条短信最早的回执设置稳定键,其余历史行原样保留。
  • 补发记录、提交会话计数和短信当前尝试改为同一数据库事务创建;相同来源提交记录的并发线程只有一个能取得下一跳,其他线程读取并复用已存在的补发,禁止再次向Gateway发布。缺少可审计来源提交记录时安全停止补发并写结构化错误。
  • 企业账户通用余额变更改为企业级PostgreSQL事务锁加原子increment;短信扣费、提交成功释放冻结、最终释放和退款使用平台消息号稳定幂等键。三次并发退款专项用例返回同一交易ID,只创建一条流水并只改变一次余额。
  • CMPP最终回执使用receipt:{messageRecordId}唯一键;HTTP回执事件使用evt_receipt_{messageRecordId}稳定事件号并复用事件/端点唯一投递。并发专项用例证明三个完成线程只向Gateway发送一次最终回执;所有抢占、复用和投递去重均写结构化日志。
  • 当前专项门禁:发送链、账务和HTTP API共3 suites / 121 tests通过,包含三个长短信失败处理线程并发抢占、三次并发退款及三次最终回执创建。全量API回归26 suites / 346 tests通过,API TypeScript构建检查、Prisma schema校验、前端TypeScript/Vite/生产依赖安全门禁及Gateway Go测试/vet均通过;提交、推送和预生产部署结果待完成后补记。
  • 功能提交e0f6eed0d40e21fb06166e28dd54fefa7d0f09b0已推送并由精确Git快照发布;快照585个条目、1741824字节,本地与服务器SHA-256均为99ed2d4b86f91b09a87baca027441aa63bec4b0ccefae3a04be5c63d80878e3f。部署前数据库备份为/opt/cmpp-deploy-backups/cmpp-20260726-223344.sql,旧运行目录保留为/opt/cmpp-platform.previous-20260726-223344
  • 标准部署脚本成功应用20260726223000_prevent_duplicate_retry_side_effects,预发布73条migration齐全;三个目标字段、唯一索引及补发自关联外键均已落库,.deployed-commit=e0f6eed0d40e21fb06166e28dd54fefa7d0f09b0。API、Gateway、Nginx、PostgreSQL、MinIO均activeRedisPONG12026/17890/8090/3000/6379/5432/9000监听,内外健康页、运营端和客户端入口HTTP 200,公网CMPP 17890可连接,发布后API/Gateway无error级日志。
  • 四个启用通道均为connected/currentConnections=1/desiredConnections=1Redis提交流消费者1、pending=0lag=0。事故短信只读复核仍为4条提交尝试、12条供应商回执、3条下游投递和3条refunded账务流水,证明发布未删除、重写或自动冲正历史证据;本轮未发送任何真实测试短信。

2026-07-27 HTTP环境前端随机ID兼容修复(发布前)

  • 预发布运营端删除签名在发起删除预检前调用crypto.randomUUID();公网入口为裸HTTP IP,浏览器非安全上下文中该方法不可用,导致点击后抛出TypeError且后端未收到删除请求。
  • 新增统一随机ID工具:安全上下文优先使用原生randomUUID()HTTP等环境回退到crypto.getRandomValues()生成符合版本位和变体位要求的UUID v4;极旧环境无Web Crypto时保留随机字节兼容兜底。
  • 删除签名/模板/通道、签名和模板审核通过、人工充值、报备批次生成统一改用兼容工具;企业应用密码随机生成也复用随机字节实现,避免同类问题从其他入口再次出现。
  • Node.js v24.14.0下前端TypeScript检查、Vite生产构建及git diff --check通过;无randomUUID()和无Web Crypto两种模拟环境均生成格式正确的UUID v4,getRandomValues()回退同时生成16位十六进制应用密码。构建仅保留既有约1.95MB单chunk提示。
  • 此修改已纳入用户授权的本轮统一提交、推送和预生产发布范围;工作区原有构建缓存、outputs/及空文件=继续作为非代码临时产物隔离。

2026-07-27 签名不可见字符校验与通道报备真实统计(发布前)

  • 客户端与运营端签名新增/编辑统一禁止普通空格、Unicode空白、控制字符和默认不可见字符;非法键入或粘贴不覆盖已有受控输入,并即时显示错误。NestJS新增、编辑接口复用相同后端校验,防止绕过页面写入非法签名。
  • 通道报备详情恢复设计基线的“提交报备时间、报备成功时间、上次发送成功时间、今日发送”列;报备成功时间取真实通过记录,上次成功时间取当前通道与签名/引流范围内最近一条最终成功短信。
  • 今日发送统计由PostgreSQL真实提交记录、分片审计和供应商回执聚合,拆分成功、未知、回执失败和提交失败。提交拒绝/超时不混入已接受短信的回执失败率;签名任务汇总签名全部引流范围,具体引流任务严格隔离到自身。
  • Node.js v24.14.0定向验证通过:通道与短信配置2 suites / 103 tests;本机临时Redis就绪后API全量26 suites / 353 tests通过,测试结束即停止临时Redis。Prisma schema校验、API TypeScript build、前端TypeScript/Vite生产构建、Gateway Go全量测试/vet和依赖安全门禁通过;前端仅保留既有约1.96MB单chunk提示。
  • 预发布PostgreSQL按新口径只读执行聚合成功:当前报备任务范围覆盖512条通道提交尝试,其中北京时间今日324条、提交失败1条、最终成功169条,最近成功时间为2026-07-27 11:18:39.04 UTC;查询未写入或改写业务数据。提交、推送及预生产部署结果以本轮交付回执为准。
  • 用户明确授权将工作区所有有效代码一并发布;api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/及空文件=属于既有构建/临时产物,不纳入源码提交。
  • 功能提交94aeacd3a20b4c838c59d67ba86ef466ff49ce03已推送并由精确Git快照发布;快照586个条目、1748983字节,本机与服务器SHA-256均为563de7dbc2c6b85b5d120f37ba92f16c2933da1c4d5f6c7939d2c41a53ea3595。首次推送被内部Git服务瞬时返回Failed to authenticate user,保持提交不变后重试成功。
  • 部署前PostgreSQL和环境配置分别备份为/opt/cmpp-deploy-backups/cmpp-20260727-205312.sql/opt/cmpp-deploy-backups/cmpp-env-20260727-205312.env,旧运行目录保留为/opt/cmpp-platform.previous-20260727-205312;标准脚本完成两套依赖安装、安全门禁、Prisma、前端/API/Gateway构建及Gateway先于API重启,73条migration齐全且无待执行项。
  • 预发布.deployed-commit=94aeacd3a20b4c838c59d67ba86ef466ff49ce03API、Gateway、Nginx、PostgreSQL、MinIO均activeRedisPONG12026/17890/8090/3000/6379/5432/9000监听,内外页面和健康接口HTTP 200CMPP 17890可连接,Redis Stream消费者1、pending=0lag=0,发布后API/Gateway无error级日志。
  • 部署后的真实ChannelsService查询53个报备任务,4个存在今日真实发送统计,返回成功、未知、回执失败、提交失败和最近成功时间;前端产物包含三项新交付文案。4个启用通道中3个立即恢复connected 1/1;“会员营销-富泷”首次鉴权失败后按5分钟慢重试策略于20:59:07自动恢复connected 1/1,未人工高频重连。本轮未发送真实测试短信。

2026-07-27 签名动态资格与运营端十项缺陷修复(发布前)

  • 签名审核资格从固定signatureProfile切换为提交时reportRequirementSnapshot.fields + signatureReportValues,只校验签名/通用类型必填字段;通道仅要求引流字段时不再误报公司名称、信用代码、法人、责任人和资质文件。
  • 短信提交新增channelGroupId/channelGroupName历史归因,migration对仍可唯一确认的历史提交回填;名称快照保证通道组删除后仍可解释历史发送。发送详情展示通道组,分片补偿审计按创建时间升序并展示审计时间。测试短信不再把说明写入errorMessage,详情失败框只由真实最终失败状态触发。
  • 运营看板签名统计增加提交失败并从送达失败中拆出;企业消费排行改为北京时间当天真实charged计费聚合,覆盖全部企业账户,不再从最近10条手工充值和最近20个账户拼装。
  • 审核中心把风控规则移到最后并修正面包屑;通道测试密码/接入号增加独立autocomplete/name语义;通用输入控件有无提示时顶部对齐,企业应用通道组Select及选项限制在卡片宽度内。
  • 最后一个企业管理员允许删除、禁用或降权至零人;最后一个平台管理员保护保持不变。
  • Node.js v24.14.0下签名审核、用户、运营统计3 suites / 43 tests,通道1 suite / 41 tests,通道组持久化发送路径专项通过;启动临时本地Redis后API全量26 suites / 354 tests通过,测试结束即关闭临时Redis。API TypeScript build、前端TypeScript和Vite生产构建、Prisma format/generate/validate及git diff --check通过。
  • 功能提交df70b336a038fafab6afdcf24f1d35b7ade50744fix: align signature review and admin operations)及部署加固提交7c1a0287a0b68e6f3ecdbd16243dd05bb8a263e1chore: harden preproduction deployment)已推送至origin/main。第一次功能提交推送被内部Git服务瞬时返回Failed to authenticate user,保持提交与工作区不变后重试成功;既有api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/及空文件=未纳入提交。
  • 精确Git归档共441个文件、5939200字节,本机与服务器SHA-256均为dcbdf236e1fbe0ecf6da87c3b5306f805661a5d35f89edbc466a00287b8da56f。部署前数据库备份为/opt/cmpp-deploy-backups/cmpp-20260727-221003-before-df70b336.sqlSHA-256 cfc75e2a388454ec9f3a0b30ff14719c34e8cd8ff39908c7cf0eaac1f5a521a3),环境备份为/opt/cmpp-deploy-backups/cmpp-env-20260727-221003-before-df70b336.envSHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7),旧运行目录保留为/opt/cmpp-platform.previous-20260727-221003
  • 标准部署脚本完成依赖安装、安全门禁、Prisma生成和migration、前端/API/Gateway构建;新migration20260727113000_persist_submit_channel_group应用成功,预发布共74条migration。首次systemd启动因精确快照不包含运行时logs/目录,而服务配置使用StandardOutput=append:/opt/cmpp-platform/logs/...API和Gateway在启动前以209/STDOUT退出;未回滚或重复执行migration,复用上一运行目录保留的日志目录后按Gateway、API、Nginx顺序重启,服务恢复并通过健康检查。部署脚本随后补充install -d,在服务重启前显式创建API和Gateway日志目录,避免同类启动空窗。
  • 加固提交再次以精确Git归档发布,共441个文件、5939200字节,本机与服务器SHA-256均为db61ed69298796b0f4b4d16306a09f1a19526cdc3b43af88ae2a7334933a2940。部署前数据库和环境备份分别为/opt/cmpp-deploy-backups/cmpp-20260727-221934-before-7c1a0287.sqlSHA-256 64c23d625e606bb4a90d0fd6335472775a88c4ec7a107269684120cce1864ea3)和/opt/cmpp-deploy-backups/cmpp-env-20260727-221934-before-7c1a0287.envSHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7),旧运行目录保留为/opt/cmpp-platform.previous-20260727-221934。空快照环境下脚本自行创建logs/apilogs/gateway且一次启动成功,74条migration无待执行项,证明修复闭环。
  • 部署后真实数据库直接验证待审核签名【安徽航天信息】返回allowedActions=["approve","reject"]blockedReasons=[]且配置必填字段数为0,证明不再套用旧固定资格项。SmsSubmitRecord共530条,其中512条已回填通道组ID及名称;剩余18条无法唯一归因的测试或历史提交保持空值,未伪造归因。真实OperationsService可返回当天charged计费企业消费排行(首位“启瑞中转企业”77220内部计费单位)及包含acceptedCount/submitFailureCount的签名统计。
  • .deployed-commit=7c1a0287a0b68e6f3ecdbd16243dd05bb8a263e1API、Gateway、Nginx、PostgreSQL、MinIO均activeRedisPONG12026/17890/8090/3000/6379/5432/9000均监听。Gateway重启后3个客户CMPP账号因旧进程连接行尚在90秒心跳期限内首次重连收到连接数限制,超时清理后均由客户端自动重连成功,最终4个客户CMPP应用均有实时心跳;4个启用供应商通道也全部恢复connected/currentConnections=1/desiredConnections=1。Redis Stream消费者1、pending=0lag=0
  • 公网首页、运营端、客户端和API health均HTTP 200,公网CMPP 17890 TCP可连接。应用内浏览器验证运营登录页标题为“聆界短信管理平台”,1280px视口scrollWidth=clientWidth=1280且控制台0条error/warn;当前无可接管的已登录会话且页面存在图形验证码,未绕过认证,因此十项登录后交互的最终可见验收保留为持有有效运营会话后的人工复核项。本轮未发送真实测试短信。

2026-07-28 运营端有效数据口径与审核详情补齐(本地未提交)

  • 报备字段库引用数改为只统计未删除通道并按通道去重;字段只剩已删除通道历史映射时可正常删除,并同步清理失效映射。通道报备详情同时排除已删除签名。
  • 运营看板今日企业消费在原有北京时间当日真实charged计费口径上排除已删除企业。
  • 短信审核列表改为展示发送企业和企业应用,移除审核任务号与审核原因列;详情仍保留任务、原因和真实号码明细。
  • 短信任务进度号码数量新增真实列表入口,后端按批次提供手机号搜索、分页及手机号、归属地、运营商、短信状态字段,不在浏览器内截断或拼装。
  • 企业签名引流资料新增/编辑统一为“引流url或号码”,移除独立“引流信息”输入;企业管理移除“数据来自租户、账户真实接口。”研发注释。
  • 企业认证、短信、模板、签名、引流信息审核入口统一为“详情”,缺失详情入口的页面已补齐;所有详情展示审核时间和审核人员用户名。新审核动作保存真实审核用户,历史缺失审核人不伪造。
  • Node.js v24.14.0下前端TypeScript、API TypeScript和Vite生产构建通过;字典、通道、运营统计、风控审核、企业认证5 suites / 94 tests及发送链1 suite / 101 tests定向通过,临时本地Redis下API全量26 suites / 358 tests通过,测试结束后已停止临时Redis;git diff --check通过。应用内浏览器访问本地生产构建的短信审核路由时,真实鉴权守卫跳转运营登录页;本地预览未连接API而返回502,且图形验证码阻止登录后页面验收,未绕过认证或将登录页冒充目标页面。
  • 本轮按用户要求保持未提交、未推送、未部署;既有构建缓存、outputs/及空文件=继续作为其他会话/历史临时产物保留。

2026-07-28 签名/引流导入审核与报备批次页面重构(本地未提交)

  • Excel 导入从“确认后直接写业务对象”改为真实待审核明细:新增 ReportMaterialImportItem 保存行号、新增/修改类型、目标对象、资料载荷、原快照、校验错误、审核人及审核时间。提交导入只进入 pending_review,不会创建、修改或自动审核通过签名/引流信息。
  • 短信签名审核和引流信息审核分别增加“导入批次审核”页签,支持按批次查看行明细、勾选多行或整批通过、批量驳回;驳回原因可选。审核通过后才复用真实短信配置服务应用新增/修改并进入正常待报备流程,非法行独立记录错误。
  • 企业签名管理新增“批量导入签名及引流资料”入口;导入弹窗文案明确为提交审核,不再从待生成资料页混入导入操作。
  • “待生成报备批次”改为“待生成资料/已生成批次”两个页签,两个页签均提供后端分页、关键字和时间查询;筛选重置使用显式空条件重新查询,避免 React 状态异步导致旧条件残留。
  • 已生成批次按真实导出文件明细统计报备总数,按关联通道任务当前通过状态统计成功数和成功率;移除已导入回执、等待回执等无明确当前需求的展示。
  • 原“报备任务”页面收敛为逐通道“报备明细”,移除无真实产物的“生成同范围任务”和回执导入入口。人工状态弹窗只选择目标状态,原因可选;详情展示企业、应用、来源批次/文件行号和按时间顺序排列的状态轨迹。历史回执表及后端兼容接口暂不删除,避免破坏既有数据追溯。
  • 新增 migration 20260728153000_stage_report_material_import_reviews。Node.js v24.14.0 下报备资料与通道服务定向 2 suites / 51 tests 通过,覆盖导入仅暂存不改业务对象、无原因驳回、批次总数/成功数/成功率及通道报备关联读取;临时本地 Redis 下 API 全量 26 suites / 361 tests 通过,测试结束后已停止临时 Redis。前端/API TypeScript、Prisma validate、Vite 生产构建及 git diff --check 通过,Vite 只保留既有大 chunk 提示。
  • 应用内浏览器连接失败后按浏览器控制技能切换到可用 Chrome,在本地生产构建访问 /admin/report-materials;前端路由和登录守卫正常,但本地未启动 NestJS API,认证请求返回 502 并跳转登录页,且没有可接管的已登录运营会话。未绕过验证码,因此双页签、批次审核和人工状态弹窗的登录后视觉验收仍需有效会话复核,不能以登录页冒充完成。
  • 本轮按用户要求保持未提交、未推送、未部署;工作区其他会话及历史未提交修改继续原样保留。

2026-07-28 企业营业执照、利润成本与删除余额门禁(本地未提交)

  • 新建/编辑企业共用页面将“企业照片”统一改为“企业营业执照”,同步调整已上传占位、上传按钮、默认文件名和失败提示;对象存储既有 purpose/prefix 保持兼容,不迁移历史文件。
  • 利润报表成本改为“提交时通道成本单价快照 × 该次提交成功短信分片数”。新数据优先按 SmsMessageSegmentAuditreceiptStatus=delivered 的分片数统计;历史缺少分片审计但存在明确成功回执时按短信计费分片数兼容,失败、未知和未收到成功回执的分片不计成本。企业应用和通道两个利润维度使用同一口径,利润及利润率随成本同步重算。
  • 企业删除在与充值、扣费、退款相同的 tenant-account:<tenantId> PostgreSQL 事务锁内读取真实账户余额;余额非0时拒绝删除并提示“完成余额清算后方可删除,请给企业充值到金额为0”,余额为0后仍继续执行活动企业应用门禁。
  • Node.js v24.14.0 下报表和企业服务定向 2 suites / 14 tests、API 全量 26 suites / 364 tests、前端与 API TypeScript、Vite 生产构建及 git diff --check 通过;Vite 仅保留既有大 chunk 提示。
  • 本地 PostgreSQL 启动后确认目标为 localhost:5432/cmpp_platform,应用至75条 migration;本地 API 在3000端口、前端生产预览在4173端口、Redis在6379端口运行,健康接口和页面均返回 HTTP 200。真实 PostgreSQL 已使用新成本 SQL 成功重算 2026-07-24 至 2026-07-27,未出现 SQL 语法或字段关联错误。
  • 本地未启动 Gateway,API 启动时本地库两个历史 active 通道的恢复连接请求按预期失败;发送 worker 和回执超时扫描已关闭,不连接供应商、不发送短信,不影响运营页面查看。
  • 本轮继续保留为未提交、未推送、未部署状态;本地服务按用户要求保持运行。

2026-07-28 恢复状态与下游投递近七天筛选(本地未提交)

  • “恢复状态管理”补充用途说明:该页按客户账号展示 Gateway 在客户重连或实例重启后,对未完成状态回执和上行短信续投的当前/最近一次恢复状态;逐条消息的投递、重试与客户端 ACK 仍在“下游投递记录”查看。
  • 恢复状态增加按最近更新时间的真实后端时间区间筛选,默认今天在内的近 7 个自然日;摘要、失败分类、分页列表和 CSV 导出统一使用同一筛选条件,重置后恢复默认近 7 天。
  • 恢复状态列表标题区补充卡片内边距,避免标题紧贴外框;“最后错误/跳过原因”列固定为 320px 可读宽度。下游投递记录创建日期默认及重置均改为近 7 天。
  • Operations 专项 1 suite / 22 tests 通过,覆盖恢复状态列表和 CSV 导出的北京时间起止边界;前端 TypeScript、API 正式构建配置 TypeScript、Vite 生产构建及 git diff --check 通过,Vite 仅保留既有大 chunk 提示。真实本地 PostgreSQL 使用 2026-07-22 至 2026-07-28 条件执行恢复状态查询成功,本地库当前返回 0 条。
  • API 全量 Jest 在本轮等待 120 秒后仍未结束且未输出最终汇总,确认遗留测试进程仍在运行后已只停止该本轮测试进程;不把它记录为通过或失败。专项测试及正式构建结果不受影响。
  • 本地 API 已重启并在 3000 端口健康运行,前端生产预览继续在 4173 端口运行;Gateway 未启动,发送 worker 与回执超时扫描保持关闭。本地浏览器已打开运营登录页,受图形验证码保护,未绕过认证。
  • 本轮保持未提交、未推送、未部署,工作区其他会话及历史未提交修改继续原样保留。

2026-07-28 签名通道与运营商发送质量(本地未提交)

  • 数据统计页新增已登记签名发送质量区域,默认北京时间当天并跟随现有日期查询;支持按签名、企业或应用关键字查询及后端分页。未关联signatureId的正文签名按用户最新决定不纳入统计。
  • 签名主表按业务短信记录展示业务短信、送达成功、送达失败、提交失败、最终成功率和平均到达时间;通道提交数按真实SmsSubmitRecord尝试统计,明确允许补发时大于业务短信数。
  • “查看明细”使用右侧大尺寸抽屉,先按移动、联通、电信汇总,再以通道为行、运营商为列展示提交次数、成功率、平均到达时间和提交失败;同一通道可同时出现多个运营商,不建立错误的一对一归属关系。
  • 新增独立真实后端接口GET /admin/operations/signature-quality,签名汇总只连接平台SmsSignature,通道质量复用分片审计及供应商回执完成口径;平均到达时间仅统计成功送达尝试,长短信以全部成功分片完成为准。
  • Operations定向1 suite / 24 tests通过,新增覆盖分页签名矩阵合并和真实空状态;API TypeScript正式构建、前端TypeScript检查及Vite生产构建通过,Vite仅保留既有约1.98MB单chunk提示。
  • 新SQL已对本地PostgreSQL真实执行。为便于本地视觉验收,新增必须显式设置ALLOW_LOCAL_SIGNATURE_QUALITY_DEMO=true、只允许localhost数据库且在NODE_ENV=production下无条件拒绝执行的演示数据脚本,并写入明确标记的“本地统计演示企业/应用”、3个已登记签名、54条业务短信、61次通道提交和51条回执;演示通道均为inactive,Gateway未启动,不连接供应商、不发送短信。
  • 本地API和前端生产预览分别运行于3000、4173端口,健康检查及数据统计页均HTTP 200。应用内浏览器以真实本地运营会话验证签名列表、运营商概览和通道×运营商矩阵;窄窗口下矩阵横向滚动已限制在矩阵内部,不再撑宽整个详情抽屉。
  • 本轮按用户要求只运行在本地,保持未提交、未推送、未部署;工作区其他会话已有未提交修改继续保留。

2026-07-28 工作区汇总发布门禁

  • 本次汇总范围包含:报备字段和有效通道引用口径、审核详情与号码列表、签名/引流资料导入审核、待生成资料与已生成批次双页签、报备明细人工状态、企业营业执照文案、利润成功分片成本、企业余额删除门禁、恢复状态和下游投递近7天筛选,以及签名通道×运营商发送质量统计。
  • 演示数据脚本仅作为本地视觉验收工具纳入源码,不属于部署初始化或migration;脚本必须显式设置ALLOW_LOCAL_SIGNATURE_QUALITY_DEMO=true、数据库主机必须为localhost,并在NODE_ENV=production时无条件拒绝执行,预发布部署不会写入演示数据。
  • 发布前重新确认HEADorigin/main均为352a6293b47f95653fbb079f2cf528fba4d59818,工作区修改来自前序多个会话,按用户明确要求统一归入本次发布;outputs/、空文件=api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfo继续作为构建或临时产物排除。
  • 首次API全量测试因本地Redis未运行导致3个发送链用例连接等待超时;恢复本地Redis后重跑,API全量26 suites / 366 tests全部通过。Prisma format/validate/generate、API TypeScript正式构建、前端TypeScript/Vite生产构建、Gateway go test ./...go vet ./...、依赖安全门禁和git diff --check均通过;Vite仅保留既有大chunk提示,Jest保留既有--forceExit异步句柄提示。
  • 汇总功能提交99c8c7c68b5eb7cd0f63f0c70d376c257cc18c61feat: complete reporting and filing workflows)已创建并推送至origin/main;首次推送被内部Git服务瞬时返回Failed to authenticate user,保持提交和工作区不变后原样重试成功。
  • 精确Git归档包含445个跟踪文件、1783539字节,本地与服务器SHA-256均为6807fc83778437b80798b9c5efd1b9897307cb69de1c29c076d3ab58462d8e48,服务器tar完整性校验通过。部署前PostgreSQL、运行源码和环境文件备份位于/opt/cmpp-platform/backups/releases/20260728-203014-before-99c8c7c6SHA-256依次为9c3fee92363483ba78a43bd24173acfd1ccfc37aee39ccdd7da84df8043e340f3ef84c58775c0dbf90b7e0b8c19e1caac8350afbef214e49d6dde91ec1bc1e49189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7gzip、tar和sha256sum -c全部通过;旧运行目录保留为/opt/cmpp-platform.previous-20260728-203034
  • 标准部署脚本完成两套npm ci、依赖安全门禁、Prisma生成、前端/API/Gateway构建及Gateway先于API重启;新migration20260728153000_stage_report_material_import_reviews应用成功,预发布共75条migration。演示企业计数为0,证明本地签名质量演示脚本未执行、未写入预发布数据。
  • 部署后cmpp-apicmpp-gateway、Nginx、PostgreSQL和MinIO均activeRedisPONG12026/17890/8090/3000/6379/5432/9000均监听,API/Gateway health、公网首页、运营端、客户端和API health均HTTP 200,公网CMPP 17890 TCP可连接。Redis Stream消费者1、pending=0lag=0,发布后API/Gateway无error级journal。
  • 4条active供应商通道中3条恢复connected 1/1会员营销-富泷保持failed 0/1,数据库明确记录authentication / connect response status: auth failed并进入既有自动重连窗口,该状态属于当前上游鉴权配置/外部连接事实,本次未擅自修改通道账号或状态。120秒内活跃下游客户连接为0。
  • 本次未发送、重投或补发真实短信,未执行本地演示数据脚本,未修改通道配置或客户连接状态。发布运行代码为99c8c7c68b5eb7cd0f63f0c70d376c257cc18c61

2026-07-28 签名发送质量运营商概览业务短信口径(本地未提交)

  • 数据统计“签名通道发送质量”的查看明细中,运营商概览不再累加通道提交尝试,改为按真实SmsMessageRecord业务短信统计;同一短信发生通道切换或补发仍只计一条。卡片数量文案由“XX次”改为“XX条业务短信”。
  • 运营商概览的“成功率”改名为“最终成功率”,按该运营商最终送达成功的业务短信数除以业务短信总数计算;平均到达时间同步取最终成功业务短信的deliveredAt - submittedAt。下方“通道 × 运营商矩阵”继续保留真实SmsSubmitRecord提交尝试口径,不与业务短信口径混算。
  • 后端GET /admin/operations/signature-quality新增独立运营商业务短信汇总,数据直接来自PostgreSQL,不使用前端去重、mock、静态数据或localStorage。需求文档和系统功能测试用例已同步补充补发去重及最终成功率规则。
  • Node.js v24.14.0下Operations定向1 suite / 24 tests、API TypeScript正式构建、前端TypeScript检查和Vite生产构建通过;Vite仅保留既有大chunk提示。预发布PostgreSQL只读执行等价聚合SQL成功并返回真实运营商分组,验证业务短信数、最终成功数、最终成功率和平均到达时间字段可执行;本地5432未运行,因此未虚报本地数据库验证。
  • 本轮按用户要求保持未提交、未推送、未部署;既有api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/及空文件=继续保留且不纳入代码提交。

2026-07-28 待生成报备批次搜索区宽度统一(发布前门禁)

  • “待生成资料”搜索区将资料类型收窄为160px,将“企业/应用/签名/站点”关键字控制在200~260px,并把剩余主要空间分配给“资料变更时间”;“已生成批次”将批次号控制在220~260px、批次生成时间固定为300px,避免日期条件无意义拉满。
  • 新增全局.ui-query-actions查询操作区样式,查询和重置按钮统一为88px,不再由当前Grid隐式拉伸重置按钮。980px及以下两个页签统一切换为两列搜索布局,操作按钮独占下一行,避免横向溢出。
  • 需求文档新增搜索区尺寸规则,系统功能测试新增TC-REPORT-BATCH-007覆盖桌面和平板布局;筛选查询、重置及真实后端分页逻辑未改动。
  • 本次发布门禁覆盖此前未提交的“签名发送质量运营商概览业务短信口径”和本次搜索区调整:Node.js v24.14.0下API全量26 suites / 366 tests通过,Prisma format/validate/generate、API TypeScript正式构建、前端TypeScript/Vite生产构建、Gatewaygo test ./...go vet ./...、依赖安全门禁和git diff --check通过;Vite仅保留既有大chunk提示,Jest保留既有--forceExit异步句柄提示。
  • 应用内浏览器接管检查确认当前没有已登录运营会话,目标路由被真实鉴权守卫跳转至图形验证码登录页;未绕过验证码,因此发布前未把登录页冒充为两个页签的视觉验收。发布后仍需在有效运营会话下复核两页签桌面和平板宽度。

2026-07-28 95c052e9 预发布记录

  • 功能提交95c052e9ea987f58c34002543331c2b75f36c642fix: align reporting filters and carrier quality)已提交并推送至origin/main,包含签名运营商概览业务短信/最终成功率口径、待生成报备批次搜索区宽度优化、全局等宽查询操作按钮及同步需求/测试/进度文档。既有构建缓存、outputs/和空文件=未纳入提交。
  • 精确Git归档包含445个跟踪文件、1786373字节,本地与服务器SHA-256均为6d5d39021e2edd984e3d6137101e9daf3eba62bf92668ad8fe0fe53dfb0b4038,服务器tar完整性校验通过。部署前PostgreSQL、运行源码和环境文件备份位于/opt/cmpp-platform/backups/releases/20260728-205719-before-95c052e9SHA-256依次为637d39d2c34a7aa888584b745797e34f966e14508bd1e95930fa7aaa9df97b4633519dae970b725a603d71fd24cb3c6ea917652de2fb8f4962386ec968c73e13189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7;旧运行目录保留为/opt/cmpp-platform.previous-20260728-205719
  • 标准tools/deploy/production-deploy.sh完成依赖安装、自定义依赖缓解门禁、Prisma生成、migration、前端/API/Gateway构建及Gateway先于API重启;75条migration齐全且无待执行项。npm当前公告仍报告根项目React Router未使用的RSC模式2个high、API的Prisma工具链Valibot 3个moderate,自定义门禁确认PostCSS补丁、未使用React Router RSC、brace expansion边界均有效;未将其误报为npm audit=0,后续依赖升级需单独处理兼容性。
  • .deployed-commit=95c052e9ea987f58c34002543331c2b75f36c642API、Gateway、Nginx、PostgreSQL、MinIO和Redis均active12026/17890/8090/3000/6379/5432/9000均监听,API/Gateway health与Redis PONG通过。gateway.submit.commands消费者1、pending=0lag=0,12个通道TPS配置键存在,发布后API/Gateway error级journal为0。
  • 公网首页、运营端、客户端和API health均HTTP 200,公网CMPP 17890 TCP可连接。4条active供应商通道中3条为connected 1/1;“会员营销-富泷”为failed 0/1,数据库记录authentication / connect response status: auth failed并保留系统自动重连,未修改账号、密码或启停状态。120秒内活跃下游客户连接为0。
  • 部署源码和前端产物均包含.ui-query-actions、两个报备筛选布局类及“条业务短信”新口径文案。应用内浏览器仍因无已登录运营会话停留在图形验证码登录页,未绕过验证码或虚报登录后视觉验收;本次未发送、重投或补发真实短信。

2026-07-28 全业务列表后端分页与短信记录性能修复(发布前)

  • 预生产短信记录页面卡顿根因已定位:页面一次读取443条短信及其760条提交、1492条回执和435条下游投递,JSON约4.47MB,再在浏览器切出25条;数据库基础查询不足1ms,主要耗时来自不必要的关联装载、序列化、网络传输和前端解析。
  • 除用户明确排除的“通道组”外,显式浏览器切片分页已全部移除。运营端短信记录、短信任务、报备任务/记录、企业应用/签名/模板、短信通道、上行短信和充值记录,以及客户端短信明细、批量任务、应用、签名/引流、模板、上行短信和充值记录,均改为真实PostgreSQL分页与后端筛选。
  • 短信记录列表改为当前页最小字段与当前页关联数据,新增独立后端CSV导出;企业应用、签名下拉改用轻量选项接口。新增分页排序索引migration 20260728223000_optimize_list_pagination,部署脚本为JSON及静态文本资源启用gzip并在重启前执行nginx -t
  • Prisma format、validate、generate通过;Node.js v24.14.0下前端与API TypeScript检查通过。API全量26 suites / 367 tests全部通过,新增短信记录数据库分页页码、容量、总数及目标页关联约束;Jest仅保留既有--forceExit异步句柄提示。后续构建、Gateway、安全门禁、提交、推送及预生产部署结果在本节继续补记。
  • 既有api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/和空文件=继续视为构建/临时产物,不纳入提交。

2026-07-28 列表分页性能修复预生产发布记录

  • 功能提交b8560372cc79eb405d49ef97fd51db60067b169a和gzip MIME修正提交fbacb7454463e305d3ae65ebaf23882eb85bf487已推送。首次功能提交推送被内部Git服务瞬时返回Failed to authenticate user,保持提交不变后重试成功。
  • 功能归档446个跟踪文件、1794168字节,本地与服务器SHA-256均为50ff817c2ecdc358fd10317d6ff1690884d9bd62fc2fa3d307e77c18000f152d。首次发布前备份位于/opt/cmpp-platform-backups/releases/20260728-232144-before-b8560372,PostgreSQL、运行源码和环境文件SHA-256依次为ea6471078f202f3115a7dc839dc57f96e4d535f7390cbb6a76b0ccfe742442b9eee5bc85d6ad3bd52f163a68634a48ef8003b9498b687b0b354095000926c259189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7
  • gzip修正归档1794162字节,本地与服务器SHA-256均为1c05f83affdbf7388d665cbfe241c497606dd293f54e2aa01026e62ed56bd803。修正发布前备份位于/opt/cmpp-platform-backups/releases/20260728-232640-before-fbacb745,PostgreSQL、运行源码和环境文件SHA-256依次为2018116642f58ebd9af961cd989d54b1f70a8ccaaf8e5fa0d279b5819b068bc601d9ca07994188205006f40489d6349b2672c438d11653d96ea1bbc6ae084801189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7
  • 标准tools/deploy/production-deploy.sh完成依赖安装、安全门禁、Prisma、前端/API/Gateway构建和Gateway先于API重启。新migration20260728223000_optimize_list_pagination应用成功,预生产共76条migration且无待执行项。
  • 发布后真实OperationsService在与问题复现相同的2026-07-272026-07-28范围查询第一页25条:总数443,当前页46条提交、90条回执、25条下游投递,序列化后约110139字节,真实PostgreSQL查询及对象构造耗时约171.4ms;原全量响应约4.47MB,体积下降约97.6%。Nginx对Vite的text/javascript资源真实返回Content-Encoding: gzip,不是仅写配置未生效。
  • API、Gateway、Nginx、PostgreSQL、MinIO和Redis均active12026/17890/8090/3000/6379/5432/9000监听;内外健康接口、首页、运营端和客户端均HTTP 200,公网CMPP 17890可连接。Redis Stream消费者1、pending=0lag=0API/Gateway近10分钟error级journal为0。
  • 4条active供应商通道均为connected 1/1;最近120秒活跃下游客户连接为0。本轮未发送、重投或补发真实短信,未修改通道账号、密码、启停状态、企业余额或客户连接。

2026-07-29 企业应用列表 Prisma 字段回归修复(发布前)

  • 预生产企业应用页面和企业应用黑名单页面 HTTP 500 已定位为列表查询 omit 错误引用 DTO/响应别名 passwordCipher;真实 SmsApplication 模型只保存敏感字段 secretHashPrisma 7.9.0 在执行 SQL 前抛出 PrismaClientValidationError
  • 企业应用列表查询已移除不存在的 passwordCipher,继续明确排除真实敏感字段 secretHash。企业应用黑名单改为调用轻量企业应用选项接口,不再为了筛选项加载连接状态、统计及完整关联;本次修复不修改企业、应用、黑名单、通道、余额或短信数据。
  • 新增回归断言:企业应用查询的 omit 必须等于 { secretHash: true },且每个排除字段都必须存在于当前生成 Prisma Client 的 SmsApplication DMMF 模型,避免 Mock 测试再次接受不存在的数据库字段。
  • 代码检查确认短信入库和通道路由不会调用手机号段页面分页接口:运营商直接读取启用的 PhoneCarrierRule,省份通过唯一索引 PhoneSegment.prefix 逐级精确查询;本次页面列表错误不影响号码段识别链路。
  • Node.js v24.14.0 下短信配置定向 1 suite / 62 tests、API 全量 26 suites / 367 tests 全部通过;Prisma format、validate、generate、API TypeScript 正式构建、前端 TypeScript/Vite 生产构建、Gateway go test ./...go vet ./...、依赖安全门禁和 git diff --check 均通过。Jest 仅保留既有强制结束异步句柄提示,Vite 仅保留既有大 chunk 体积事实。
  • 发布前使用预生产真实 Prisma Client 和 PostgreSQL 只读执行 SmsApplication.findMany(... omit: { secretHash: true }) 成功返回 10 条企业应用,结果中 secretHash 泄漏计数为 0;未写入或修改预生产数据。
  • 既有 api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/ 和空文件 = 继续作为构建或临时产物保留,不纳入提交。

2026-07-29 短信号码路由查询降载(本地未提交)

  • 预生产只读诊断确认手机号段 516217 条、全部为 7 位且省份完整,唯一前缀索引单次执行约 0.058ms;运营商规则 30 条,单次全量读取约 0.044ms。最近 24 小时仅 41 条短信、峰值 2 条/分钟,因此当前不是线上瓶颈,但发送 Worker 并发 50 与默认 10 个 PostgreSQL 连接组合下存在批量放大风险。
  • 使用预生产真实 PostgreSQL 和最近 100 个真实号码进行只读微基准:当前每条正常号码 2 次查询,顺序总耗时约 108ms;连接池预热并发 50 时号码识别部分 100 条约 86ms、单条 P50 约 40ms;缓存规则后 100 条约 20ms。基准只覆盖号码识别,不等同于完整短信发送耗时。
  • 新增共享 PhoneRoutingLookupService:30 条启用规则编译后默认缓存 30 秒,并发冷加载合并;规则新增和删除成功后立即失效,失效前正在执行的旧加载不会覆盖新缓存。多实例场景仍由 TTL 限定其他实例最多 30 秒陈旧窗口。
  • 省份识别由最多 5 次 findUnique 改为一次 7 位至 3 位候选前缀 findMany,在内存中选择最长命中;未知号码同样只查询一次。运营商路由仍由独立 PhoneCarrierRule 决定,不改变广电等业务归类口径。
  • 首次路由继续把运营商和省份写入真实 SmsMessageRecord;后续补发检测到已持久化运营商时直接复用运营商及省份(含 province=null),不再重复读取规则和号段。
  • Node.js v24.14.0 下新增路由服务及发送链定向 3 suites / 122 tests、API 全量 27 suites / 374 tests 全部通过;Prisma format、validate、generate、API TypeScript 正式构建、前端 TypeScript/Vite 生产构建、Gateway go test ./...go vet ./...、依赖安全门禁和 git diff --check 均通过。首次直接使用系统默认 Node.js v14.17.4 执行安全门禁因运行时过旧失败,切换到项目验证用 Node.js v24.14.0 后通过;本机 5432 未监听,因此未虚报本地数据库实测。
  • 本轮按用户要求只保留本地未提交修改,不提交、不推送、不部署;既有构建缓存、outputs/、空文件 =tsconfig.tsbuildinfo 继续原样保留。

2026-07-29 运营看板与短信记录运营商筛选(本地未提交)

  • 运营看板“今日发送趋势”已改为上海时区 24 个小时桶的真实折线图,同时展示业务短信提交总条数和最终成功条数;后端按 SmsMessageRecord.queuedAt/status 聚合并为无数据小时补零。
  • “审核处理趋势”已更名为“审核处理速度”,按企业认证、短信审核、模板、签名、引流信息展示北京时间当天已完成数量及平均处理时长。企业认证、短信审核、引流信息使用各业务表提交/审核时间;签名和模板使用同一对象最近一次进入 pending 的审计记录与审核完成审计配对,负时长和无法配对的历史数据不参与平均值。
  • 签名通道发送质量详情的运营商概览已显式固定为移动、联通、电信顺序,未识别项排在其后,不依赖数据库聚合返回顺序。
  • 运营端短信记录新增全部、移动、联通、电信、未识别筛选;真实后端条件同时用于数据库分页、总数和 CSV 导出。兼容 mobile/cmcc/移动/中国移动 等历史值,空值及非三大运营商值归入未识别。
  • Node.js v24.14.0 下 Operations 定向 1 suite / 26 tests、API 全量 27 suites / 375 tests 全部通过,API TypeScript 正式构建、前端 TypeScript 检查和 Vite 生产构建通过;全量 Jest 仅保留既有强制结束异步句柄提示,Vite 仅保留既有约 1.99MB 单 chunk 提示。首次通过系统 npm 启动定向测试未在 120 秒内输出,终止该次遗留测试进程后改用 Node.js v24 直接运行 Jest,测试正常完成,未将超时计为通过。
  • 本机 PostgreSQL 5432 未监听。预发布 PostgreSQL 只读执行等价 SQL 成功:当天小时聚合返回 6 个有数据小时;审核速度 SQL 执行成功且当天无已完成审核样本;运营商真实存量分组为移动 575、联通 138、电信 121、未识别 87。验证过程未写数据库、未发送短信、未修改通道或企业数据。
  • 本轮按用户要求保持未提交、未推送、未部署。工作区中另一会话既有的号码路由优化代码和文档继续保留,本节不将其归因于本需求。

2026-07-29 短信审核列表信息布局调整(本地未提交)

  • 短信审核列表由原 8 列压缩为 6 列:发送企业与企业应用、提交时间与审核来源、号码数量与状态分别在同一单元格内上下分层展示;短信内容列设置为 440px 主要宽列。
  • 号码数量仍打开真实后端分页号码列表,审核状态、详情、勾选、批量通过和驳回逻辑均未改变;本次没有新增 mock、静态数据或 localStorage 数据路径。
  • 工作区中既有号码路由优化及另一会话的运营看板、短信记录运营商筛选修改全部保留,本节不将其归因于本需求。
  • 恢复 package-lock.json 锁定依赖后,Node.js v24.14.0 下前端 TypeScript 检查和 Vite v8.0.16 生产构建通过,2442 个模块完成转换;仅保留既有约 1.99MB 单 chunk 提示。首次误用捆绑 pnpm 触发包管理器不一致保护并生成的两个临时 pnpm 文件已精确清理,没有纳入工作区修改。
  • 本地 PostgreSQL、API 和前端预览启动成功,应用内浏览器及 Chrome 均无现成的本地运营登录会话,目标路由被真实鉴权跳转至图形验证码登录页。未绕过验证码,故未把登录页冒充短信审核列表的视觉和号码弹窗交互验收;本次启动的 PostgreSQL、API 和前端进程已清理,原先已运行的 Redis 保持不变。
  • 本轮按用户要求只保留本地修改,不提交、不推送、不部署。

2026-07-29 号码路由、运营视图与短信审核布局汇总发布门禁

  • 用户已明确授权将当前工作区代码提交、推送并发布到预生产。本次汇总范围为:号码路由规则缓存和单次最长前缀查询、运营看板逐小时发送趋势和审核处理速度、短信记录运营商真实后端筛选、签名质量运营商排序,以及短信审核组合单元格布局。
  • 发布前 main、本地 HEADorigin/main 均为 500f43f673408900c3d658051d67cf0602f6005a。工作区中不同会话形成的上述有效源码、测试和文档统一纳入本次授权范围;api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/ 和空文件 = 继续作为构建缓存或临时产物排除。
  • 预生产只读基线确认 .deployed-commit=500f43f673408900c3d658051d67cf0602f6005a76 条 migration 已应用且与源码目录一致。API、Gateway、Nginx、PostgreSQL、Redis、MinIO 均 active12026/17890/8090/3000/6379/5432/9000 监听,内外健康接口和首页、运营端、客户端均 HTTP 200。
  • 发布前 Redis Stream gateway.submit.commands 消费者 1、pending=0lag=0,12 个通道 TPS 配置键存在;4 条 active 供应商通道均为 connected 1/1,最近 120 秒活跃下游客户连接为 0,API/Gateway 近 30 分钟 error 级 journal 均为 0。
  • Node.js v24.14.0 下 API 全量 27 suites / 375 tests 全部通过;Prisma format、validate、generate、API TypeScript 正式构建、前端 TypeScript/Vite v8.0.16 生产构建、Gateway go test ./...go vet ./...、依赖安全门禁和 git diff --check 均通过。Vite 仅保留既有约 1.99MB 单 chunk 提示,Jest 仅保留既有强制结束异步句柄提示。
  • 本次没有新 migration;发布过程不得发送、重投或补发真实短信,不修改供应商通道账号、密码、启停状态、企业余额或客户连接。提交、推送、备份、部署和发布后验证结果在本节后续补记。

2026-07-29 c0a4317a 预生产发布记录

  • 功能提交 c0a4317a7ea641bab39294e596f58f859edfca73feat: optimize routing and operations views)包含 21 个源码、测试和文档文件,已推送至 origin/main。首次推送被内部 Git 服务瞬时返回 Failed to authenticate user,保持提交、索引和工作区不变后原样重试成功;构建缓存、outputs/ 和空文件 = 未纳入提交。
  • 精确 Git 归档包含 448 个跟踪文件、1,804,602 字节,本地和服务器 SHA-256 均为 4d37a6deb9f0cb9497d73dcbd44531f5b3e293a71ae3aa99401d3cc0352299dc,服务器 tar 完整性校验通过。
  • 发布前 PostgreSQL、运行源码和环境文件备份位于 /opt/cmpp-platform-backups/releases/20260729-223616-before-c0a4317a。数据库备份 7,227,624 字节、SHA-256 05d63761458c51cb2667eee7d7296974be42de466bb6c8d602ede6a42aa64a9f;源码备份 2,147,955 字节、SHA-256 986ad77fd982a2870f03b02f3866d12f11db36430aa775f7ee59fd4a4bcfe62e;环境文件 850 字节、SHA-256 189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三份文件权限为 600,gzip、tar 和 sha256sum -c 全部通过;上一运行目录保留为 /opt/cmpp-platform.previous-20260729-223721
  • 标准 tools/deploy/production-deploy.sh 完成两套依赖安装、自定义依赖缓解门禁、Prisma generate/migrate、前端/API/Gateway 构建、Nginx 配置检查和 Gateway 先于 API 重启。预生产 76 条 migration 齐全且无待执行项;npm 仍公告根项目未使用 React Router RSC 路径的 2 个 high 和 API Prisma 工具链的 3 个 moderate,自定义门禁确认既定缓解有效,未执行破坏兼容性的 audit fix --force
  • .deployed-commit=c0a4317a7ea641bab39294e596f58f859edfca73。Gateway、API、Nginx、PostgreSQL、Redis、MinIO 均 active12026/17890/8090/3000/6379/5432/9000 监听;API/Gateway health 和 Redis PONG 通过。公网首页、运营端、客户端及 API health 均 HTTP 200,公网 CMPP 17890 TCP 可连接。
  • Redis Stream gateway.submit.commands 消费者 1、pending=0lag=0,12 个通道 TPS 配置键存在。4 条 active 供应商通道中“会员营销-富泷”重启后首次鉴权短暂出现 authentication / connect response status: auth failed,保留系统自动重连且未改账号、密码或启停状态;观察窗口内自行恢复,最终 4 条均为 connected 1/1。最近 120 秒活跃下游客户连接为 0。
  • 部署后使用真实 Prisma Client 和 PostgreSQL 只读执行新路径:运营看板返回 00:00~23:00 共 24 个小时桶和企业认证、短信审核、模板、签名、引流信息 5 类审核速度;短信记录运营商筛选真实计数为移动 630、联通 145、电信 138、未识别 87。共享号码路由服务并发识别 3 次只加载 1 次运营商规则,真实号码和未知号码各用 1 次号段查询,均返回预期结果。
  • 尝试受保护 HTTP 验证时,部署管理员凭据文件的 password=unchanged 标记被误当成密码提交一次并返回 401;未继续猜测或绕过认证。随后使用部署自带 ensure-production-admin.mjs 将该部署管理员失败计数恢复为 0,确认未锁定。发布后 API/Gateway error 级 journal 和 panic/fatal/unhandled/Prisma 关键错误匹配均为 0。
  • 本次未发送、重投或补发真实短信,未修改供应商通道凭据或启停状态、企业余额、客户连接和短信业务数据。

2026-07-29 运营看板今日发送趋势小时分桶时区修复(本地未提交)

  • 预生产只读核验确认“01:00 提交 128 条”并非真实凌晨发送:对应 SmsMessageRecord.queuedAt 存储值为 UTC 2026-07-29 01:19:4101:50:42,正确北京时间为 09:19:4109:50:42
  • 根因是 queuedAt 在 PostgreSQL 中为 timestamp without time zone 并按 UTC 保存,原聚合 SQL 直接执行 queuedAt AT TIME ZONE 'Asia/Shanghai',把 UTC 墙上时间错误解释为上海本地时间,小时桶整体提前 8 小时且受数据库会话时区影响。
  • 小时分桶改为先用 AT TIME ZONE 'UTC' 将存储值解释为 UTC,再用 AT TIME ZONE 'Asia/Shanghai' 转为北京时间后提取小时;新增 SQL 结构回归断言,并在需求和 TC-DASHBOARD-007 中明确 UTC 存储及会话时区无关性。
  • Node.js v24.14.0 下 Operations 定向 1 suite / 26 tests 全部通过,API TypeScript 正式构建通过。预生产真实 PostgreSQL 只读执行修正后的等价 SQL,在会话时区分别设置为 UTC 和 Asia/Shanghai 时,128 条记录均稳定归入北京时间 09:00,未落入 01:00
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署;既有构建缓存、outputs/、空文件 =tsconfig.tsbuildinfo 继续原样保留。

2026-07-30 号码发送频次风控(本地未提交)

  • 按用户确认口径新增两条全局兜底:北京时间自然日 10 条、固定 5 分钟 5 条;隔离键为企业应用、号码和规则,两条规则独立覆盖与命中,首版统一直接拒绝。
  • 新增PhoneFrequencyState实时状态和PhoneFrequencyHit历史触发模型及 migration 20260730093000_add_phone_frequency_controls。计数通过 PostgreSQL INSERT ... ON CONFLICT DO UPDATE ... RETURNING原子占用;大批量号码按 1000 条分块写入但保持同一数据库事务,避免 PostgreSQL 参数数量上限。
  • 客户端批量、公开 HTTP 和 CMPP 单号码入口已接入同一频控服务。非法/黑名单号码和任务级已拒绝记录不计数;命中号码按业务短信记录直接失败且金额为 0,未命中号码继续发送,长短信分片与通道补发不重复计数。
  • 风控规则页新增两类规则定义,应用级阈值可分别覆盖全局规则,后端强制正整数阈值和直接拒绝动作;新增真实触发记录分页、号码/状态/应用范围查询及“解除并清零”操作。解除原因必填,保留历史触发记录并写操作审计。
  • Prisma format、validate、generate通过;API TypeScript正式构建和前端 TypeScript/Vite生产构建通过。新增频控服务 1 suite / 2 tests、发送链 1 suite / 104 tests、原风控 1 suite / 15 tests均通过;API 全量 28 suites / 380 tests全部通过。发送链及全量测试需沿用项目既有--forceExit开放句柄处理,首次未带该参数运行在工具时限内未自行退出,未将超时计为通过。
  • 本地真实 PostgreSQL 已应用全部 77 条 migration,其中包含20260730093000_add_phone_frequency_controls。6 个同应用同号码并发占用的结果为 5 个放行、1 个拒绝,状态计数 6、活跃命中 1 条;后续提交继续拒绝且计数冻结为 6。人工解除后计数归零、代次从 0 增至 1,同周期再次越线成功生成新代次命中;日规则与 5 分钟规则独立生效。验证使用专用测试号码,状态、命中和操作日志均已清理。
  • 本地 API 关闭发送 Worker 后连接真实 PostgreSQL 启动成功,Vite production preview 可正常渲染且控制台无错误;访问风控规则目标路由被真实鉴权跳转至图形验证码登录页。codex_local_admin在本地数据库中复核为 active、平台管理员、失败次数 0 且未锁定,但本轮未请求用户授权代解验证码,因此未把登录页冒充规则页视觉和解除弹窗交互验收。Vite dev 模式另出现既有cookie.parse导出不兼容白屏,改用成功生产构建的 preview 后消失,未修改依赖。
  • 验收启动的本地 API、Vite dev/preview 和 PostgreSQL 已停止;原先已运行的 Redis 保持不变。当前仍缺登录后规则页桌面/窄屏视觉和解除弹窗交互验收,未提前宣称该项通过。
  • 本轮按用户要求保持本地未提交、未推送、未部署。另一会话既有的运营看板小时分桶时区修复及其文档修改继续保留,不归因于本需求;构建缓存、outputs/、空文件=tsconfig.tsbuildinfo继续原样保留。

2026-07-30 平台级号码频控白名单(本地未提交)

  • 按用户确认口径新增平台级号码白名单:启用号码在全平台所有企业应用下均豁免24小时和5分钟号码频控,其他号码校验、黑名单、内容审核、余额、路由及其他风控不受影响。
  • 新增PhoneFrequencyWhitelist模型及 migration 20260730114500_add_phone_frequency_whitelist,号码全平台唯一,记录启用/停用/软删除状态、用途说明、备注、创建人、最后操作人和时间;创建人、更新人及状态时间均建立相应索引。
  • 后端提供真实数据库分页、状态/号码/关键字/更新时间查询及新增、修改、停用和软删除接口。批量发送在频控事务内按1000个号码分块读取启用白名单,不使用逐号码查询、Mock、静态数据或localStorage。
  • 新增/恢复启用、改号、启停和删除会在同一事务中清零相关号码在所有应用和两类规则下的当前状态,并解除活跃命中;白名单及频控命中历史均保留,所有写操作写入运营审计。
  • 运营端风控规则页新增“平台级号码频控白名单”区域,提供号码/状态查询、真实分页、新增、编辑、启停和填写原因后删除,页面明确说明仅豁免两类号码频控及跨应用生效范围。
  • Prisma format、validate、generate通过;API TypeScript正式构建、前端TypeScript检查及Vite v8.0.16生产构建通过。号码频控服务定向1 suite / 3 tests、API全量28 suites / 381 tests全部通过;全量Jest仅保留项目既有--forceExit开放句柄提示,Vite仅保留既有约1.99MB单chunk提示。
  • 本地真实PostgreSQL已应用全部78条migration。专用验收号码先在应用A形成24小时计数6和5分钟计数6/活跃命中1条;新增启用白名单后两类状态均归零且活跃命中被解除;在应用B连续占用12次未产生任何频控状态;删除白名单后应用B两类计数均从1重新开始。白名单、状态、命中和审计验收数据均已清理。
  • 本地API以关闭发送Worker、扫描任务和通道重连的安全配置连接真实PostgreSQL运行,/api/health返回HTTP 200;前端production preview的目标路由返回HTTP 200且控制台无warning/error。应用内浏览器无既有登录会话,真实鉴权将目标路由跳转至图形验证码登录页,未获本轮授权代解验证码,因此未把登录页冒充白名单区域的登录后视觉验收。
  • 本地API继续监听3000,前端production preview继续监听4173PostgreSQL和Redis分别继续监听5432、6379,供用户本地查看。当前按用户要求保持未提交、未推送、未部署;另一会话的运营看板小时分桶修改继续保留且不归因于本需求,构建缓存、outputs/、空文件=tsconfig.tsbuildinfo继续原样保留。

2026-07-30 客户端工作台与短信发送体验完善(本地未提交)

  • 客户端 Dashboard 新增真实企业概览:企业名称来自Tenant,认证状态按是否存在已通过EnterpriseCertification判定,签名数量排除已删除和已禁用签名,待审核批量任务独立统计当前企业sourceType=client/status=pending_reviewSmsBatchTask。这些独立查询与原 Dashboard 聚合并行执行。
  • 工作台账户状态改为已认证/未认证,企业主体展示企业名称,默认签名改为签名数量;快捷操作移除“真实”字样。模板、签名、批量任务卡片分别展示真实待审核数量并可进入对应菜单。
  • 客户端今日发送趋势改为消费后端00:00~23:00共24个北京时间小时桶;继续包含另一会话尚未提交的 UTC 存储时间到上海时区双重转换修复,不将其归因于本需求。
  • 签名与引流信息页的“重置”增加刷新代次,即使筛选条件已经为空也会重新请求真实签名工作区;运营端企业认证审核和短信模板审核的初始及重置状态改为待审核。
  • 短信发送预计条数改为70字符内1条、长短信每67个Unicode字符一条,并随正文和有效号码数即时计算;单价单位改为元/条。提交失败使用中央弹窗,提交成功弹窗展示真实任务编号和号码数,可清空表单继续发送或携带任务编号进入批量任务页。
  • 定时发送日期控件新增按Asia/Shanghai计算的“今天”按钮和当天浅色标识,提交时把页面选择值显式规范为+08:00;不依赖用户浏览器或服务器默认时区解释业务时间。
  • Operations 定向1 suite / 26 tests、API全量28 suites / 381 tests全部通过;API TypeScript正式构建、前端TypeScript检查和Vite v8.0.16生产构建通过,2442个模块完成转换。Jest仅保留项目既有--forceExit开放句柄提示,Vite仅保留既有约2.00MB单chunk提示,git diff --check通过。
  • 本地真实PostgreSQL只读执行企业名称、已通过认证、有效签名和待审核客户端批量任务等价查询成功;样本同时覆盖已认证和未认证企业,未写入或修改认证、签名、任务和短信数据。
  • 本地API health和production preview均HTTP 200,浏览器加载前端无框架错误覆盖层且控制台无warning/error;目标客户端路由被真实鉴权跳转到图形验证码登录页。未获授权处理验证码,因此未把登录页当作工作台、短信发送、日期控件和成功/失败弹窗的登录后视觉及交互验收。
  • 本轮未提交发送任务、未发送真实短信,也未修改企业余额、通道、客户连接或预生产数据。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署。号码频控、平台白名单及其migration、发送链、风控页面和文档是另一会话既有修改,继续完整保留且不归因于本需求。

2026-07-30 R0 渐进式拆分安全护栏(本地未提交)

  • R0 已按“先锁定行为、不移动生产代码”的范围完成。新增大文件职责与副作用索引,覆盖 SendChainService、Gateway 入站/上游、Channels、SmsConfig、Operations、ReportMaterials、adminApi 和全局样式,并记录直接调用者、主要数据库表、队列/外部副作用、事务与幂等不变量。
  • 新增单版本唯一结构修改会话规则、开始前/实施中/提交前/发布观察清单、立即停止条件和回滚记录模板。后续 R1~R11 每个版本仍需重新核对 Git 与部署事实,不能把本轮基线提交视为永久事实。
  • 新增机器可执行的 tools/quality/verify-refactor-r0.mjsdocs/contracts/refactoring-r0-manifest.json,固定 8 个稳定门面、Redis Stream 四类契约样例、CMPP 2.0/3.0 报文、Gateway ACK/重连以及发送链和账务并发幂等测试入口。R0 门禁和现有队列契约校验均通过。
  • Node.js v24.16.0 下 API 全量 28 suites / 381 tests 全部通过;API TypeScript 正式构建、前端 TypeScript 与 Vite v8.0.16 生产构建、Prisma format/validate/generate、Gateway go test ./...go vet ./...、依赖安全门禁和 git diff --check 全部通过。Jest 仅保留项目既有 --forceExit 开放句柄提示,Vite 仅保留既有约 2.00MB 单 chunk 提示。
  • R0 没有新增或修改业务接口、数据库 schema、migration、Redis Stream 消息或 CMPP 行为,没有启动新服务、写数据库或发送短信。当前工作区既有号码频控/白名单、客户端体验、运营看板等其他修改及构建产物均完整保留,不归因于 R0。
  • 本轮按用户要求仅保留本地未提交修改,不提交、不推送、不部署。

2026-07-31 R1 前端 API 兼容门面拆分(本地未提交)

  • 按路线图完成 R1.1R1.5。原src/api/adminApi.ts从2292行缩减为19行稳定兼容门面;现有页面仍统一从该文件导入,不批量修改73处调用位置。
  • 通用HTTP、错误解析、401退出、SESSION_LOCKED、最近认证、租户请求头、Blob、multipart和查询参数逻辑移动到src/api/core/httpClient.ts;函数体与拆分前逐项一致。运营端按身份与企业、通道与报备、运营查询、审核风控账务、文件上传拆成五个领域对象;客户端API和会话API独立。
  • 104个公开类型按common、identity-config、channels-reports、operations、governance五个领域拆分并由统一barrel重导出。最大业务API文件194行,最大类型文件580行;没有新增循环运行时依赖,跨领域引用均为type-only import。
  • 新增docs/contracts/admin-api-r1-methods.jsontools/quality/verify-admin-api-r1.mjs。门禁确认183个运营端方法、60个客户端方法、7个会话方法及9个HTTP核心函数的实现哈希与拆分前一致,同时确认adminApiclientApiportalSessionApifileDownloadUrl稳定导出仍存在;R0门禁继续通过。
  • Node.js v24.16.0下前端TypeScript检查及Vite v8.0.16生产构建通过,2456个模块完成转换;API全量28 suites / 381 tests、API TypeScript正式构建、Gatewaygo test ./...go vet ./...、依赖安全门禁和git diff --check全部通过。Jest仅保留既有--forceExit开放句柄提示,Vite仅保留既有约2.00MB单chunk提示。
  • 应用内浏览器访问http://localhost:4173/#/admin/login,页面标题为“聆界短信管理平台”,登录表单和验证码正常渲染;点击验证码后真实算式发生变化,控制台无warning/error且无框架错误覆盖。未获授权求解验证码和登录,因此登录后关键菜单真实API冒烟仍未执行,未将登录页验证冒充该项通过。
  • R1只移动前端API与类型代码,没有修改URL、HTTP方法、请求体、返回类型、页面交互、后端、数据库schema、migration、Redis Stream或CMPP协议;没有写数据库或发送短信。工作区中既有号码频控/白名单、客户端体验、运营看板及其他会话产物继续完整保留,不归因于R1。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署。

2026-07-31 R2 运营查询服务兼容门面拆分(本地未提交)

  • 按路线图完成R2。api/src/operations/operations.service.ts从2368行缩减为150行稳定门面,运营端和客户端控制器继续只注入OperationsService,29个公开方法的名称、参数、异步标记和返回推断保持不变。
  • 原实现按短信记录与CSV、上行与监控、运营看板、发送/签名质量、系统日志、下游投递恢复、追踪对账七个领域迁移;3个私有方法随唯一调用域移动。查询契约独立到operations.contracts.ts,36个查询构造、时区、CSV、安全视图和响应汇总函数集中到operations.helpers.ts
  • 新增docs/contracts/operations-r2-methods.jsontools/quality/verify-operations-r2.mjs。R2门禁确认29个公开方法、3个私有方法、9个查询契约和36个辅助函数与拆分前实现哈希一致;SQL、Prisma查询参数、分页、CSV、上海时区和客户端安全映射未改写。
  • Operations定向1 suite / 26 tests、API全量28 suites / 381 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、前端TypeScript与Vite v8.0.16生产构建、Gatewaygo test ./...go vet ./...、依赖安全门禁和git diff --check全部通过。Jest仅保留既有--forceExit开放句柄提示,Vite仅保留既有约2.00MB单chunk及本次构建解析耗时提示。
  • 真实本地PostgreSQL只读调用拆分后的服务:短信总数56、第一页5条;签名质量和恢复状态当前均为0条;客户端看板返回真实企业“测试客户A”、未认证、有效签名0和待审核任务0。首次只读验证误用了Tenant不存在的deletedAt字段,Prisma在SQL执行前拒绝,修正为当前schema字段后通过;全程未写数据库。
  • R2没有修改控制器、路由、数据库schema、migration、Redis Stream、Gateway或CMPP协议,没有触发下游重投、文件导出落库或短信发送。当前工作区既有号码频控/白名单、客户端体验、R0/R1及其他会话产物继续完整保留,不归因于R2。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署。

2026-07-31 R3 短信配置兼容门面拆分(本地未提交)

  • 按路线图完成R3。api/src/sms-config/sms-config.service.ts从2268行缩减为约244行稳定门面,运营端、客户端、Gateway事件和报备资料服务继续依赖SmsConfigService;51个公开方法名称、参数、异步标记和返回推断保持不变。路线图中的“第一阶段”表示保留统一门面,不表示短信配置只拆了一部分。
  • 原实现按应用配置与接入参数、应用停用生命周期和下游连接、签名、引流信息、模板、审核记录与动作、共享报备资料校验七个领域迁移。21个内部方法随职责移动;既有私有停用扫描测试入口由门面继续委托生命周期服务,未复制业务实现。
  • 19个DTO和查询类型移到sms-config.contracts.ts,运营端、客户端和Gateway控制器不再从实现类文件导入DTO。27个规范化、CMPP参数、模板变量及报备值辅助声明集中到sms-config.helpers.tsSmsConfigModule仍只注册并导出稳定门面,不扩大NestJS provider图。
  • 新增docs/contracts/sms-config-r3-methods.jsontools/quality/verify-sms-config-r3.mjs。R3门禁确认51个公开方法、21个内部方法、19个契约和27个辅助声明领域归属正确,迁移前后方法体在受控依赖委托还原后完全一致;R0、R1、R2门禁继续通过。
  • Node.js v24.14.0下短信配置与审核治理定向2 suites / 68 tests、API全量28 suites / 381 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、前端TypeScript和Vite v8.0.16生产构建、Gatewaygo test ./...go vet ./...、依赖安全门禁和git diff --check通过。Jest只保留既有--forceExit开放句柄提示,Vite只保留既有约2.00MB单chunk提示。
  • 真实本地PostgreSQL只读调用拆分后的门面成功:读取真实应用并确认租户匹配,应用报备字段当前0条、引流信息0条、模板1条、签名审核记录0条。第一次只读校验脚本按错误的对象结构读取报备字段长度而抛出TypeError,修正为当前数组响应后通过;两次均未执行写操作。
  • R3没有修改控制器路由、请求/响应DTO内容、数据库schema、migration、Redis Stream、Gateway或CMPP协议,没有调用创建、编辑、审核、停用、下游重投或短信发送路径。现有号码频控/白名单、客户端体验、R0~R2和其他工作区修改继续完整保留,不归因于R3。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署。

2026-07-31 R4 报备资料与企业签名页面拆分(本地未提交)

  • 按路线图完成R4后端全部边界。api/src/report-materials/report-materials.service.ts从1134行缩减为82行稳定门面,12个公开方法的名称、参数、异步标记和返回推断保持;11个内部方法按官方模板与导出、导入解析映射、暂存与审核、待生成查询、批次预检生成、通道文件导出、幂等操作记录七个领域迁移。
  • 10个DTO、查询和内部数据类型移到report-materials.contracts.ts,32个工作簿安全、字段映射、分页、日期、文件和导出辅助函数移到report-materials.helpers.ts。控制器DTO不再从实现类文件导入,模块和其他调用方仍只依赖稳定门面。
  • 前端遵守“一个版本只拆一个大页面”,选择AdminEnterpriseSignaturesPage.tsx,从884行缩减为238行页面容器。类型、纯展示辅助、动态报备资料、签名编辑、引流编辑、报备状态弹窗和签名/引流表格拆为7个文件,最大132行;页面容器继续统一维护筛选、分页、加载、保存和删除协调。
  • 新增docs/contracts/report-materials-r4-methods.jsondocs/contracts/admin-enterprise-signatures-r4.jsontools/quality/verify-report-materials-r4.mjstools/quality/verify-enterprise-signatures-r4.mjs。后端门禁确认12个公开方法、11个内部方法、10个契约和32个辅助函数实现一致;前端门禁确认20个移出函数、表格JSX、8个真实API调用和25个页面状态保持。
  • Node.js v24.14.0下报备资料定向1 suite / 10 tests、API全量28 suites / 381 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、前端TypeScript和Vite v8.0.16生产构建、Gatewaygo test ./...go vet ./...、依赖安全门禁通过。Jest只保留既有--forceExit开放句柄提示,Vite只保留既有约2.00MB单chunk提示。
  • 真实本地PostgreSQL只读调用拆分后门面成功:待生成资料、导入审核批次和已生成批次当前均0条,导入映射配置0条;未调用模板生成、文件上传、导入提交、审核、批次生成、幂等认领或通道导出,没有写数据库或对象存储。
  • 应用内浏览器访问http://localhost:4173/#/admin/enterprise-signatures,真实鉴权将失效会话跳转运营登录页;页面标题、非空DOM、登录提示和表单正常,控制台无warning/error,点击验证码后算式从25 + 1变为36 + 9。当前浏览器运行时不支持页面或元素截图命令,未切换到未授权的Playwright回退;没有求解验证码或把登录页当成企业签名主体的登录后视觉验收。
  • R4没有修改数据库schema、migration、Redis Stream、Gateway、CMPP协议或其他大页面,没有发送短信、生成报备文件或修改业务数据。号码频控/白名单、客户端体验、R0~R3和其他工作区修改继续完整保留,不归因于R4。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署。

2026-07-31 R5 通道服务兼容门面拆分(本地未提交)

  • 按路线图完整拆分R5七个领域。api/src/channels/channels.service.ts从2572行缩减为204行稳定门面,控制器、模块和既有测试继续依赖同一入口;37个公开方法的名称、参数、异步标记和返回推断保持不变。
  • 原实现按通道配置与状态、连接/重连与Gateway控制、测试短信、通道组与路由、报备字段/任务/回执/记录、通道复制、删除入口七个领域迁移。连接服务统一持有定时器、Redis客户端、Gateway请求和队列副作用;配置服务仅在既有连接参数变化条件满足时委托重连;既有私有Gateway重启恢复测试入口由门面继续委托。
  • 17个DTO和查询契约移到channels.contracts.ts,控制器不再从实现类文件导入DTO;60个共享常量、类型和纯辅助声明移到channels.helpers.tsChannelsModule仍只注册并导出稳定门面,没有扩大NestJS provider图。
  • 新增docs/contracts/channels-r5-methods.jsontools/quality/verify-channels-r5.mjs。门禁确认37个公开方法、14个内部方法、17个契约和60个辅助声明领域归属正确,并锁定连接参数重连条件、Gateway连接/断开路径、定时器、Redis队列和Stream、测试号码规范化及单次提交语义。首次生成版本因统一缩进改变模板字符串内SQL空白,被门禁在listReportTasks处拒绝;改为只缩进方法首行后,迁移实现哈希全部一致。
  • Channels定向测试首次有1项失败,原因是稳定门面遗漏既有私有reconnectActiveChannelsAfterGatewayRestart测试缝;补回纯委托入口后1 suite / 41 tests全部通过。API全量28 suites / 381 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、前端TypeScript和Vite v8.0.16生产构建、Gatewaygo test ./...go vet ./...及依赖安全门禁通过。Jest只保留项目既有--forceExit开放句柄提示,Vite只保留既有约2.00MB单chunk提示。
  • 真实本地PostgreSQL只读调用拆分后门面成功:通道分页返回5/5条、通道组2条、路由规则1条、报备任务1/1条,连接、连接日志、报备字段和报备记录查询均正常完成。验证未调用onModuleInit、重连、状态同步、创建、编辑、复制、删除、测试短信、报备导出或其他写路径。
  • R5没有修改数据库schema、migration、控制器路由、Redis Stream契约、Gateway或CMPP协议,没有发送真实短信,也没有修改真实通道账号、密码、启停状态或连接。号码频控/白名单、客户端体验、R0~R4及其他工作区修改继续完整保留,不归因于R5。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署。

2026-07-31 R6 Gateway 入站服务拆分(本地未提交)

  • 按路线图在gateway/internal/inbound同一Go package内完整拆分R6。原server.go从1671行缩减为37行稳定启动入口;Server.ListenAndServeDisconnectAccountPushReceiptWithResultPushUplinkWithResult等公开入口、cmd/gateway及控制服务调用方式保持不变。
  • 原实现按登录认证、Submit与报文转换、下游会话注册、回执/上行Deliver、ACK追踪与SubmitResp顺序屏障、待投递恢复扫描、协议日志、共享HTTP传输八个职责迁移到9个聚焦文件。现有presence.gorecovery.go保持原样;没有跨package改接口或形成新的运行时依赖。
  • 新增docs/contracts/inbound-r6-declarations.jsontools/quality/verify-inbound-r6.go。门禁逐项确认迁移前93个声明的文件归属和实现哈希一致,并锁定稳定启动入口、控制服务三个调用入口及12项关键协议测试。SubmitResp先于排队回执、会话唯一所有权、原始Msg_Id恢复和多实例恢复锁等复杂边界补充了原因注释,没有改写实现。
  • 入站定向测试32项全部通过;Gatewaygo test ./... -count=1全部package通过,go vet ./...通过。go test -race ./internal/inbound因当前Windows Go环境CGO_ENABLED=0而在执行测试前拒绝启动,未将竞态检测记为通过,也未为本轮临时安装C工具链。
  • API全量28 suites / 381 tests全部通过;API TypeScript正式构建、Prisma format/validate/generate、前端TypeScript和Vite v8.0.16生产构建、依赖安全门禁及R0~R6全部结构门禁通过。Vite只保留既有约2.00MB单chunk提示,Jest只保留既有--forceExit开放句柄提示。
  • 第一次API全量命令误在仓库根目录直接启动Jest,没有加载api目录的TypeScript配置,28个suite均在解析阶段退出且0项测试执行;回到正确api工作目录后381项全部通过,该误调用不属于产品失败。
  • Gateway测试覆盖真实本地TCP监听及CMPP 2.0/3.0登录、单/多号码、长短信、SubmitResp顺序、Deliver ACK、ACK超时、连接关闭与恢复锁。额外的独立本地Gateway进程冒烟命令被当前执行策略在启动前拦截,因此没有把它记录为通过;本轮没有连接预生产CMPP端口。
  • R6没有修改CMPP报文、HTTP回调内容、Redis键、数据库schema、migration、队列或业务规则,没有发送短信、触发补发/重投、登录真实下游账号,也没有修改通道、余额或客户连接。号码频控/白名单、客户端体验、R0~R5及其他工作区修改继续完整保留,不归因于R6。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署。

2026-07-31 R7 Gateway 上游管理拆分(本地未提交)

  • 按路线图在gateway/internal/upstream同一Go package内完整拆分R7。原manager.go从1495行缩减为198行稳定管理入口;Manager.SubmitConnectChannelDisconnectChannelConnectionState等公开契约,以及cmd/gateway、控制服务和Submit Worker调用方式保持不变。
  • 原实现按Manager与连接池注册、连接池生命周期、物理连接与读循环、重连状态机、窗口/心跳、Submit与分片、回执/上行Deliver、协议日志、ConnectionState与API回调九个职责迁移。既有long_message.go已独立承担长短信拆分和上行组装,本轮保持原样。
  • 新增docs/contracts/upstream-r7-declarations.jsontools/quality/verify-upstream-r7.go。门禁按接收者类型分别确认迁移前68个声明的文件归属和实现哈希一致,避免混淆连接池与物理连接的同名方法;同时锁定Manager稳定入口、控制服务调用、既有长短信函数及15项关键状态机测试。
  • 为慢鉴权重连、手工断开停止条件、每连接窗口所有权、长短信逐分片结果、未决提交唤醒和回执tracker等复杂边界补充原因注释,未修改业务实现、常量或时序。
  • 上游定向测试18项全部通过;其中本地重连集成测试使用真实TCP监听模拟供应商端点,先确认连接失败,再启动端点并验证自动恢复连接。Gatewaygo test ./... -count=1全部package通过,go vet ./...通过;没有连接任何真实供应商通道。
  • API全量28 suites / 381 tests全部通过;API TypeScript正式构建、Prisma format/validate/generate、前端TypeScript和Vite v8.0.16生产构建、依赖安全门禁及R0~R7全部结构门禁通过。Vite只保留既有约2.00MB单chunk提示,Jest只保留既有--forceExit开放句柄提示。
  • R7没有修改连接数、窗口、心跳、重连延迟、鉴权失败分类、长短信分片、回执状态、HTTP回调、CMPP协议、Redis Stream、数据库schema或migration,没有发送短信、触发补发/重投,也没有修改通道凭据、启停状态、余额或客户连接。号码频控/白名单、客户端体验、R0~R6及其他工作区修改继续完整保留,不归因于R7。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署。

2026-07-31 R8 发送链纯逻辑拆分(本地未提交)

  • 按路线图完成R8。api/src/send-chain/send-chain.service.ts从5345行缩减为4578行;24个DTO、Gateway事件和队列契约迁移到send-chain.contracts.ts,64个既有常量、状态/错误映射、号码/资源判定、模板/签名/引流分类及事件键等纯声明迁移到send-chain.helpers.ts
  • SendChainService仍保留98个数据库事务、队列发布、Gateway调用和顶层编排方法。通道候选选择、通道可发送性、分片最终状态聚合、上游端点身份比较和回执事件键生成改为显式纯函数;既有数据库查询、事务范围、日志字段、幂等键、队列消息及调用顺序未改变。
  • 为省内优先/全国兜底、排除或未报备通道、分片未收齐、全部成功、明确失败优先、上游端点身份和稳定回执事件键新增8项纯逻辑测试。纯逻辑与既有SendChain定向2 suites / 112 tests全部通过,其中既有104项特征测试保持。
  • 新增docs/contracts/send-chain-r8-pure-logic.jsontools/quality/verify-send-chain-r8.mjs。门禁逐项锁定24个契约与64个迁移声明的实现哈希,确认98个编排方法以及数据库事务、队列、补发和分片审计副作用仍在原服务;R0~R8全部结构门禁继续通过。
  • Node.js v24.16.0下API全量29 suites / 389 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、前端TypeScript和Vite v8.0.16生产构建、Gatewaygo test ./... -count=1go vet ./...、依赖安全门禁和git diff --check全部通过。Jest只保留项目既有--forceExit开放句柄提示,Vite只保留既有约2.00MB单chunk提示。
  • 真实本地运行态只读核验:API health返回HTTP 200PostgreSQL与Redis端口监听,Redis返回PONG;数据库现有56条短信记录、0条分片审计,因此真实分片聚合样本记为不适用,没有造数冒充通过。使用真实5条通道记录调用可发送性纯函数,当前2条active、0条满足本地连接可发送条件;未调用模块初始化、重连、状态同步或任何写路径。
  • R8没有修改数据库schema、migration、控制器路由、Redis Stream、Gateway、CMPP协议或业务规则,没有发送短信、触发补发/重投,也没有修改通道账号、密码、启停状态、余额或客户连接。号码频控/白名单、客户端体验、R0~R7及其他工作区修改继续完整保留,不归因于R8。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署;R9、R10再分别拆入口/提交和回执/补发/下游投递编排。

2026-07-31 R9 发送入口与提交编排拆分(本地未提交)

  • 按路线图完成R9五类入口。api/src/send-chain/send-chain.service.ts从R8的4578行缩减为2983行,98个稳定方法继续供控制器、Open API、审核中心和其他模块调用;send-submission.service.ts为305行内部兼容门面。
  • 45个方法按批量/HTTP入口、CMPP入站、审核续发、定时调度和Gateway提交拆到五个实现文件,行数分别为552、840、109、160和491。没有把最初1939行的单一提交域文件作为终点,避免只移动大文件而不形成职责边界。
  • 迁移方法体保持原实现;内部跨方法调用返回SendChainService稳定门面,再经内部兼容门面分派,以保留既有覆盖点和测试可观察性。日志上下文继续是SendChainService,没有改变控制器路由、公开参数、响应或NestJS provider边界。
  • 新增docs/contracts/send-chain-r9-submission.jsontools/quality/verify-send-chain-r9.mjs。门禁锁定45个方法体哈希、五个领域归属、双层门面委托和Worker/事务/回调/Redis Stream副作用;确认Gateway结果、回执、补发、退款及下游投递仍留在R10边界。R0~R9全部结构门禁通过。
  • 第一次定向测试为97/112通过,15项失败均源于新域内部直接互调,导致既有测试替换稳定门面的enqueueBatchTask、调度、队列和限速方法时无法观察内部调用;改为跨方法调用统一返回稳定门面后,2 suites / 112 tests全部通过。该问题在本地门禁阶段发现,没有进入提交或部署。
  • Node.js v24.14.0下API全量29 suites / 389 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、前端TypeScript和Vite v8.0.16生产构建、Gatewaygo test ./... -count=1go vet ./...、依赖安全门禁和git diff --check全部通过。Jest仅保留既有--forceExit提示,Vite仅保留既有约2.00MB单chunk提示。
  • 真实本地后端只读核验使用实际SendChainService、Prisma/PostgreSQL和现有任务:拆分后的任务查询成功;号码导入预检通过真实企业/全局黑名单查询,3行数据返回1条有效、2条错误。调用前后批量任务1条、短信56条、频控状态0条、账户流水3条完全不变。API health HTTP 200PostgreSQL/Redis端口监听,Redis返回PONG。
  • R9没有调用创建任务、确认导入、HTTP/CMPP真实提交、审核动作、定时调度、Worker或Gateway发布,没有发送短信、触发补发/重投,也没有修改schema、migration、队列消息、通道、余额或客户连接。号码频控/白名单、客户端体验、R0~R8及其他工作区修改继续完整保留,不归因于R9。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署;R10再处理Gateway结果、分片回执、最终聚合、补发、退款和下游投递。

2026-07-31 R10 发送完成链编排拆分(本地未提交)

  • 按路线图完成R10八项边界。api/src/send-chain/send-chain.service.ts从R9的2983行缩减为878行,98个稳定方法继续供控制器、Open API、Gateway事件和其他模块调用;send-completion.service.ts为323行内部兼容门面。
  • 41个方法按Gateway提交结果与分片提交审计、上游回执收件箱/分片回执/最终聚合、失败补发、扣费退款与预占释放、下游最终状态、CMPP/HTTP最终回执投递、回执超时扫描七个领域迁移,领域文件分别为390、593、359、142、510、489和104行。
  • 迁移方法体保持原实现;内部跨领域调用返回SendChainService稳定门面,再经完成链兼容门面分派,保留R9提交域依赖方向、既有测试替换点和调用可观察性。日志上下文继续使用SendChainServiceNestJS模块仍只注册稳定门面。
  • 新增docs/contracts/send-chain-r10-completion.jsontools/quality/verify-send-chain-r10.mjs。门禁锁定41个方法体哈希、七个领域归属、双层门面委托和98个稳定方法,并检查来源提交唯一补发关系、P2002唯一冲突、当前尝试判定、分片聚合、账务幂等键、最终回执键、下游去重/ACK/人工重排键及历史记录不删除。为适配R10物理归属,R8门禁改为在全部send-*.service.ts实现中检查既有副作用不变量。
  • 第一次API TypeScript构建发现完成链门面包装方法可见性及迁移领域的少量显式导入缺失;补齐公开委托和UplinkMatchCandidateInput、超时/规范化辅助导入后正式构建通过。问题在本地编译门禁发现,没有进入提交或部署。
  • SendChain定向2 suites / 112 tests、API全量29 suites / 389 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、前端TypeScript和Vite v8.0.16生产构建、Gatewaygo test ./... -count=1go vet ./...、依赖安全门禁、R0~R10全部结构门禁及git diff --check通过。Jest仅保留既有--forceExit提示,Vite仅保留既有约2.00MB单chunk与插件耗时提示。
  • 真实本地运行态只读核验:API /api/health返回正常,3000、5432、6379端口监听,Redis返回PONG。真实PostgreSQL查询前后均为提交记录61、分片审计0、回执53、下游投递2、下游attempt 0、上游回执收件箱0、Gateway提交死信0、账户流水3,最新提交、回执和下游投递路径均可读,前后计数完全一致。当前没有真实分片审计和下游attempt样本,因此对应数据态验证记为不适用,不造数冒充通过。
  • R10没有调用模块初始化、Gateway结果写入、回执入箱、补发抢占、扣费、退款、预占释放、最终回执创建、下游认领、ACK、人工重排或超时扫描,没有发送短信、重试、补发或重投,也没有修改数据库schema、migration、Redis Stream、CMPP协议、通道、余额或客户连接。号码频控/白名单、客户端体验、R0~R9和其他工作区修改继续完整保留,不归因于R10。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署。

2026-07-31 R11 通道管理页面与专属样式拆分(本地未提交)

  • 按路线图“每次只迁移一个页面域”执行R11第一页面域,选择剩余最大页面AdminChannelsPage.tsx,从782行缩减为197行稳定协调层。类型、纯映射、表格、编辑弹窗、测试短信弹窗和连接日志弹窗拆入src/apps/admin/channels/,各TypeScript文件为51153行。
  • 页面继续直接调用真实adminApi:列表分页、发送质量、连接状态、创建/编辑、启停、复制、连接日志和测试短信接口均保留;没有引入barrel、mock、静态数据或localStorage。React组件不在页面函数内部定义,查询和写操作仍由页面统一协调。
  • 将通道列表、质量指标、编辑表单、测试结果和连接日志的467行专属样式迁入AdminChannelsPage.cssglobal.css从12270行缩减为11800行;共享给通道组的.channel-confirm保留全局,375px下连接摘要规则随页面迁移。main.tsx的tokens/global/components加载顺序未变。
  • 新增docs/contracts/admin-channels-r11.jsontools/quality/verify-admin-channels-r11.mjs,门禁确认198行稳定入口、五个聚焦模块、全部真实API调用、八个交互入口和页面样式归属。第一次门禁用.sms-channel-宽前缀误匹配仍属通道组的.sms-channel-group-*,改为逐项页面选择器后通过;不是产品故障。
  • 前端TypeScript检查通过。本地应用内浏览器使用真实运营账号登录,真实API返回5条通道;按Smoke查询得到1条,重置恢复5条。编辑弹窗正常回填业务信息、单价、地区和CMPP参数,点击取消未保存;连接日志弹窗正常加载真实连接状态/日志并提供关键词筛选。
  • 默认桌面和375×812视口页面均非空、无框架错误覆盖,控制台无warning/error。桌面列表、筛选、质量指标和操作按钮布局正常;窄屏保持既有横向表格浏览方式。浏览器运行时截图通过Tab截图接口获取,未写入仓库。
  • 前端TypeScript和Vite v8.0.16生产构建通过,2468个模块完成转换;API全量29 suites / 389 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、Gatewaygo test ./... -count=1go vet ./...、依赖安全门禁、R0~R11全部结构门禁及git diff --check通过。Vite仅保留既有约2.00MB单chunk提示,Jest使用项目既有的--forceExit验收口径并保留开放句柄提示。
  • 第一次并行Gateway全量测试中TestInboundServerAuthenticatesAndSubmits因模拟API服务提前关闭而失败;该用例单独重跑通过,随后Gateway全量及vet通过,未修改Gateway代码。两次直接执行未带--forceExit的API全量命令在测试完成后留下Jest进程并达到超时,确认并只终止本轮创建的两个全量Jest进程后,按既有--forceExit口径重跑,389项在21.381秒全部通过;未终止其他会话长期存在的定向Jest进程。
  • 验证没有点击编辑确认、添加确认、复制确认、启停确认、删除确认或测试短信最终发送,没有修改通道账号、密码、启停状态、连接或任何业务数据;没有发送短信。
  • 本轮按用户要求仅保留本地修改,不提交、不推送、不部署。其他剩余大页面及专属样式必须继续按独立小版本迁移,不在本次R11中批量处理。

2026-07-31 R11 短信任务进度页面与专属样式拆分(本地未提交)

  • 按路线图“每次只迁移一个页面域”执行R11第二页面域。AdminSmsTaskProgressPage.tsx从657行缩减为163行稳定协调层,只保留真实任务查询、企业/应用筛选项加载、选中状态和终止操作;纯任务映射、筛选区、主表、详情弹窗、真实号码分页弹窗和终止确认拆入src/apps/admin/sms-task-progress/,各TypeScript文件为28170行。
  • 页面继续直接使用真实adminApi:任务分页、企业与应用选项、批次号码分页和终止接口均保留;任务状态归一化、提交/成功/失败计数、计费条数、运营商/省份聚合、进度和成功率公式保持原实现。未引入barrel、mock、静态数据或localStorage,也未把组件定义嵌回页面函数。
  • 将详情标题、指标、任务详情、运营商卡片和移动端详情布局共273行页面专属样式迁入AdminSmsTaskProgressPage.cssglobal.css从11800行缩减为11527行。报备、下游记录等页面仍使用的.admin-task-filter.admin-task-table-card.admin-task-id.admin-task-enterprise.admin-task-card.batch-progress保留全局。
  • 新增docs/contracts/admin-sms-task-progress-r11.jsontools/quality/verify-admin-sms-task-progress-r11.mjs,门禁确认164行文本入口、六个聚焦模块、全部真实API边界、十一项交互文案、专属/共享样式归属和375px详情布局。入口物理行数为163,门禁按末尾换行计为164,均低于220行上限。
  • 本地应用内浏览器使用已存在的真实运营账号会话,解锁后真实API返回1条客户批量任务BT-1783075838138-a886dd56。不存在批次号查询返回真实空列表,重置再查询恢复1条;详情展示2个号码、2条计费、中国移动2个和未识别省份2个;号码列表真实返回1380013800013900139000,按138查询后返回1条。
  • 默认桌面详情弹窗和375×812窄屏列表均非空、无框架错误覆盖,控制台0条warning/error;手机端筛选区、查询/重置按钮和任务卡片正常显示。终止确认弹窗的风险提示正常,验收只点击取消,没有调用确认终止。
  • Node.js v24.14.0下前端TypeScript和Vite v8.0.16生产构建通过,2475个模块完成转换;API全量29 suites / 389 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、Gatewaygo test ./... -count=1go vet ./...、依赖安全门禁、R0~R11全部结构门禁及git diff --check通过。Vite仅保留既有约2.00MB单chunk提示,Jest使用既有--forceExit口径并保留开放句柄提示。
  • 首次前端构建由系统旧Node.js v14.17.4执行,Vite因不支持??=语法产生未处理Promise警告但错误返回0;未将其计为通过,切换到Node.js v24.14.0后重新构建并看到实际产物。第一次并行回归中的系统npm 6不支持npm exec,Prisma子任务未启动;随后改用项目本地Prisma可执行文件完整补跑并通过,属于工具链编排问题,不是产品代码失败。
  • 本轮没有发送短信、创建或终止任务、触发补发/重投,也没有修改数据库、Redis Stream、Gateway、通道、余额或客户连接。R0~R11第一页面域、号码频控/白名单、运营看板和其他工作区修改继续完整保留,不归因于本步骤。
  • 按用户要求继续仅保留本地修改,不提交、不推送、不部署。R11当前完成2个页面域;其余页面和共享CSS域继续按独立小步骤推进。

2026-07-31 R11 短信记录页面与专属样式拆分(本地未提交)

  • 按路线图“每次只迁移一个页面域”执行R11第三页面域。AdminSmsRecordsPage.tsx从640行缩减为195行稳定协调层,仅保留真实记录分页、企业/应用筛选项、分片审计、后端CSV导出和选中详情状态;时间/状态/运营商/路由映射、筛选区、记录卡片与分页、发送详情弹窗拆入src/apps/admin/sms-records/,各TypeScript文件为33219行。
  • 五个真实adminApi调用保持:listOperationMessageslistTenantslistEnterpriseApplicationOptionslistMessageSegmentAuditsexportOperationMessages。默认昨日到今日、提交失败覆盖、平台失败回执说明、运营端测试说明、通道尝试排序、发送接入号拼接和分片审计排序均保持原实现;没有引入barrel、mock、静态列表或localStorage。
  • 将短信记录筛选、卡片、状态、详情、通道路由、分片审计和900px/780px响应式规则迁入433行AdminSmsRecordsPage.cssglobal.css从11527行缩减为11098行。多个运营页面共享的.template-modal-title.muted.ui-table__empty保留全局。
  • 新增docs/contracts/admin-sms-records-r11.jsontools/quality/verify-admin-sms-records-r11.mjs,门禁确认196行文本入口、四个聚焦模块、五个真实API边界、十五项交互文案、专属/共享样式归属和两级响应式规则。入口物理行数为195,门禁按末尾换行计196,低于220行上限。
  • 本地应用内浏览器访问真实运营端和本地API:默认2026-07-30至2026-07-31返回0条,清空日期后真实返回56条、3页。按手机号13900000054查询收窄为1条;运营商下拉保留全部、移动、联通、电信、未识别五项;翻到第2页后仍显示真实总数56和3页分页。
  • 真实详情LOCAL-SIGSTAT-20260728-054展示发送成功、accepted、delivered、上海/中国联通、发送接入号10690000、两次通道尝试和对应UNDELIV/DELIVRD回执;真实分片接口返回0条,页面明确显示“暂无分片审计”,未造数冒充覆盖。现有56条为本地数据库已存在的统计演示数据,本步骤没有执行演示数据脚本或写入任何记录。
  • 默认桌面列表/详情和375×812记录卡片均非空、无框架错误覆盖,控制台0条warning/error;窄屏企业应用、状态、时间、内容、号码、计费、通道和详情入口未重叠。浏览器运行时截图未写入仓库。
  • Node.js v24.14.0下前端TypeScript和Vite v8.0.16生产构建通过,2480个模块完成转换;API全量29 suites / 389 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、依赖安全门禁和R0~R11全部结构门禁通过。Vite仅保留既有约2.00MB单chunk提示,Jest使用既有--forceExit口径并保留开放句柄提示。
  • 第一次并行Gateway全量测试中TestSubmitResponsePrecedesQueuedFailureReceipt因等待模拟失败回执超时而失败,日志同时显示模拟API连接被提前关闭。本步骤未修改Gateway;该用例定向重跑通过,随后Gatewaygo test ./... -count=1go vet ./...全量通过,按既有时序型测试波动记录而不掩盖。
  • 验收没有点击导出下载、发送、补发、重投或任何写操作,没有修改数据库、Redis Stream、Gateway、通道、余额或客户连接。R0~R11前两个页面域及其他工作区修改继续完整保留,不归因于本步骤。
  • 按用户要求继续仅保留本地修改,不提交、不推送、不部署。R11当前完成3个页面域;其余页面和共享CSS域继续按独立小步骤推进。

2026-07-31 R11 企业应用管理页面与专属样式拆分(本地未提交)

  • 按路线图“每次只迁移一个页面域”执行R11第四页面域。AdminEnterpriseApplicationsPage.tsx从616行缩减为273行稳定协调层,仅保留真实应用分页、企业选项、查询草稿/已应用条件、生命周期操作、参数详情和弹窗选中状态;筛选区、主表、生命周期弹窗、CMPP/HTTP参数弹窗、连接详情及纯映射拆入src/apps/admin/enterprise-applications/,各TypeScript文件为50164行。
  • 六类真实adminApi调用继续由页面协调:应用分页、企业列表、状态变更、停用影响预检、CMPP参数和HTTP参数。分页、查询后回第一页、重置、停用等待/强制模式、启用、删除、CMPP/HTTP能力禁用规则和参数加载时序保持原实现;没有引入barrel、mock、静态数据或localStorage。
  • 将企业应用筛选、连接状态、操作区、连接详情、参数详情、新增应用提示和响应式规则迁入222行AdminEnterpriseApplicationsPage.cssglobal.css从11098行缩减为10881行。共享筛选、确认文案、弹窗标题、堆叠和表单布局继续保留全局。
  • 窄屏视觉初检发现页面CSS后加载可能覆盖原全局780px筛选单列规则;在页面CSS显式恢复该规则并加入结构门禁。修正后375×812视口实测页面宽度375px、文档滚动宽度375px,筛选区单列、两个输入均未造成页面级横向溢出。这是拆分阶段发现并修复的样式加载顺序风险,未进入提交或部署。
  • 新增docs/contracts/admin-enterprise-applications-r11.jsontools/quality/verify-admin-enterprise-applications-r11.mjs,门禁确认274行文本入口、六个聚焦模块、六类真实API边界、十六项交互文案、专属/共享样式归属、查询状态分层以及780px、900px、520px响应式规则。R0~R11全部结构门禁和依赖安全门禁通过。
  • 本地应用内浏览器使用既有真实运营账号会话,真实应用分页返回2条。不存在企业名称查询显示真实空状态,重置恢复2条;新增应用弹窗由真实企业接口加载并保持未选择时“下一步”禁用,随后取消。
  • 对真实Smoke SMS App只读打开连接详情,显示当前连接0、配置连接1、离线及无已连接会话;CMPP参数通过真实详情接口成功打开后直接关闭,未读取、复制或记录敏感参数。停用影响预检返回2项未清算义务,弹窗展示等待/强制停用边界,验收只点击取消,没有调用状态变更。
  • 默认桌面与375×812窄屏页面均非空、无框架错误覆盖;桌面筛选、页签、真实表格和横向滚动正常,窄屏筛选单列及记录卡片正常。控制台0条warning/error,桌面和窄屏截图写入系统临时目录,未写入仓库。
  • Node.js v24环境下前端TypeScript和Vite v8.0.16生产构建通过,2487个模块完成转换;API全量29 suites / 389 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、Gatewaygo test ./... -count=1go vet ./...、依赖安全门禁、R0~R11全部结构门禁和git diff --check通过。Vite仅保留既有约2.00MB单chunk提示,Jest使用既有--forceExit口径并保留开放句柄提示。
  • 本轮没有创建、编辑、启停或删除企业应用,没有复制接口参数、发送短信、触发补发/重投,也没有修改数据库业务数据、Redis Stream、Gateway、通道、余额或客户连接。R0~R11前三个页面域、号码频控/白名单和其他工作区修改继续完整保留,不归因于本步骤。
  • 按用户要求继续仅保留本地修改,不提交、不推送、不部署。R11当前完成4个页面域;剩余5个页面/共享CSS域步骤继续按独立小版本推进。

2026-07-31 R11 tokens与reset基础样式域拆分(本地未提交)

  • 按既定9步计划执行R11第5步,范围严格限定为“tokens和reset”。现有97行tokens.css继续作为唯一设计令牌入口,76个颜色、排版、间距、形状、阴影、布局和组件基础变量未改名、未改值;新增84行reset.css,从global.css迁出13组通配符、文档、链接、表单控件、禁用态、焦点和标题基础规则。
  • main.tsx将基础样式依赖顺序固定为tokens.css → reset.css → global.css → components.css → AppRoutesglobal.css从10881行缩减为10801行;AppShell、通用组件、admin/client共享域、响应式页面规则及单页面样式均未在本步骤迁移,避免一次改变多个级联边界。
  • 第一次生产产物位置检查发现,仅在AppRoutes之后书写四个CSS导入不足以约束打包依赖图,组件CSS会先于reset/global进入产物。将AppRoutes导入移到四层CSS之后并重建,最终产物关键位置为tokens 76、reset 1969、global 3030、components 33841、页面样式219684,确认实际拼接顺序与目标一致。该风险在本地门禁阶段发现并修复,没有进入提交或部署。
  • 新增docs/contracts/foundation-styles-r11.jsontools/quality/verify-foundation-styles-r11.mjs。门禁锁定76个令牌、13组reset/base规则逐规则声明哈希、reset选择器白名单、原global.css所有权清理和四层确定性加载顺序;R0~R11全部结构门禁及依赖安全门禁通过。
  • Node.js v24环境下前端TypeScript与Vite v8.0.16生产构建通过,2488个模块完成转换,产物CSS约237.03kB、gzip约34.91kB;只保留既有约2.00MB单chunk及一次插件耗时提示,没有新增CSS错误。
  • 本地应用内浏览器在最终依赖顺序调整后重新完整验收。使用真实运营会话打开企业应用管理页,真实API继续返回2条应用。页面URL和标题正确,非空且无框架错误覆盖;背景、14px基础字号、21px行高、字体族、链接无下划线、按钮/禁用态光标和输入继承字体的计算样式均符合原令牌。
  • 键盘聚焦输入控件时继续得到rgba(37, 99, 235, 0.18) 0 0 0 3px焦点环,浏览器默认outline保持关闭。新增应用弹窗正常打开,“下一步”在未选择企业时保持禁用,随后只点击取消,没有创建或修改应用。
  • 客户端登录页在未提交表单的情况下完成只读验收:Logo、标题、说明、账号、密码、图形验证码和登录按钮正常,未刷新验证码、未登录。运营端和客户端在默认桌面及375×812视口均无页面级横向溢出,控制台均为0条warning/error;四张截图写入系统临时目录,未写入仓库。
  • API全量29 suites / 389 tests全部通过;Prisma format/validate/generate、API TypeScript正式构建、Gatewaygo test ./... -count=1go vet ./...、依赖安全门禁、R0~R11全部结构门禁和git diff --check通过。Jest使用既有--forceExit口径并保留开放句柄提示。
  • 本步骤没有修改React业务组件、API、数据库schema或migration,没有登录客户端、创建/编辑/启停/删除应用、发送短信、触发补发/重投,也没有修改Redis Stream、Gateway、通道、余额或客户连接。R0~R11前四步及其他工作区修改继续完整保留,不归因于本步骤。
  • 按用户要求继续仅保留本地修改,不提交、不推送、不部署。R11当前完成5/9;下一步为AppShell与通用布局基础域,剩余4步继续独立推进。

2026-07-31 R11 AppShell与通用布局基础域拆分(本地未提交)

  • 按既定9步计划执行R11第6步,范围严格限定为AppShell和通用页面布局。新增811行src/styles/shell.css,从global.css迁出侧栏、折叠导航、顶栏、通知/用户菜单、移动端抽屉/遮罩、减少动画规则,以及.page-content.page-stack.page-heading.page-heading__actions.page-actions.surface.section-stack.section-heading九组布局原语;global.css从10801行缩减为10001行。
  • .icon-button仍被企业应用表单和用户页面复用,继续保留global.css.ui-tabs__tab及通用表格、表单、弹窗样式也未提前迁移。混合的.page-actions, .table-actions规则按选择器拆开但声明保持一致,没有修改React业务组件、选择器权重、业务文案、API或交互逻辑。
  • main.tsx加载顺序更新为tokens.css → reset.css → shell.css → global.css → components.css → AppRoutes。Node.js v24.14.0下Vite v8.1.5生产构建通过,2530个模块完成转换,产物CSS 237.11kB、gzip 34.75kBtokens、reset、shell、global和components代表标记依次位于76、1971、3030、15675和36609,只保留既有约2.00MB单chunk及插件耗时提示。
  • 新增docs/contracts/app-shell-styles-r11.jsontools/quality/verify-app-shell-styles-r11.mjs,门禁锁定118组规则、44个当前/兼容壳层类、九组共享布局选择器、桌面折叠、781px边界、780px移动抽屉和减少动画规则。基础样式契约同步加入shell.css加载层;企业应用契约同步确认.section-stack改由shell.css托管。全部15个R0~R11结构/行为门禁和依赖安全门禁通过。
  • Prisma format、validate、generate和API TypeScript正式构建通过;API全量29 suites / 389 tests全部通过。默认Jest命令在断言结束后因既有开放句柄未退出,本次终止的仅为本轮15:44创建的npm/Jest进程,未触碰2026-07-30遗留的其他会话进程;随后按既有--forceExit口径获得全量通过并保留开放句柄提示。Gatewaygo test ./... -count=1go vet ./...通过。
  • 本地前端http://127.0.0.1:4173/和API/api/health均HTTP 200。应用内浏览器访问企业应用页时恢复运营会话返回Internal server error并跳转登录页,Chrome也没有已登录运营端标签;遵守验证码边界,没有填写或提交登录表单、读取/伪造浏览器存储。因此桌面展开/折叠、通知/用户菜单和375×812移动抽屉的真实点击验收本轮受阻,需在可用登录态下补测,不能写成已通过。
  • 本步骤没有创建、编辑、启停或删除业务数据,没有发送短信、触发补发/重投,也没有修改数据库业务数据、Redis Stream、Gateway、通道、余额或客户连接。R0~R11前五步、号码频控/白名单和其他工作区修改继续完整保留,不归因于本步骤。
  • 按用户要求继续仅保留本地修改,不提交、不推送、不部署。R11第6步代码与文档完成,当前实施进度6/9;下一步为通用表格、表单和弹窗域,真实AppShell点击验收仍列为待补风险。

2026-07-31 运营端恢复会话500诊断与R11通用组件样式域拆分(本地未提交)

  • 恢复运营会话500已按真实基础设施链路定位。无cookie直接访问API与Vite代理的/api/admin/auth/session均正常返回401,验证码接口返回200;Redis返回PONG且存在有效运营会话,但当时本地PostgreSQL 5432未监听。有效会话通过Redis校验后执行prisma.user.findUnique,真实Prisma请求以ECONNREFUSED失败,Nest因而返回500/api/health仍为200是因为当前health未执行数据库查询。根因是本地PostgreSQL停止/崩溃而API、Redis仍运行,不是前端恢复会话或R11拆分逻辑缺陷。
  • logs/postgres.log记录此前进程以Windows异常0xC0000142终止,随后完成自动恢复。使用tools/start-local.ps1 -SkipMigrate -SkipApi -SkipWeb仅恢复本地PostgreSQL、Redis和MinIO,没有执行migration,也没有重启API或前端;启动脚本遗留的等待进程已精确停止,基础服务继续运行。恢复后5432、6379、9000、9001、3000、4173均监听,真实Prisma查询返回codex_local_admin及其active/sessionVersion/角色数据,API health返回200,无cookie会话接口返回401。
  • 按既定9步计划执行R11第7步,范围严格限定为“通用表格、表单和弹窗”。从global.css迁出52组规则、57个选择器,包括通用.ui-table*.ui-modal*.form-grid*.radio-row.table-actions、表格文本辅助类、.icon-button.ui-tabs__tab、XL弹窗及780px移动端规则;global.css从10001行缩减为9660行,components.css从1333行增加为1694行。页面域复合选择器继续留在原层,没有修改React业务组件、API、文案、数据口径或写操作。
  • 为保持原级联结果,迁入的旧兼容规则位于现有规范组件规则之前,响应式规则位于对应桌面规则之后;main.tsxtokens → reset → shell → global → components → AppRoutes顺序不变。新增docs/contracts/shared-components-r11.jsontools/quality/verify-shared-components-r11.mjs,锁定259组规则、291个选择器、14组通用类族、桌面/780px所有权和五类真实UI组件绑定;短信记录及企业应用旧契约同步更新为components所有权。全部15个R0R11结构门禁通过。
  • Node.js v24.14.0下前端TypeScript和Vite v8.1.5生产构建通过,2530个模块完成转换,CSS 237.11kBgzip 34.70kB)、JS 2003.23kBgzip 596.71kB),仅保留既有大chunk提示。Prisma format/validate/generate、API TypeScript正式构建、29 suites / 389 tests、Gatewaygo test ./... -count=1go vet ./...、依赖安全门禁均通过;Jest继续使用既有--forceExit口径并保留开放句柄提示。
  • 应用内浏览器确认数据库恢复后访问企业应用页不再显示Internal server error,而是正常跳转运营端登录页并提示“请先登录”,控制台无warning/error;Edge没有已登录运营端标签。遵守验证码边界,没有自动求解验证码、读取浏览器存储、伪造cookie或绕过登录。因此第6步AppShell交互及第7步登录后桌面/375px表格、表单、弹窗点击验收仍待可用登录态补做,不能表述为已通过。
  • 本步骤没有创建、编辑、启停或删除业务数据,没有发送短信、触发补发/重投,也没有修改数据库业务数据、Redis Stream、Gateway、通道、余额或客户连接。R0~R11前六步、号码频控/白名单和其他工作区修改继续完整保留,不归因于本步骤。
  • 按用户要求继续仅保留本地修改,不提交、不推送、不部署。R11当前完成7/9;下一步为admin共享样式域,client共享域和单页面样式继续独立推进。

2026-07-31 R11 admin共享样式域拆分(本地未提交)

  • 按既定9步计划执行R11第8步,范围严格限定为运营端跨页面共享样式。以“至少被两个src/apps/admin源码文件复用、且src/apps/client不依赖”为主要判定,再按同一共享模式补齐变体和响应式规则;没有迁移client域或业务逻辑。
  • 新增678行src/styles/admin.css,从global.css迁出117组规则、141个选择器,覆盖审核筛选、任务/报备记录、安全页、系统管理、质量/利润/对账筛选、跨页面确认与表单提示、下游明细和通道字段配置等运营端共享模式;global.css从9660行缩减为9056行。
  • .report-task-detail .admin-task-card.gateway-exception-page .report-task-table-card > .ui-pagination两个带单页面上下文的覆盖规则继续留在global.css,没有因类名命中而误迁。ui-*只作为admin所有者的后代上下文,客户端源码不引用admin所有权类。
  • main.tsx加载顺序更新为tokens → reset → shell → global → admin → components → AppRoutes。前端TypeScript和Vite v8.1.5生产构建通过,2531个模块完成转换,CSS 237.70kBgzip 34.79kB)、JS 2003.23kBgzip 596.71kB),仅保留既有大chunk提示。
  • 新增docs/contracts/admin-shared-styles-r11.jsontools/quality/verify-admin-shared-styles-r11.mjs,门禁锁定117组规则、141个选择器、11项跨页面使用下限、admin/client所有权、纯共享规则不得残留global以及780px/360px响应式边界;通道、企业应用、短信任务进度和foundation旧契约同步到新的样式归属与加载顺序。
  • Prisma format/validate/generate、API TypeScript正式构建、29 suites / 389 tests、Gatewaygo test ./... -count=1go vet ./...、依赖安全门禁、全部17个R0~R11结构门禁和git diff --check通过。Jest继续使用既有--forceExit口径并保留开放句柄提示。
  • 应用内浏览器访问真实本地运营端短信审核路由时,因无可复用运营端登录态正常跳转登录页;未求解验证码或伪造会话。运行时生产CSS已包含.admin-task-filter.admin-report-filter-grid规则,页面宽度与1280px视口一致,控制台0条warning/error。登录后的审核、任务、安全、系统及统计代表页面与375px交互验收仍待有效登录态补做,不能表述为已通过。
  • 本步骤没有修改React业务组件、API、数据库schema或migration,没有创建、编辑、启停、删除、导入或导出业务数据,没有发送短信、触发补发/重投,也没有修改Redis Stream、Gateway、通道、余额或客户连接。R0~R11前七步、号码频控/白名单和其他工作区修改继续完整保留,不归因于本步骤。
  • 按用户要求继续仅保留本地修改,不提交、不推送、不部署。R11当前完成8/9;下一步为client共享样式域,单页面覆盖规则继续保留原所有权。

2026-07-31 R11 client共享样式域拆分(本地未提交)

  • 按既定9步计划执行R11第9步,范围严格限定为client跨页面共享样式。静态引用盘点覆盖global.css和全部admin/client TypeScript源码;真正满足“至少两个client文件使用且admin完全不依赖”的全局类只有.eyebrow,由ClientHome.tsxClientBillingPage.tsx使用。
  • 新增8行src/styles/client.css并迁移.eyebrow一组规则,global.css从9056行缩减为9049行。客户端首页专属的.overview-hero .eyebrow覆盖继续留在global,没有把单页面上下文误判为共享。
  • .sms-send-title.system-page-toolbar.system-table-card虽然分别被9、3、2个客户端文件使用,但运营端系统日志页也真实依赖,因此继续作为跨门户兼容样式留在global。签名、发送、企业认证、发送详情和模板等代表性单页面样式也继续保留原所有权,没有为扩大改动而批量迁移。
  • main.tsx最终加载顺序为tokens → reset → shell → global → admin → client → components → AppRoutes。新增docs/contracts/client-shared-styles-r11.jsontools/quality/verify-client-shared-styles-r11.mjs,锁定唯一client所有权规则、两页面使用下限、三组跨门户兼容边界和五类单页面保留边界;foundation契约同步加入client层。
  • Node.js v24.14.0下前端TypeScript和Vite v8.1.5生产构建通过,2532个模块完成转换,CSS 237.70kBgzip 34.79kB)、JS 2003.23kBgzip 596.71kB),与第8步产物体积一致,仅保留既有大chunk提示。全部18个R0~R11结构门禁通过。
  • Prisma format/validate/generate、API TypeScript正式构建、29 suites / 389 tests、Gatewaygo test ./... -count=1go vet ./...、依赖安全门禁和git diff --check全部通过。Jest继续使用既有--forceExit口径并保留开放句柄提示。
  • 应用内浏览器访问真实本地客户端首页路由时,因无可复用客户端登录态正常跳转登录页;未求解验证码或伪造会话。运行时生产CSS确认纯.eyebrow.overview-hero .eyebrow页面覆盖及.sms-send-title跨门户规则均存在,默认1280px和375×812视口均无页面级横向溢出,控制台0条warning/error。登录后的首页、账单和代表单页面验收仍待有效登录态补做,不能表述为已通过。
  • 本步骤没有修改React业务组件、API、数据库schema或migration,没有创建、编辑、删除或导出业务数据,没有发送短信、触发补发/重投,也没有修改Redis Stream、Gateway、通道、余额或客户连接。R0~R11前八步、号码频控/白名单和其他工作区修改继续完整保留,不归因于本步骤。
  • 按用户要求继续仅保留本地修改,不提交、不推送、不部署。R11既定九步当前完成9/9;这表示本轮计划范围完成,不代表剩余单页面CSS已被一次性清空,后续应另立小版本继续。

2026-07-31 工作区业务功能与R0-R11汇总提交门禁

  • 用户已明确授权提交并推送当前工作区全部有效代码,但不部署。提交范围包括号码频次风控和平台级白名单、运营看板与短信记录改进、客户端发送体验、R0-R11渐进式拆分、两条新migration、结构契约、测试脚本、需求/测试/进度文档以及后续global.css拆分计划。
  • 提交前重新执行git fetch --prune,本地分支为mainHEADorigin/main均为0af671b4ed4713912e703defd08791f164d4eb25,没有远端分叉。工作区未发现相较前次停止时新增的未知业务修改。
  • 使用Node.js v24.14.0执行Prisma format、validate、generate和migrate status;本地PostgreSQL仅恢复服务用于只读状态检查,没有执行migration或写入业务数据。源码目录共78条migration,本地数据库schema up to date。
  • API全量测试首次因本地Redis未运行出现1 suite/3项队列等待超时;启动本地Redis并确认PONG后,原命令复跑为29 suites / 389 tests全部通过。没有修改或放宽测试来绕过失败,Jest继续使用既有--forceExit口径。
  • API TypeScript正式构建、前端TypeScript与Vite生产构建通过;前端2532个模块完成转换,CSS 237.70kBgzip 34.79kB)、JS 2003.23kBgzip 596.71kB),仅保留既有大chunk提示。
  • 19个Node结构门禁以及R6/R7两个Go结构门禁全部通过;Gatewaygo test ./... -count=1go vet ./...、依赖缓解安全门禁和Git差异检查通过。
  • api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=继续作为构建缓存或临时产物保留在本地,不纳入提交、不删除、不错误归因。未发送、重投或补发真实短信,未修改真实通道账号、密码、启停状态、企业余额或客户连接,本轮明确不部署。

2026-07-31 ca4f591a 工作区汇总提交记录

  • 业务功能、两条migration、R0-R11渐进式拆分、结构契约、测试脚本和同步文档已形成提交ca4f591afeat: add phone frequency controls and modularize codebase),共216个文件、46214行新增、28329行删除。
  • 提交继续排除api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=;这些本地缓存及临时产物未删除。本文档记录将单独提交并与功能提交一同推送到origin/main
  • 本轮仅提交和推送,不执行tools/deploy/production-deploy.sh,不改变预发布运行版本、服务、数据库migration、Redis Stream、供应商通道或客户连接。

2026-07-31 工作区汇总推送认证阻塞记录

  • 推送前再次执行git fetch --prune,确认origin/main=0af671b4ed4713912e703defd08791f164d4eb25且为本地HEAD祖先;本地提交可以正常fast-forward推送,没有代码冲突或远端分叉。
  • 执行git push origin main时远端返回Failed to authenticate user,因此功能提交ca4f591a及记录提交461a65f8尚未到达远端。现有Windows Git凭据已被服务器拒绝,未删除、覆盖或输出保存的密码/令牌,也未使用预发布服务器SSH私钥冒充Git仓库凭据。
  • 当前阻塞仅为Git远端认证,需要用户重新登录或更新该仓库凭据后重试推送。本轮仍未部署,预发布环境没有任何变化。

2026-07-31 工作区汇总推送成功记录

  • 用户要求再次尝试后,推送前确认本地HEAD=4b9127e1abb78e8ca858fb67d8f4f09d453a3819origin/main=0af671b4ed4713912e703defd08791f164d4eb25,远端仍为本地祖先且不存在分叉。
  • 第二次执行git push origin main成功,远端main0af671b4快进到4b9127e1,功能提交ca4f591a、验证记录461a65f8和认证阻塞记录4b9127e1均已到达远端。首次失败属于凭据助手当时提供的认证状态被服务器拒绝,重试时已取得有效凭据,不涉及代码、分支或合并冲突。
  • 本次只提交和推送代码,没有执行部署;预发布环境运行版本、服务、数据库migration、Redis Stream、供应商通道和客户连接均未改变。

2026-07-31 37ffce40 预生产发布记录

  • 用户明确授权发布到预生产。发布前重新执行git status --short --branchgit diffgit fetch --prune并分别核对HEADorigin/main,确认二者均为37ffce40b274e218e6e64210ac9f0f4db88106c8。工作区仅保留既有api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=,均未纳入发布、提交或删除,也未发现其他会话新增的未知业务修改。
  • 发布前预生产.deployed-commit=c0a4317a7ea641bab39294e596f58f859edfca73,数据库共76条migrationAPI、Gateway、Nginx、PostgreSQL、Redis、MinIO均为active,目标端口均监听,Redis返回PONGStream消费者1、pending=0、lag=0,下游120秒内活跃连接为0API/Gateway近30分钟error级日志为0。4条active供应商通道当时均为connected 1/1。
  • 发布包严格从Git提交37ffce40b274e218e6e64210ac9f0f4db88106c8生成:outputs/cmpp-37ffce40-20260731-234258.tar.gz,共786个条目、2078953字节,本地与服务器SHA-256均为9ef5c5f6ee71cefecb1d3ae44f66875ea7bb5b74f1043b3bb2cd8c2cd7c3e972,服务器端压缩包完整性检查通过。
  • 发布前备份目录为/opt/cmpp-platform-backups/releases/20260731-234347-before-37ffce40。PostgreSQL备份postgresql.sql.gz为7931336字节,SHA-256=3d48c4ec5aebe177bb7e2354c4c8ceede679acf984d64d53f3465ab6e9e16127;运行源码备份runtime-source.tar.gz为1818522字节,SHA-256=c8ad0fb47854a8a3e60da1415a8da70c09d11021fa0f677120c17a09b9985709;环境文件备份cmpp-platform.env为850字节,SHA-256=189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三项备份均完成完整性和哈希复核,上一运行目录保留为/opt/cmpp-platform.previous-20260731-234453
  • 使用规定的tools/deploy/production-deploy.sh完成部署,Gateway先于API重启。新增migration 20260730093000_add_phone_frequency_controls20260730114500_add_phone_frequency_whitelist均已应用;预生产现有78条migrationPrisma确认数据库schema up to datePhoneFrequencyHitPhoneFrequencyStatePhoneFrequencyWhitelist三张新表存在。
  • 发布后.deployed-commit=37ffce40b274e218e6e64210ac9f0f4db88106c8。API、Gateway、Nginx、PostgreSQL、Redis、MinIO均为active12026、17890、8090、3000、6379、5432、9000均监听;内网API/Gateway health和MinIO health通过,公网首页、运营端、客户端及API health均HTTP 200,公网CMPP 17890 TCP可连接。
  • Redis返回PONGgateway.submit.commands消费者组为cmpp-gateway,消费者1、pending=0、lag=0、entries-read=2148。号码频控12个配置键已加载,两条默认规则分别为24小时10条和5分钟5条;号码频控命中与平台级白名单接口未登录访问均返回401,确认真实后端路由已注册并受权限保护。
  • 发布后API和Gateway自本次发布起error级日志均为0,panic/fatal/unhandled/exception/error关键字检查无新增异常;120秒内活跃下游客户连接仍为0。未发送、重投或补发真实短信,未修改真实通道账号、密码、启停状态、企业余额或客户连接。
  • 发布后供应商通道现状为3条connected 1/1会员营销-铁布衫赛邮行业-王斯评中转赛邮行业-王斯评中转副本会员营销-富泷持续约90秒为failed 0/1,数据库原因为authentication / connect response status: auth failed。保留系统自动重连,未修改其账号、密码或启停状态。
  • 依赖缓解安全门禁通过。npm audit仍报告既有前端2项high(未使用的React Router RSC路径)和API 3项moderatePrisma工具链)告警,未执行可能引入破坏性升级的audit fix --force

2026-08-01 下游人工重投弹窗与结果反馈修复(本地未提交)

  • 线上只读诊断确认预生产运行37ffce40,单条重投真实逻辑一直是操作前调用浏览器原生window.confirm、成功后仅静默刷新列表、失败时仅在页面顶部显示弱提示;AdminDownstreamDeliveriesPage.tsxRealseV2.0/c0a4317a37ffce40之间无差异,本次缺少成功反馈不是R0-R11拆文件引入的回归。拆分仅将同一真实POST接口迁入src/api/admin/operations.api.ts
  • 线上OperationLog只读记录显示2026-07-31 16:01:5516:02:41已受理多条真实状态回执人工重投,其中同一记录人工次数达到2,说明静默成功与缺少处理中锁会增加误判和重复操作风险;诊断过程没有新增重投或修改线上业务数据。
  • 运营端下游投递记录页改用平台Modal完成单条和批量重投确认,明确展示投递类型、消息ID或所选条数以及客户侧重复处理风险;提交期间确认按钮显示“重投处理中…”且所有重投入口禁用,避免同一页面重复点击。
  • 单条真实接口成功后结果弹窗展示后端返回的当前投递状态和manualRetryCount;批量接口结果始终展示total/successCount/failedCount,部分或全部失败时列出真实逐条错误。请求异常时弹窗提醒先刷新核对人工次数和系统日志,避免在结果不明确时直接重复提交。
  • 已同步需求文档和TC-GW-014/TC-GW-016,覆盖取消不请求、确认弹窗、处理中防重复、单条成功、批量全成功/部分失败、异常结果提示。代码按用户要求仅保留本地,未提交、未推送、未部署;未发送、补发或重投真实短信。
  • 使用Node.js v24.16.0执行前端TypeScript和Vite v8.1.5生产构建通过,2532个模块完成转换;仅保留既有约2.01MB单chunk提示,git diff --check通过。应用内浏览器及Chrome均无可复用的本地运营端登录页,遵守验证码边界且避免真实重投,没有为了视觉验收伪造会话或调用写接口;登录后的确认/结果弹窗真实点击验收待后续具备会话时补测。

2026-08-02 运营端安全控制时间格式与企业签名删除稳定性回归(本地未提交)

  • 全局黑名单“入库时间”和敏感词“创建时间”不再直接输出后端 UTC ISO 字符串,统一复用formatDateTime;共享格式化工具显式固定Asia/Shanghai并输出YYYY-MM-DD HH:mm:ss,避免依赖访问者设备时区。真实数据库全局黑名单时间为 UTC 2026-08-02 09:02:11,页面显示北京时间2026-08-02 17:02:11;敏感词页面显示2026-08-02 17:02:22,两处均无T/Z
  • 企业签名删除使用真实 Smoke Test Enterprise / Smoke SMS App 共执行10轮:3轮创建后直接删除、3轮编辑为待审核后删除、2轮成功反馈修复后复测及2轮截图/最终确认。PostgreSQL确认10条测试签名均为auditStatus=deletedOperationLog存在10条governance.delete/signature记录;每轮刷新后列表均不再返回目标签名,未发生删除失败、重复删除或残留 active 数据。
  • 原“不稳定”现象不是删除事务或幂等链路失败。删除组件成功后立即调用父列表刷新,目标签名卡片被移除时连同弹窗一起卸载,导致已经生成的“删除已完成/操作单号”结果区无法展示;同时AppShell存在独立的待审核任务原生 alert,签名编辑进入待审核后可能在时间上干扰操作观感,但本次10轮没有再次触发该提醒。
  • DeleteRiskAction现改为删除成功后切换到独立结果视图,明确展示“删除已完成”和操作单号;用户关闭结果弹窗后才通知父列表刷新。修复后直接删除和编辑为待审核后删除均验证结果视图可见,关闭后列表刷新并移除签名。
  • 已同步需求文档和TC-ADMIN-026/TC-ADMIN-027。Node.js v24.16.0下前端TypeScript和Vite v8.1.5生产构建通过(2532 modules),删除治理定向测试1 suite / 6 tests通过,git diff --check通过,应用内浏览器控制台无相关warning/error。
  • 本轮测试数据使用独立前缀并全部按系统规则逻辑删除;全局黑名单、敏感词和签名仅保留规定的deleted审计历史。未发送、重投或补发短信,未修改企业余额、真实通道账号/密码/状态、Redis Stream或客户连接。修改仅保留本地,未提交、未推送、未部署;原有下游人工重投及其他工作区改动继续保留,不归因于本轮。

2026-08-02 下游重投反馈与时间/删除稳定性修复发布前门禁

  • 用户明确授权提交、推送并部署当前工作区全部有效代码。发布范围为下游投递单条/批量人工重投确认与结果反馈、提交期间防重复操作、运营端日期时间统一为北京时间,以及删除治理成功结果在父列表刷新前稳定展示;同步包含需求和测试用例文档。
  • 发布前重新执行git status --short --branch、完整git diffgit fetch --prune并分别核对HEADorigin/main,二者均为ecc3d7a5045b7669d102f4c81cd2f011b207b3b5且无分叉。RealseV2.0注解标签仍指向c0a4317a7ea641bab39294e596f58f859edfca73,既定代码回滚基线有效。
  • 发布前预生产实际运行37ffce40b274e218e6e64210ac9f0f4db88106c8,源码与数据库均为78条migration。API、Gateway、Nginx、PostgreSQL和MinIO为activeRedis实际端口监听且返回PONGgateway.submit.commands消费者1、pending=0、lag=0。4条active供应商通道均为connected 1/1120秒内活跃下游连接为0API/Gateway近30分钟error级journal均为0。
  • 本地首次Prisma命令命中系统PATH中的旧Node.js并因不支持??=退出,未进入schema检查且未产生代码改动;切换至工作区Node.js v24.14.0后,Prisma format、validate、generate和migrate status全部通过,本地数据库schema up to date。
  • Node.js v24.14.0下API全量29 suites / 389 tests全部通过,API TypeScript正式构建、前端TypeScript与Vite v8.1.5生产构建通过(2532 modules);Gatewaygo test ./... -count=1go vet ./...、19个Node结构门禁、2个Go结构门禁、依赖缓解安全门禁及git diff --check全部通过。Jest仅保留既有--forceExit开放句柄提示,Vite仅保留既有约2.01MB单chunk提示。
  • api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=继续作为构建缓存或临时产物排除,不提交、不删除、不错误归因。发布和验证过程禁止发送、重投或补发真实短信,禁止修改真实通道账号、密码、启停状态、企业余额或客户连接。

2026-08-02 94e997ec 预生产发布记录

  • 功能提交94e997ec4d7566f6d6d7131c0ada9a17a23099e3已推送至origin/main。第一次推送因远端凭据助手返回Failed to authenticate user失败;重新fetch确认远端没有变化且可fast-forward后第二次推送成功,不涉及代码冲突或分支合并。
  • 发布包严格从功能提交生成:outputs/cmpp-94e997ec-20260802-204038.tar.gz,包含623个跟踪文件、2084685字节,本地与服务器SHA-256均为d76a5b4de5a8a8dae6c218d43221e3807bab51dac566bc9ee0e40219a19ec702,服务器tar完整性检查通过。
  • 发布前备份目录为/opt/cmpp-platform-backups/releases/20260802-204103-before-94e997ec。PostgreSQL备份postgresql.sql.gz为9895326字节、SHA-256=a8f317f68d1fa49a125f9188c36213b40fd19eee1f1bf0d95c8432322bc08824;运行源码备份runtime-source.tar.gz为2106891字节、SHA-256=f928b28ccbc74529c4457e0a74086750b4f56051138b8cdaa6ad320bbca38460;环境文件cmpp-platform.env为850字节、SHA-256=189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三项备份均通过gzip/tar、非空和sha256sum -c检查,权限为600;上一运行目录保留为/opt/cmpp-platform.previous-20260802-204103
  • 首次切换尝试因Git归档中的production-deploy.sh没有可执行位而在前置test -x断言处退出;当时当前运行目录仍为37ffce40.previous尚未创建、服务均为active,没有发生目录替换、migration或服务重启。复核后改为校验脚本普通文件并继续用bash tools/deploy/production-deploy.sh调用,同时增加失败自动恢复运行目录与服务的保护。
  • 使用规定的tools/deploy/production-deploy.sh完成正式部署,Gateway先于API重启。Prisma确认78条migration且无待执行项,前端、API和Gateway构建成功,Nginx配置检查通过,.deployed-commit=94e997ec4d7566f6d6d7131c0ada9a17a23099e3
  • 部署后Gateway、API、Nginx、PostgreSQL、实际Redis单元redis.service和MinIO均为activeredis-server.service为未使用的别名单元且显示inactive,实际Redis进程/usr/bin/redis-server 127.0.0.1:6379正常。12026、17890、8090、3000、6379、5432和9000均监听,内网API/Gateway/MinIO health通过;公网首页、运营端、客户端和API health均HTTP 200,公网CMPP 17890 TCP可连接。
  • Redis返回PONGgateway.submit.commands消费者组为cmpp-gateway,消费者1、pending=0、lag=0、entries-read=3047。部署后约95秒内API/Gateway error级journal均为0,关键字检查无panic/fatal/unhandled/exception/error120秒内活跃下游客户连接为0。
  • 4条active供应商通道中3条稳定connected 1/1会员营销-铁布衫赛邮行业-王斯评中转赛邮行业-王斯评中转副本会员营销-富泷在部署前为connected 1/1Gateway重启后持续约95秒为failed 0/1,数据库原因为authentication / connect response status: auth failed;保留系统自动重连,没有修改其账号、密码或启停状态。
  • 依赖缓解安全门禁通过。npm audit仍报告既有前端2项high(未使用的React Router RSC路径)和API 3项moderatePrisma工具链)告警,未执行可能引入破坏性升级的audit fix --force。本次没有发送、重投或补发真实短信,没有修改企业余额、客户连接或真实通道配置。

2026-08-03 客户端今日消费金额、审核提交时间与查询控件统一(本地未提交)

  • 客户端短信服务工作台在“今日返还金额”前增加“今日消费金额”,直接展示当前企业真实 Dashboard API 的today.spendCents;该字段由后端按当前租户及北京时间当天SmsMessageRecord汇总,不新增浏览器估算、静态数据或本地缓存。四张金额/发送指标卡在桌面端四列、1180px以下两列、780px以下单列展示。
  • 新增全局查询尺寸令牌:普通条件220px、日期区间320px、查询/重置按钮88px;新增共享.ui-filter-row/.ui-filter-actions布局并保留R11既有页面类兼容。风控规则页的规则范围、平台白名单和号码频次触发记录不再整行拉伸,白名单与触发记录增加等宽重置按钮并按明确默认值重新请求真实接口。
  • 企业认证、短信、模板、签名、引流信息五个审核页面均增加“提交时间”日期区间;签名和引流的导入批次审核Tab也使用已有真实分页日期参数。前端分别传递submittedAtFrom/submittedAtTo或导入批次startAt/endAt,不是仅过滤当前页面数组。
  • 后端新增共享北京时间日期边界解析,校验YYYY-MM-DD、真实日历日期和范围顺序,并生成包含开始日00:00:00及结束日23:59:59.999的闭区间。数据库查询分别落到企业认证submittedAt、短信审核任务createdAt、模板createdAt、签名当前提交口径updatedAt和引流信息submittedAt;没有新增schema或migration。
  • 新增/补充日期筛选单元测试。定向结果为日期边界与企业认证2 suites / 6 tests、风控审核1 suite / 16 tests、短信配置1 suite / 63 tests全部通过;本地Redis和PostgreSQL端口均监听时,API全量30 suites / 394 tests全部通过,保留既有--forceExit提示及测试场景内预期的错误/告警日志。
  • API TypeScript正式构建、前端TypeScript与Vite v8.1.5生产构建通过(2532 modulesCSS 239.86kB/gzip 35.11kBJS 2007.30kB/gzip 597.78kB),仅保留既有大chunk提示。R11 foundation/shared components/admin/client四项样式门禁和git diff --check通过;契约同步锁定3个查询尺寸令牌、共享筛选布局和DateRangeInput绑定。
  • 应用内浏览器访问本地客户端工作台和运营端风控路由时,均被真实鉴权守卫正确重定向到对应图形验证码登录页;页面身份正确、无框架错误覆盖,控制台0条warning/error。没有可复用登录态,未解验证码或伪造会话,因此登录后金额卡、审核筛选和风控布局的真实交互视觉验收保留为人工登录复核项。
  • 已同步首版需求、系统功能测试用例和本进度文档。本轮按用户要求保持全部业务代码未提交、未推送、未部署;既有api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=继续保留且不纳入本轮归因,未发送短信、修改余额、通道配置或客户连接。

2026-08-03 引流信息识别与统计(本地开发中,未提交)

  • 本期范围确定为只识别、记录、查询和统计是否含引流信息;不根据报备/审核状态做发送、拒绝或人工审核。客户端批量发送和 CMPP 入站中的DRAINAGE_NOT_APPROVED分支已移除,既有引流资料匹配只保留关联信息,不参与发送决策。
  • 新增DrainageDetectionRule真实数据库模型、消息记录识别快照字段及 migration;检测器按规则类型对副本规范化,覆盖裸域名/短链/IP、中文标点和空格拆分 URL、+86/空格/短横线手机号、括号区号/分机固话,并排除邮箱。批量发送、CMPP 入站和通道测试记录写入同一识别快照。
  • 运营端新增“系统管理 → 引流识别规则”页面及真实 CRUD、启停、测试接口;短信记录新增含引流/不含引流/未检测筛选、命中片段提示色高亮和 CSV 列。
  • 发送质量明细的通道×运营商矩阵保留整体聚合,并新增含引流、不含引流、未检测切分结果;运营看板第一张签名表改为全部短信,第二张只取识别为含引流的短信。
  • 当前验证:Prisma Client 已基于新 schema 生成且 schema validate 通过;API TypeScript 构建、前端 TypeScript检查和 Vite v8.1.5 生产构建通过(2533 modulesCSS 241.13kB/gzip 35.30kBJS 2016.72kB/gzip 600.04kB),仅保留既有大 chunk 提示。识别器及发送链路/通道/运营统计定向回归 4 suites / 180 tests 通过,API 全量 31 suites / 403 tests 通过;Jest 仍保留既有开放句柄--forceExit提示。未在本地或预生产执行 migration,未执行 Gateway 回归或登录后浏览器验收。
  • 全部修改仅保留本地,未提交、未推送、未部署;未发送、补发、重投真实短信,未修改真实通道账号、密码、启停状态、企业余额或客户连接。工作区中原有认证、风控、审核样式、日期筛选、构建缓存和临时文件继续保留,不归因于本需求。
  • 本地页面联调时发现3000端口仍由2026-08-02启动的旧API进程占用,当前源码进程因EADDRINUSE未实际接管,导致登录后访问新接口返回Cannot GET /api/admin/dictionaries/drainage-detection-rules。已仅重启本工作区本地API,确认新路由完成挂载、API health与4173前端预览均为HTTP 200。
  • 初始migration中的默认正则使用了JavaScript字符串式双反斜杠,而PostgreSQL标准字符串会原样保存,导致数据库内3条默认规则无法命中。初始种子已改用美元引用的单反斜杠表达式,并新增20260803140000_fix_default_drainage_detection_rule_patterns向前修复migration;本地库已应用至80条migration。真实本地数据库现有URL/裸域名、手机号、固话3条active默认规则;组合样例正确命中中文句号裸域名、+86短横线手机号和括号区号带分机固话,同时排除邮箱。

2026-08-03 下游投递与恢复状态筛选布局优化(本地未提交)

  • 设计规范核对确认R11已有共享.ui-filter-row/.ui-filter-actions:普通查询控件使用--query-control-width: 220px,日期范围使用--query-date-range-width: 320px,查询/重置按钮使用--query-action-width: 88px;容器允许按完整控件换行,780px以下条件整行、按钮两列。下游投递记录和恢复状态管理仍使用旧admin-task-filter自适应网格,5组条件及按钮会为维持单行而被压缩。
  • 两页筛选区已改为直接复用共享R11布局和操作区,不新增页面私有宽度、不改变筛选状态、查询接口、日期口径、导出或重投行为。已同步首版需求和TC-GW-014/TC-GW-024的桌面换行、移动端整行及无压缩/重叠验收要求。
  • 同轮纳入运营端用户管理:原页面在外层工具栏内再用repeat(auto-fit, minmax(160px, 1fr))压缩五组查询条件,现改为与查询/重置共同使用共享筛选流式布局;“新增用户”继续作为独立业务操作。查询参数、真实GET /api/admin/users组合查询及新增用户行为均未改变,并同步TC-USER-FILTER-001布局验收。
  • Node.js v24.16.0下前端TypeScript检查和Vite v8.1.5生产构建通过(2533 modulesCSS 241.00kB/gzip 35.28kBJS 2016.78kB/gzip 600.05kB),仅保留既有大chunk提示;R11 foundation/shared components两项样式门禁及git diff --check通过。系统PATH旧Node首次执行Vite时因不支持??=产生未处理Promise警告但错误返回0,已明确判定无效并用Node.js v24重新完成全部门禁。
  • 本地深链访问下游投递页被真实鉴权守卫正确重定向至运营端登录页,页面身份正常、无框架覆盖、控制台0条warning/error;没有可复用登录态且未解图形验证码或伪造会话,因此三页登录后桌面/移动实际截图与查询交互仍需人工登录复核。修改仅保留本地,未提交、未推送、未部署,也未触发任何下游重投或真实短信操作。

2026-08-03 CMPP逐分片回执与72小时超时失败回执(本地未提交)

  • 协议和历史代码复核纠正了“临时状态”和“长短信聚合回执”两项不严谨结论:CMPP只有状态值,没有规定临时状态生命周期,也没有长短信聚合回执报文。历史版本曾按上游分片产生多条下游投递,但全部复用第一片客户Msg_Id;后续为修复并发重复补发/退款改成每条业务短信一条回执,两种实现都不满足逐个原始客户分片精确关联。
  • Gateway入站契约现传递每包真实Registered_Delivery;短短信写入SmsMessageRecord.cmppRegisteredDelivery,长短信逐片写入CmppInboundLongMessageSegment.registeredDelivery/sequenceId。migration20260803190000_downstream_fragment_receipts同时增加timeoutReceiptQueuedAt,历史已有CMPP记录按原行为回填为请求回执;本地PostgreSQL已成功应用至81条migration。
  • 内部长短信仍只形成一个业务终态、一次重投决定、一次退款和一个HTTP最终事件。CMPP下游改用receipt:{messageRecordId}:segment:{segmentIndex}逐片幂等;Gateway根据每片原始SubmitGroupMessageId + Sequence_Id重建对应SubmitResp Msg_Id,在线会话不再导致所有分片回执复用第一片Msg_Id。Registered_Delivery=0分片不建CMPP回执。
  • 下游逐片payload优先使用对应SmsMessageSegmentAudit的真实状态、原始码、错误码和到达时间;已成功分片不会因另一片失败被改写。业务已明确最终失败而个别片尚无状态时,缺失片使用整条短信的明确失败结果,保证每个请求回执的原始分片都有最终答复。
  • 72小时扫描将submitted/unknown明确改为timeout + undelivered + EXPIRED + RECEIPT_TIMEOUTHTTP建立一个失败Webhook,CMPP为每个请求回执的原始分片建立失败状态报告。只有全部应建投递持久化后才写timeoutReceiptQueuedAt;建单中断时下一轮扫描继续补齐,退款仍由原消息级幂等键保证一次。
  • 验证结果:Prisma format、validate、generate和API TypeScript正式构建通过;新增逐片目标/Registered_Delivery/HTTP超时及中断恢复测试后,定向3 suites / 117 tests、API全量32 suites / 407 tests通过,保留既有Jest开放句柄--forceExit提示及预期场景日志。Gatewaygo test ./... -count=1go vet ./...通过,并新增不同原Sequence_Id生成不同回执Msg_Id的专项测试。
  • 本轮没有修改或清理工作区中既有的引流识别、审核筛选、查询布局和其他会话修改;构建缓存、outputs/和空文件=继续保留。代码按用户要求未提交、未推送、未部署;没有发送、补发或重投短信,没有修改预生产数据库、企业余额、通道配置或客户连接。

2026-08-03 跨会话工作区整合与提交前完整回归

  • 汇总当前工作区全部有效修改后,组合范围确认为四组:客户端今日消费与运营统计、审核日期和共享查询布局、引流信息识别与统计、CMPP逐分片回执及72小时超时失败回执。3条新增migration按202608031130002026080314000020260803190000顺序衔接;本地真实PostgreSQL共81条migration且schema up to date。
  • 完整回归发现拆分阶段的结构契约未同步业务演进:R1新增5个引流识别规则API且7个查询实现更新,R5通道测试加入引流识别,R2短信导出/质量统计查询变化,R8/R9/R10的引流识别、Registered_Delivery、逐片回执及超时回执实现变化,R3审核提交时间查询变化。已按实际组合实现更新对应契约哈希;R0将已失效的“单条聚合最终回执”特征替换为“同一分片幂等一次”和“HTTP单事件+CMPP逐请求分片”两项真实特征,没有恢复错误的聚合回执行为。
  • Node.js v24.16.0下Prisma format、validate、generate、migrate status通过;API全量32 suites / 407 tests全部通过,API TypeScript正式构建通过;前端TypeScript与Vite v8.1.5生产构建通过(2533 modules),仅保留既有约2.02MB单chunk和插件耗时提示。
  • Gatewaygo test ./... -count=1go vet ./...通过;19个R0-R11结构门禁全部通过;依赖缓解安全门禁通过;git diff --check和合并冲突标记扫描通过。Jest仍保留既有--forceExit开放句柄提示及测试场景内预期日志。
  • 依赖审计仍有已知告警:前端2项high来自项目未启用的React Router RSC路径,专用门禁已验证RSC未使用;API 3项moderate来自Prisma开发工具链的Valibot间接依赖。未执行可能改变依赖或引入破坏性升级的自动修复。
  • api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=继续作为构建缓存或临时产物排除,不提交、不删除、不错误归因。本轮未部署、未发送/补发/重投短信,也未修改预生产数据库、企业余额、通道配置或客户连接。

2026-08-03 530a65de 预生产发布记录

  • 用户明确授权发布最新代码。发布前重新执行git status --short --branchgit diffgit fetch --prune并核对HEADorigin/main,确认二者均为530a65de809a1d2dee7000642bc99c1e483c15f6。工作区仅保留既有api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=,没有把构建缓存或临时产物纳入发布,也未发现待提交的业务代码。
  • 发布前预生产.deployed-commit=94e997ec4d7566f6d6d7131c0ada9a17a23099e3,源码和数据库均为78条migrationAPI、Gateway、Nginx、PostgreSQL、Redis、MinIO均active12026、17890、8090、3000、6379、5432、9000均监听,API/Gateway/MinIO health、Redis与Stream正常,Stream消费者1、pending=0、lag=0120秒内活跃下游客户连接为0API/Gateway近30分钟error级journal为0。4条active供应商通道发布前均为connected 1/1。
  • 发布包严格从Git提交530a65de809a1d2dee7000642bc99c1e483c15f6生成:outputs/cmpp-530a65de-20260803-163032.tar.gz,共799个条目、2113112字节;本地与服务器SHA-256均为a0b9870aa33748ddd1fc2948bca6d4fee16484195f261ee27c69a5910978a7ac,服务器tar完整性检查通过。
  • 发布前备份目录为/opt/cmpp-platform/backups/releases/20260803-163032-before-530a65de。PostgreSQL备份postgresql.sql.gz为9707232字节、SHA-256=14d28a0c31e56a9784d019bb26f0a27804331ae0a101e4632f4cabe5e15f8475;运行源码备份runtime-source.tar.gz为2114266字节、SHA-256=db15f22191eb99d50a989c5153157c2ed6c366ae982791908833eea9459538aa;环境文件cmpp-platform.env为850字节、SHA-256=189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7。三项备份均通过gzip/tar、非空和sha256sum -c复核,上一运行目录保留为/opt/cmpp-platform.previous-20260803-163032
  • 使用规定的tools/deploy/production-deploy.sh完成部署,Gateway先于API重启。新增20260803113000_add_drainage_content_detection20260803140000_fix_default_drainage_detection_rule_patterns20260803190000_downstream_fragment_receipts三条migration成功应用,源码与数据库均为81条migration;前端、API和Gateway正式构建及Nginx配置检查通过,.deployed-commit=530a65de809a1d2dee7000642bc99c1e483c15f6
  • 发布包装脚本完成核心部署后,在最终读取校验单时发现备份最初位于旧运行目录内、随目录切换进入previous路径,因此该包装命令最终返回1;当时production-deploy.sh已经明确输出Done/DEPLOY_OK,发布和服务检查均成功,且失败处理已处于不回滚阶段。随后仅将已完成校验的精确备份目录移动到上述约定位置并再次执行sha256sum -c,三项均为OK;没有重复部署或重复执行migration。
  • 发布后API、Gateway、Nginx、PostgreSQL、Redis、MinIO均active12026、17890、8090、3000、6379、5432和9000均监听;内网API/Gateway/MinIO health通过,公网首页、运营端、客户端和API health均HTTP 200,公网CMPP 17890 TCP可连接。Redis返回PONGgateway.submit.commands消费者1、pending=0、lag=0、entries-read=3270;观察窗口后API/Gateway error级journal仍为0120秒内活跃下游客户连接为0。
  • 供应商通道重启后3条保持connected 1/1会员营销-铁布衫赛邮行业-王斯评中转赛邮行业-王斯评中转副本会员营销-富泷由发布前connected 1/1变为failed 0/1,观察窗口复查仍为authentication / connect response status: auth failed;保留系统自动重连,没有修改其账号、密码或启停状态。
  • 依赖缓解安全门禁通过。npm audit仍为已知前端2项high(项目未使用的React Router RSC路径)和API 3项moderatePrisma开发工具链),未执行破坏性自动升级。本次没有发送、重投或补发真实短信,没有修改企业余额、客户连接或真实通道配置。

2026-08-05 HTTPS 双域名与 HTTP API 公网地址配置(服务器配置完成,业务代码未提交)

  • sms.lisglo.com 已使用匹配 *.lisglo.com 的 Cloudflare Origin CA 证书和 SESSION_COOKIE_SECURE=true;Nginx 只监听 443/旧切换端口 12026,不监听 80。新增基于原始 TCP 对端 $realip_remote_addr 的 Cloudflare 网段限制,并启用 Cloudflare 全局 Authenticated Origin Pulls:橙云公网健康接口返回 200,直连源站并指定 sms.lisglo.com SNI 因缺少 Cloudflare 客户端证书返回 400,避免绕过 Cloudflare WAF。
  • 新增 /usr/local/sbin/update-cloudflare-nginx-ranges 与 systemd timer,每日从 Cloudflare 官方 IPv4/IPv6 列表生成 Real-IP 与源站判定配置;更新前校验格式和最小网段数、执行 nginx -t,失败时保留旧配置。当前列表为 IPv4 15 段、IPv6 7 段,下一次计划执行时间由 timer 随机延迟确定。
  • api.lisglo.com 灰云 A 记录已真实解析到 8.160.169.106。已创建仅限 lisglo.com DNS 编辑的 Cloudflare 用户 API Token,使用 Certbot 5.7.0 和 DNS-01 签发独立 ECDSA Lets Encrypt 证书,有效期至 2026-11-03;凭据文件仅 root 可读(0600),一次性中转文件和本地剪贴板已清理。新增独立 API-only Nginx 虚拟主机,只放行 /api/health/api/openapi/v1//api/client-docs,管理页面、客户端页面、运营/客户端私有 API 均返回 404。
  • 本地业务代码增加后端环境变量 HTTP_API_PUBLIC_ORIGIN,由真实配置 API 返回 publicOrigin;运营端参数复制、客户端接口概览/复制和 Swagger 链接统一使用 https://api.lisglo.com,不再错误沿用管理页面 window.location.origin。同步更新首版需求、TC-HTTP-PUBLIC-ORIGIN-001、环境示例和部署手册。
  • 新增 cmpp-letsencrypt-renew.timer 每日检查续期,续期成功后先执行 nginx -t 再 reloadLets Encrypt staging dry-run 已成功。公网验证结果为 sms 健康接口 200、api 健康接口和客户 Swagger 200、OpenAPI 未认证请求 401、api 根路径/管理与客户端入口/私有 API 404;api 直连源站使用可信 Let’s Encrypt 证书并返回 200。
  • 本轮服务器配置备份位于 /opt/cmpp-platform-backups/config/20260805-100601-cloudflare-origin-restriction20260805-102234-api-letsencrypt20260805-102550-sms-aop20260805-102614-http-api-origin-env。未修改防火墙、安全组、CMPP 17890、短信数据、通道、余额或客户连接;业务代码保持未提交、未推送、未部署,生产环境变量已预置但需代码发布后页面才会展示新的公网 API 地址。

2026-08-05 旧 IP:12026 登录短时过渡与撤销(已恢复 HTTPS-only,未提交)

  • 真实故障确认为 HTTPS 切换后服务器设置 SESSION_COOKIE_SECURE=trueAPI 发送的 Secure 会话 Cookie 无法被 http://8.160.169.106:12026 接收;因此登录接口成功后,受保护页面恢复会话失败并重新跳回登录页。
  • 为保留旧 IP 登录入口,预生产环境临时改为 SESSION_COOKIE_SECURE=false 并只重启 cmpp-api.service。进程环境已确认读取 falseAPI 服务 active 且重启后无 error 级 journal;IP 首页、运营登录页和健康接口均返回 200,sms.lisglo.com 经 Cloudflare/AOP 的健康接口及 api.lisglo.com 健康接口也均返回 200。
  • 该短时方案保留了 HttpOnlySameSite=Lax 和运营/客户端独立 Cookie,但 HTTPS 入口也会使用非 Secure 的过渡期 Cookie,已有登录用户可能需要重新登录;用户随后决定不接受该长期代价。临时调整前的配置备份位于 /opt/cmpp-platform-backups/config/20260805-105501-ip-login-cookie-compat
  • 用户复核安全代价后决定不再保留 IP 直接登录,也暂不新增灰云管理域名证书。预生产已于 11:04 将 SESSION_COOKIE_SECURE 恢复为 true 并只重启 API;进程环境确认读取 truesms.lisglo.com 经 Cloudflare/AOP 与 api.lisglo.com 健康接口均返回 200API active 且重启后无 error 级日志。12026 当前仍监听并可健康检查,但不再是受支持的登录入口;恢复前配置备份位于 /opt/cmpp-platform-backups/config/20260805-110427-restore-secure-cookie
  • 同步撤销首版需求和系统测试用例中的 IP 登录兼容要求,部署规范明确只支持 HTTPS 登录;本次未新增证书、未修改 Nginx、Cloudflare、防火墙或安全组,也未提交、推送或部署业务代码。

2026-08-05 运营端待审核角标轻量轮询(本地未提交)

  • 新增真实后端 GET /api/admin/operations/pending-audits,仅并发统计企业认证、短信审核、模板、签名和引流信息五类待审数量及总数,复用运营看板原有口径,不执行发送、账务、连接、下游投递和趋势等看板查询。
  • 运营端全局布局的首次加载、30 秒轮询、窗口重新获得焦点和审核刷新事件已改用轻量接口,不再调用 /api/admin/operations/dashboard/statistics;运营看板页本身仍保留完整统计接口。
  • 新增服务层单元测试,校验五类数量口径、总数和租户边界,并断言该路径不执行短信状态聚合或看板原始 SQL。
  • 本地验证通过:针对性 operations.service.spec.ts 27/27API 全量 32 suites / 409 testsAPI TypeScript 构建、前端 TypeScript 检查、Vite 生产构建和 git diff --check均通过。Vite 仍有已知大 chunk 警告,与本次接口替换无关。
  • 本地 4173 前端登录页标题、DOM 和主要控件可正常渲染;本地未运行真实 API,图形验证码请求返回 502,因此未伪造登录或进行登录后端到端轮询验收。本次未提交、推送、部署,也未发送或重投短信,未修改通道、余额或客户连接。

2026-08-06 供应商长短信整条级成功回执与网关异常双Tab(本地未提交)

  • 运营菜单“Gateway提交异常”更名为“网关异常”,保留原/admin/gateway-submit-exceptions路由;页面拆为“提交异常”和“回执异常”两个Tab。提交异常继续使用既有真实死信接口,回执异常使用新增GET /api/admin/operations/receipt-anomalies,两处均在标题区解释数据来源、业务含义、不能代表的结论和人工处理注意事项。
  • 通道配置新增longMessageReceiptMode:默认per_segment保持逐分片聚合;仅供应商明确采用整条级成功口径时配置message_level。后一模式收到当前提交尝试的一条成功回执后,只将同次提交尚无回执的分片标记为推断成功,并写compensationType=supplier_message_level_receipt;供应商真实回执仍只保存实际收到的一条,不伪造原始回执。
  • 新增SmsReceiptAnomaly及migration20260806100000_add_receipt_anomalies。整条级成功已经形成delivered后,同一提交尝试再到明确失败时,保留原始失败回执和分片证据,不改写已送达终态、不重复退款/补发、不向客户推送矛盾失败;异常按消息和提交尝试稳定键upsert,重复事件累加发生次数,并可在回执异常Tab分页、筛选和查看结构化详情。
  • 新增发送链、通道配置和运营查询回归,针对性3 suites / 178 tests通过;API全量32 suites / 413 tests通过。API TypeScript构建、前端TypeScript、Vite生产构建、Prisma schema validate/generate、R2运营查询/R5通道/R10发送完成结构门禁和git diff --check均通过。Vite仍有既有大chunk告警;Jest仍需--forceExit结束既有开放句柄。
  • docs/contracts/operations-r2-methods.json按当前组合工作区同步:pendingAudits和dashboard哈希属于此前“待审核角标轻量轮询”会话,本轮仅新增回执异常契约/查询,并为同文件当前行尾结果刷新受影响的既有哈希,未把前一会话业务改动归入本需求。
  • 本轮未应用migration到本地或预生产数据库,未连接预生产、未发送/补发/重投短信,未修改真实通道配置、账号密码、启停状态、企业余额或客户连接;代码按要求保持未提交、未推送、未部署。*.tsbuildinfooutputs/和空文件=继续作为其他会话/构建产物保留,不删除、不提交、不归因。

2026-08-06 RealeseV2.3 工作区合并与推送前验证

  • 用户授权将当前工作区全部有效业务代码合并、提交并推送,版本名称按用户给出的精确拼写定为RealeseV2.3。合并范围包括:HTTPS双域名与HTTP API公网地址、运营端待审核角标轻量轮询、供应商长短信整条级成功回执及网关异常双Tab;三组需求、测试、部署说明和进度记录均随代码纳入。
  • git fetch --prune --tags后本地HEADorigin/main均为57b58f1c4052691531941e0fbda02e43ce2fea87,分歧为0/0,因此没有远端提交需要合并,也没有源代码文本冲突。既有annotated恢复标签RealseV2.0仍有效并指向c0a4317a7ea641bab39294e596f58f859edfca73;本轮只提交和推送,不部署、不执行migration。
  • 合并后同步结构契约:R1登记getPendingAudits/listReceiptAnomalies及当前重入队实现,R2登记轻量审核和回执异常查询,R5/R10登记长短信回执口径及处理变化;R6清单的5个声明哈希与当前main既有Gateway源码重新对齐,Gateway业务源码没有工作区改动。全部结构门禁随后通过。
  • 发布前验证通过:API全量32 suites / 413 testsAPI TypeScript构建;前端TypeScript与Vite生产构建;Prisma schema validate/generateGateway go test ./... -count=1go vet ./...19个.mjs结构门禁、R6/R7 Go结构门禁、依赖缓解安全门禁和git diff --check。Vite仍只有既有大chunk警告,Jest仍使用--forceExit结束既有开放句柄。
  • 提交范围排除api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=;这些缓存或临时产物继续保留在工作区,不删除、不提交。本轮未连接或修改生产/预生产服务、数据库、通道、余额或客户连接,未发送、补发或重投真实短信。

2026-08-06 RealeseV2.3 预生产发布记录

  • 发布目标为annotated tagRealeseV2.3对应提交8ad8e6179305f7be3046fc761826c6f1c1b9e4c2。发布前预生产.deployed-commit=530a65de809a1d2dee7000642bc99c1e483c15f6,数据库81条migrationAPI、Gateway、Nginx、PostgreSQL、Redis、MinIO均active,关键端口全部监听,API/Gateway health与Redis PONG通过。5条active供应商通道均为connected 1/1,最近120秒客户下游连接为0,Redis Stream消费者1、pending=0lag=0,近30分钟API/Gateway无error级日志。
  • 精确Git归档outputs/cmpp-RealeseV2.3-8ad8e617-20260806-1128.tar.gz包含803个条目、2128574字节,本地与服务器SHA-256均为3c6c8dd274b7feef783dcb941e83950bf3b24c1841587d1419f4084912ced167,服务器tar完整性检查通过。
  • 发布前备份目录为/opt/cmpp-platform-backups/releases/20260806-112900-before-8ad8e617。PostgreSQL备份postgresql.sql.gz为12118930字节、SHA-256=25c9b47f7287a486b204669c0afc90799a2bb6abd441b7b0fa742440ba1386f7;运行源码runtime-source.tar.gz为2142057字节、SHA-256=d7cb9d03b40687cba5c9b56c48528d3c217fd448e4c221dafe435a616ee40793;环境文件为895字节、SHA-256=7a26d83b062f9d7e9503e2a987f39a899510f8981be63be997bccfc988fbbc60。三项备份均为0600并通过gzip/tar及sha256sum -c,上一运行目录保留为/opt/cmpp-platform.previous-20260806-112900
  • 标准tools/deploy/production-deploy.sh成功完成两套依赖安装、安全缓解门禁、Prisma generate/migrate、前端/API/Gateway构建、Nginx配置校验及Gateway先于API重启。新增20260806100000_add_receipt_anomalies成功应用,预生产共82条migration且Prisma确认schema up to dateSmsReceiptAnomaly表存在,发布时记录数为0。最终.deployed-commit=8ad8e6179305f7be3046fc761826c6f1c1b9e4c2
  • 部署后API、Gateway、Nginx、PostgreSQL、Redis、MinIO均active,关键端口均监听;API/Gateway/MinIO内部健康、Redis PONG、公网页面、运营登录、客户端登录、API health和客户Swagger均通过,客户OpenAPI未认证POST返回401,API专用域名的根路径、管理页面和管理API仍返回404,公网CMPP 17890纯TCP连通。
  • 5条active供应商通道均在本次重启后产生新状态并恢复connected 1/1Redis Stream仍为消费者1、pending=0lag=0,13个通道TPS配置键存在,最近120秒客户下游连接为0。部署后API/Gateway error级journal为0,程序错误关键字无新增;Nginx仅记录正常优雅重启notice。
  • npm审计仍报告根项目2项high及API 3项moderate、2项high;专用安全门禁确认PostCSS补丁、React Router RSC未使用和brace expansion边界有效,未执行可能破坏兼容性的自动升级。本次没有发送、补发或重投真实短信,没有修改真实通道账号、密码、启停状态、企业余额或客户连接。

2026-08-09 运营端休眠唤醒后连续401修复(本地未提交)

  • 生产Nginx只读日志确认pending-audits连续401的响应体长度为86字节,对应SESSION_LOCKED2026-08-09 11:10:45运营端登录成功后,前端在11:10:47立即请求/auth/session/lock11:10:49才完成解锁,而11:10:57短信记录、企业和应用选项接口均返回200。根因是同一SPA重新登录未重置上一会话的内存活动时间,以及布局只读取首次挂载的session.locked快照,锁定后仍保留业务路由和角标轮询。
  • 登录成功后立即调用markUserActivity(),保证新会话使用新的活动起点。AppShell在本地空闲、服务端SESSION_LOCKED和跨标签事件三条锁定入口中统一写入实时锁定状态、暂停业务路由,并将状态回传给运营布局;解锁时恢复路由、清除锁定请求标记并重新挂载当前页面。
  • 运营端待审核角标现在跟随AppShell实时锁定状态启停,锁定后清理30秒定时器和窗口焦点监听;解锁后才重新拉取真实待审核数量。短信记录路由因锁定被卸载,解锁后重新请求真实短信记录及筛选项,不使用缓存或静态数据伪造恢复结果。
  • 使用Node.js v24.14.0分别执行前端TypeScript --noEmit和Vite v8.1.5生产构建,2534个模块构建通过;仅保留既有约2.03MB单chunk和CSS插件耗时提示。git diff --check通过。
  • 本地http://127.0.0.1:4173/#/admin/login浏览器检查通过页面身份、非空渲染、无框架错误覆盖和输入控件交互;本地预览未启动真实API,验证码请求按预期返回502,因此没有伪造登录态,也未在本地完成真实锁定/解锁交互。完整TC-AUTH-014TC-AUTH-016仍需代码发布后在预生产使用真实会话复测。
  • 本轮未提交、未推送、未部署,没有发送、补发或重投真实短信,没有修改数据库、企业余额、真实通道配置或客户连接。既有api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=继续保留,不删除、不提交、不归因。

2026-08-09 签名删除预检与多通道报备汇总修复(本地未提交)

  • 删除预检现已将approvedabandoned等报备终态排除在“未结束报备任务”之外;预生产只读核对的三条任务cmrxc3rgk004017nks1bktp9ncmrxc3rgo004217nkw9enwk72cmrxc3rgr004417nk887sg9ef均为abandoned,修复后不会再仅因这三条历史任务阻止签名删除。模板、引流信息和真实过程态任务仍继续阻止删除。
  • 新增统一报备汇总函数并复用于签名总状态、三网摘要和引流报备摘要:全部目标失败才汇总为failed;通过与失败并存汇总为partial_success;失败与待处理并存保持reporting。运营端签名卡片同步调整为只有所有适用目标均失败才显示红色整体失败,部分失败且仍待处理显示橙色,部分通过显示蓝色。
  • 使用Node.js v24.14.0执行本次相关4个API suites,118个测试全部通过;排除受本地Redis影响的send-chain.service.spec.ts后,其余API全量32个suites、312个测试全部通过。API与前端TypeScript --noEmit --incremental false均通过,Vite v8.1.5生产构建通过(2534个模块,仅保留既有约2.03MB单chunk提示),git diff --check通过。
  • API全量运行结果为33 suites中的32个通过、420个测试中的415个通过;未通过的5项全部位于本次未修改的send-chain.service.spec.ts,原因是本地Redis 127.0.0.1:6379未运行导致BullMQ连接失败和5秒超时。该套件单独重跑同样被Redis重连拖至工具超时,因此不把API全量记为通过,也未为本任务修改发送链代码或启动外部依赖。
  • 本轮没有提交、推送或部署,没有修改预生产数据库、发送真实短信、调整通道配置或客户连接。其他会话已有的登录/休眠恢复代码和文档增量继续原样保留;测试命令意外生成且本轮开始前不存在的根目录pnpm-lock.yaml已删除,既有tsbuildinfooutputs/和空文件=仍受保护。

2026-08-09 发送质量矩阵与成功率色阶统一(本地未提交)

  • 签名通道发送质量明细的“按引流切分”已改为每个通道固定三行“含引流、不含引流、未检测”,并固定三列“移动、联通、电信”;通道集合取整体和引流切分真实数据的并集,缺少真实提交的组合保留位置并显示单个0。整体统计页签及后端统计口径未改动。
  • 新增共享成功率色阶函数,签名质量列表、明细总览、运营商概览、矩阵、短信通道管理列表和通道报备详情统一按0红、>0且<=25橙、>25且<=50黄、>50且<=75蓝、>75且<96绿、>=96深绿展示数字。通道列表和报备详情的提交失败、回执未知、送达失败比例及数量恢复为黑灰色。
  • 使用Node.js v24.14.0执行成功率边界校验,0、0.1、25、25.1、50、50.1、75、75.1、95.9、96共10个边界值全部符合约定;前端TypeScript --noEmit --incremental false通过,Vite v8.1.5生产构建通过(2535个模块),仅保留既有约2.03MB单chunk提示;git diff --check通过。
  • 本步骤只修改前端展示、共享色阶工具及需求/用例/进度文档,没有修改后端、数据库或真实统计接口,没有连接预生产、发送/补发/重投短信,也没有修改真实通道、企业余额或客户连接。代码按要求保持未提交、未推送、未部署;其他会话和前一步已有修改、tsbuildinfooutputs/及空文件=继续保留并保护。

2026-08-09 运营端菜单与查询控件细节修正(本地未提交)

  • 风控规则已从“审核中心”移动到“安全控制”,页面面包屑同步调整,既有/admin/risk-rules路由和真实后端规则接口未改变。发送监控对移动、联通、电信、三网和未识别运营商统一显示中文,未知新值仍原样展示。
  • 待生成报备批次两个页签已移除括号及动态数量,标题固定为“待生成资料”和“已生成批次”;后端返回的total继续用于分页。短信记录通道条件已由自由文本改为通用可搜索Select,真实调用通道接口加载未删除通道,以名称和编码搜索,查询及导出改传精确channelId,重置恢复全部通道。
  • 使用Node.js v24.14.0执行前端TypeScript --noEmit --incremental false通过,Vite v8.1.5生产构建通过(2535个模块),仅保留既有约2.03MB单chunk提示;git diff --check通过。本步骤不涉及后端业务逻辑,因此未增加或运行API单元测试。
  • 本步骤没有连接预生产、修改数据库、发送/补发/重投短信,也没有修改真实通道配置、企业余额或客户连接。代码保持未提交、未推送、未部署;AdminLayout.tsx仅对菜单项位置做局部修改,其他会话已有的会话锁定和轻量轮询增量继续保留且未归因给本步骤。

2026-08-09 URL空白边界识别修正(本地未提交)

  • 引流检测副本不再删除URL类别中的空白字符。协议链接、裸域名及路径遇普通空格、制表符、换行或全角空格时立即结束命中,空白后的字符不再归入前一个链接;空格拆分域名也不再被拼接成一个URL。短信真实原文、命中位置映射、中文句号域名兼容和数据库默认URL正则保持不变,因此本步骤不需要migration。
  • 邮箱排除改用独立检测副本,继续允许仅为排除目的而规范化带空格邮箱,避免其中的数字本地部分被误判为手机号;手机号和固话类别原有空格、短横线及中文标点规避识别不受URL边界修正影响。
  • 引流检测针对性测试13/13通过,覆盖四类空白边界、空格拆分域名不命中、中文句号域名、原文高亮位置、普通及带空格邮箱排除、手机号和固话识别;规则管理与通道相关2个suites、57个测试通过。API正式构建配置TypeScript检查和git diff --check通过。
  • 一次诊断命令误用api/tsconfig.json --noEmit,该配置会包含全部*.spec.ts但不加载Jest全局类型,因而产生既有测试类型环境错误;随后使用项目正式api/tsconfig.build.json重新检查并通过,未修改TypeScript或Jest配置。
  • 本步骤未连接预生产、未修改数据库规则、未发送/补发/重投真实短信,也未修改通道、余额或客户连接;代码保持未提交、未推送、未部署。

2026-08-09 CMPP客户连接请求诊断日志(本地未提交)

  • Gateway入站CMPP CONNECT鉴权请求新增协议版本和原始版本值,并将真实TCP远端IP、Source_Addr账号、Base64 AuthenticatorSource、时间戳一并传给API。API在认证成功或失败时同步写cmpp_connection.connect_requested操作日志,客户入站资源固定为cmpp_downstream_connection;未知账号同样以请求账号为资源ID保存,便于定位恶意连接。
  • 日志ipAddress直接保存Gateway报告的真实远端IP,结构化详情保存认证结果、应用ID、失败原因和全部客户请求参数。标准CMPP CONNECT报文不含明文密码,因此详情明确显示该协议事实;只有兼容调用真实携带password字段时才保存该字段,平台数据库内的应用密钥不会作为客户参数写入日志。
  • 运营端系统与操作日志对cmpp_connection.connect_requested增加“查看详情”按钮,弹窗展示请求IP、账号、密码字段说明、AuthenticatorSource、时间戳、协议版本、结果、失败原因及应用ID;既有列表IP列继续读取真实OperationLog.ipAddress
  • Gateway全量go test ./... -count=1go vet ./...通过;Gateway入站包测试通过。API Gateway认证针对性3/3通过,覆盖成功、应用禁用失败和未知恶意账号;API正式构建TypeScript、前端TypeScript、Vite生产构建和git diff --check通过。Vite仅保留既有约2.03MB单chunk提示,Jest使用--forceExit结束既有开放句柄。
  • 本步骤未实际建立、断开或修改预生产客户连接,未连接预生产数据库,未发送短信,也未修改真实账号、密码、IP白名单、连接数、通道或余额;代码保持未提交、未推送、未部署。

2026-08-09 通讯交互日志完整手机号(本地未提交)

  • ProtocolInteractionLog新增可空phoneNumber字段及migration20260809130000_add_protocol_log_plain_phone。新产生的CMPP/HTTP通讯日志将Gateway或API上报的完整号码写入该字段,不再为新记录生成phoneMasked;既有脱敏列暂不删除,仅作为旧行显示兜底,不执行历史号码恢复或回填。
  • 通讯日志关键词查询已从phoneMasked切换到phoneNumber,运营端列表对象列和详情读取完整号码,筛选提示及页面说明同步明确“完整手机号”。短信正文、密码、密钥、Token、鉴权头和完整请求体仍继续由通讯日志详情清洗逻辑排除。
  • Prisma schema validate和client generate通过;通讯日志服务测试3/3通过,覆盖新日志完整号码持久化、敏感详情排除和完整号码查询。API正式构建TypeScript、前端TypeScript、Vite生产构建和git diff --check通过,Vite仅保留既有约2.03MB单chunk提示。
  • 新migration尚未应用到本地或预生产数据库;本步骤未查询或修改历史手机号,未连接预生产、发送短信、修改通道、余额、客户连接或权限配置。代码保持未提交、未推送、未部署。

2026-08-09 三类报表全量筛选汇总(本地未提交)

  • GET /api/admin/reports/reconciliationprofitquality在原有分页响应中新增summary;后端使用与明细、总数完全相同的where对PostgreSQL报表表执行聚合,不从当前页items二次求和。
  • 对账、利润、质量页在筛选区后展示“筛选结果汇总”,明确说明不受当前分页影响。三页均展示提交/发送/未知/成功/失败合计;利润页另展示全部金额合计和重算综合利润率,质量页展示重算综合成功率。
  • 成功率按合计成功/合计发送、利润率按合计利润/合计净消费计算,避免求和或平均分组百分比导致失真;平均到达时长不可直接加总,未放入汇总区。
  • 使用Node.js v24.14.0运行reports.service.spec.ts 7/7通过,增加无匹配行时合计及综合率全部归零覆盖;API正式构建TypeScript和前端TypeScript均通过。首次测试命令命中系统旧Node导致缺少node:util/types,改用工作区Node后专项测试正常;一次在仓库根目录直接运行API Jest未加载api/jest.config.cjs,随后在api目录按项目配置重跑通过。
  • 本步骤未连接预生产、未修改数据库、未发送/补发/重投短信,也未修改真实通道、余额或客户连接。代码保持未提交、未推送、未部署。

2026-08-09 运营端新建企业省市字典修正(本地未提交)

  • 确认根因为AdminCustomerFormPage前端写死仅12个省级地区,且每省只列出1至3个地市,与平台真实数据库不一致。该静态省市数组已移除。
  • 新增真实字典接口GET /api/admin/dictionaries/administrative-regions,从PostgreSQL PhoneSegment.province/city执行去重查询,服务层过滤空白值、合并重复地市并按中文排序。本轮不新建静态地区表、不使用Mock或localStorage。
  • 新建/编辑企业页加载上述接口并做真实省—地市级联,切换省份时清空原地市;字典加载失败显式报错。编辑历史档案时会将当前原值补入选项,避免因号段库格式差异静默丢值。
  • 字典服务专项测试16/16通过,覆盖真实查询参数、去重、空值过滤和中文排序;API正式构建TypeScript与前端TypeScript通过。
  • 本步骤未新增migration,未修改PhoneSegment数据或任何企业档案,未连接预生产、发送短信、修改通道、余额或客户连接。代码保持未提交、未推送、未部署。
  • 本轮最终组合复核:报表与字典专项共2 suites / 23 tests通过,API正式构建TypeScript、前端TypeScript和Vite v8.1.5生产构建通过(2535个模块);仅保留既有约2.03MB单chunk告警。

2026-08-09 通道组逻辑删除与真实风险统计(本地验证完成)

  • 新增GET /api/admin/channel-groups/:id/deletion-impact,从真实数据库按不同企业应用统计正常/已删除关联,并返回组内通道数及submitStatus = queued的等待供应商提交记录数;不使用静态数据、Mock或localStorage。
  • 删除弹窗改为“删除通道组:{名称}”,依次展示“关联正常企业应用、关联已删除企业应用、组内通道、等待供应商提交结果”,并使用约定的历史保留说明;不再要求输入名称或删除原因,业务关联数量不禁用确认删除。
  • 删除接口不再因企业应用关联阻止,也不再物理删除通道组或组内通道;仅将通道组状态置为deleted并记录删除前快照、实时影响统计和逻辑删除方式。默认列表排除已删除组,新短信继续只选择活动通道组,历史配置、发送、回执、上行匹配和审计链路保留。
  • 通道专项channels.service.spec.ts 1 suite / 43 tests通过;API与前端TypeScript --noEmit --incremental false通过;Vite v8.1.5生产构建通过(2535 modules,仅保留既有约2.03MB单chunk提示);Gateway全量go test ./... -count=1go vet ./...通过;Prisma schema validate及client generate通过;全部结构契约门禁通过。
  • API全量运行共33 suites / 429 tests,其中32 suites / 424 tests通过;仅send-chain.service.spec.ts的5项因本机Redis 127.0.0.1:6379未运行产生连接拒绝并超时,与此前环境阻塞一致,不是业务断言失败。本轮未为通过测试而伪造Redis或修改发送链逻辑。
  • 本地验证未发送、补发或重投真实短信,未修改真实通道账号、密码、启停状态、企业余额或客户连接。预生产发布结果将在安全备份、migration和部署后只读检查完成后补记。

2026-08-09 工作区合并与预生产发布记录(4724b9db

  • 工作区65个有效源码、migration、测试、契约和文档文件统一提交为4724b9db6a99bec15350e37978d3fb165ee74bb9并推送origin/main;本地与远端提交一致。构建缓存api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=未提交、未删除。
  • 精确Git归档outputs/cmpp-4724b9db-20260809-150404.tar.gz包含808个条目、2148867字节,本地与服务器SHA-256均为e5b413f10fa54a5bd7b9cc368ae2908d06e53122d5d3e65cb205ce5c74955985,服务器tar完整性检查通过。
  • 发布前备份目录为/opt/cmpp-platform-backups/releases/20260809-150404-before-4724b9db。PostgreSQL备份postgresql.sql.gz为16606417字节、SHA-256=0e2dbb91345f266586a349006357477214bbc2daa7125996abe99df44f869aa6;运行源码runtime-source.tar.gz为2096964字节、SHA-256=a65591656e4c8e102aaacdf1afa061c4645597d22dc80575a19fb25b64781f2f;环境文件为895字节、SHA-256=7a26d83b062f9d7e9503e2a987f39a899510f8981be63be997bccfc988fbbc60。三项备份均为0600并通过gzip/tar及sha256sum -c,上一运行目录保留为/opt/cmpp-platform.previous-20260809-150404
  • 标准tools/deploy/production-deploy.sh成功完成依赖安装、安全缓解门禁、Prisma generate/migrate、前端/API/Gateway构建、Nginx配置校验及Gateway先于API重启。新增20260809130000_add_protocol_log_plain_phone成功应用,预生产共83条已完成migrationProtocolInteractionLog.phoneNumber字段存在;最终.deployed-commit=4724b9db6a99bec15350e37978d3fb165ee74bb9
  • 部署后API、Gateway、Nginx、PostgreSQL、MinIO均activeRedis PONG,内部API/Gateway/MinIO健康通过,无failed systemd unit。公网运营登录、客户端登录、API health和客户Swagger/api/client-docs均为200;API专用域名根路径、管理页面和管理API均为404,公网CMPP 17890纯TCP连通。Redis Stream消费者1、pending=0lag=017个通道TPS配置键存在。
  • 新通道组删除影响接口已出现在部署后Swagger路径中,未认证访问返回401;前端生产包包含“等待供应商提交结果”和历史数据保留完整文案。对真实PostgreSQL最近三个活动通道组只读执行同口径统计,均得到正常应用2、已删除应用0、组内通道3、等待供应商提交0;没有点击或调用确认删除。现有浏览器无登录会话,未绕过验证码或伪造登录态,登录后UI弹窗交互仍可作为后续人工验收项。
  • 发布前数据库状态为9条active通道、连接状态9条connected;重启后6条active通道恢复connected 1/13条富泷通道返回供应商authentication / connect response status: auth failed。本轮未修改这些通道的账号、密码或启停状态,仅保留真实失败状态并报告。部署后API/Gateway error级journal均为0。
  • npm审计报告根项目3项high、API项目3项moderate和4项high;专用安全门禁确认PostCSS补丁、React Router RSC未使用和brace expansion边界有效,未执行可能破坏兼容性的自动升级。本次没有发送、补发或重投真实短信,没有修改企业余额、客户连接或任何真实通道配置。

2026-08-09 通道、签名与模板级联删除确认(已提交、已部署)

  • 通道组删除弹窗不再展示“关联已删除企业应用”,继续展示关联正常企业应用、组内通道和等待供应商提交结果;后端已有真实影响统计及删除审计快照保持不变。
  • 通道、签名和模板删除原因统一改为选填。签名存在关联模板、引流信息或未结束报备任务时分别出现“同时删除关联的模板”“同时删除引流信息”“同时结束关联的报备任务”;通道存在未结束报备任务时出现结束报备勾选项。发现的级联项必须全部勾选后页面才允许确认,后端也独立复核所有布尔选项,不能绕过前端直接删除。
  • 客户端允许同步结束签名关联的未结束报备任务,但客户端专用预检不返回任务ID、状态或通道详情,页面只展示统一处理说明。运营端仍可查看真实任务ID和状态。
  • 所有级联动作与主对象逻辑删除在同一个Serializable事务完成;关联模板和引流信息逻辑删除,过程态报备任务置为abandoned并逐条写ChannelSignatureReportRecord,子对象另写操作日志。通道删除后,同事务按剩余未删除通道重算受影响签名报备汇总;活动通道组、直接路由、活动连接及关联模板的活动发送任务仍保持硬阻断。
  • 修正模板活动任务终态口径:SmsSendTaskapproved/rejectedSmsBatchTaskfinished/canceled/rejected/failed/completed/cancelled不再被误判为未结束任务;真实过程态任务继续阻止模板或签名级联删除。无需新增数据库字段或migration。
  • 使用Node.js v24运行删除治理定向1 suite / 11 tests全部通过;排除此前已确认依赖本机Redis的send-chain.service.spec.ts后,API其余32 suites / 324 tests全部通过。API TypeScript build、前端TypeScript--noEmit --incremental false、Vite v8.1.5生产构建(2535 modules,仅既有约2.04MB单chunk提示)和git diff --check均通过。
  • 开发与本地验证阶段未连接或修改预生产数据库,未执行任何真实通道、签名、模板、引流信息或报备任务删除,未发送、补发或重投真实短信,未修改真实通道、企业余额或客户连接;最终提交、推送和预生产发布证据见下方发布记录。既有api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=继续保护,不归因、不删除、不提交。

2026-08-09 级联删除治理预生产发布记录(7804f64c

  • 级联删除治理9个有效源码、测试和文档文件提交为7804f64ced19435b15b981d2fcb7f8c7e934e33f并推送origin/main;首次推送因远端认证失败,使用既有Git凭据助手安全重试后成功。构建缓存api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=未提交、未删除。
  • 精确Git归档outputs/cmpp-7804f64c-20260809-191015.tar.gz包含808个条目、2157663字节,本地与服务器SHA-256均为97faa7900db7b06199bc99c576d2eec99c4a75d474c6d488db0681f07f63d2a0,服务器tar完整性检查通过。
  • 部署前恢复资产位于/opt/cmpp-platform-backups/releases/20260809-191015-before-7804f64c。PostgreSQL备份postgresql.sql.gz为16714530字节、SHA-256=6558ce693de1f4ae88d33df9a3a7a0e1bc51d460c2f3fe634c8f352841355328;运行源码runtime-source.tar.gz为2176250字节、SHA-256=c580c731bc90778182bb915f96c1ca0ab829f707dc044aefb428fee3df9f85af;环境文件为895字节、SHA-256=7a26d83b062f9d7e9503e2a987f39a899510f8981be63be997bccfc988fbbc60。备份目录为0700,备份文件为0600gzip、tar和SHA-256校验均通过;上一运行目录保留为/opt/cmpp-platform.previous-20260809-191015
  • 标准tools/deploy/production-deploy.sh成功完成依赖安装、安全缓解门禁、Prisma generate/migrate、前端/API/Gateway构建、Nginx配置校验以及Gateway先于API重启。预生产仍为83条已完成migration且无待执行项,最终.deployed-commit=7804f64ced19435b15b981d2fcb7f8c7e934e33f
  • 部署后API、Gateway、Nginx、PostgreSQL、MinIO均activeRedis PONG,内部API/Gateway/MinIO健康、PostgreSQL readiness均通过,无failed systemd unit。Redis Stream消费者1、pending=0lag=0API和Gateway发布后10分钟error级journal均为0,运行源码包含级联选项、客户端详情隔离、报备任务deletion_governance轨迹和删除原因选填实现。
  • 从预生产服务器公网复核:运营登录、客户端登录、API health和客户Swagger均为HTTP 200;API独立域名根路径及管理删除预检均为404;主站未认证运营端和客户端删除预检均为401。公网CMPP 17890纯TCP连接成功。本机执行公网检查时因本机DNS无法解析两个域名返回000,已由服务器侧公网检查闭环,不将本机DNS故障误记为平台故障。
  • 9条active供应商通道发布重启后6条为connected 1/1;“会员营销-富泷”“移动物业-富泷”“联电物业-富泷”3条仍为authentication / connect response status: auth failed。本轮未修改通道账号、密码、启停状态或连接参数,只保留并报告供应商真实返回。
  • 本次只部署代码和文档,未执行任何真实通道、签名、模板、引流信息或报备任务删除,未发送、补发或重投真实短信,未修改企业余额、客户连接或通道配置。部署依赖审计仍报告根项目3项high、API项目3项moderate和4项high,专用安全缓解门禁通过,未执行可能破坏兼容性的自动升级。

2026-08-09 模板删除与既有短信任务解耦(本地未提交)

  • 纠正“模板删除必须等待关联短信任务结束”的错误耦合。单独删除模板时,预检和事务内复核都不再查询或阻断SmsSendTask/SmsBatchTask;模板仅逻辑删除,已创建任务、消息、计费、审核快照及历史templateId关联保持不变。
  • 已删除模板仍不能用于新建发送任务。已接受的定时任务到点时改为使用持久化内容快照继续处理,不因模板当前deleted状态失败;仍重新校验企业、应用、模板归属和签名当前状态。签名删除的级联安全阻断本轮未改。
  • 删除治理定向1 suite / 11 tests通过;发送链3个新增边界用例通过,覆盖已删模板禁止新任务、已有定时任务按快照继续、签名失效仍阻断。排除依赖本机Redis的send-chain.service.spec.ts后,API其余32 suites / 324 tests全部通过;API正式构建TypeScript检查和git diff --check通过。
  • 完整发送链套件仍因本机Redis 127.0.0.1:6379 未运行出现5个既有连接拒绝超时,与上次记录的环境阻塞一致;本轮新增3个发送链用例已单独精确运行并通过,未为通过测试伪造Redis或改动队列配置。
  • 本轮未连接预生产、未修改数据库,未执行任何真实模板/签名/任务操作,未发送、补发或重投短信,也未修改通道、余额或客户连接。代码和文档保持未提交、未推送、未部署。

2026-08-09 通道支持运营商多选需求评估(暂缓,未实施)

  • 新需求拟将通道本体从“移动、联通、电信、三网”单选改为“移动、联通、电信”三个运营商复选,三个全选等价于现行三网,并允许两个运营商组合。用户已明确本需求暂时不实施,本步骤只同步需求和规划用例,没有修改代码、Prisma schema、migration、API、页面或生产数据。
  • 已确认多运营商通道继续共用同一个通道单价,不设计分运营商价格。完整报备的理想模型为“签名 × 通道 × 运营商”,但本期暂不考虑该扩展;未来重新启动需求时必须先重新确认报备粒度,不能把当前“签名 × 通道”状态无依据复制到各运营商。
  • 2026-08-09预生产只读盘点共18条通道:8条all/active、1条all/disabled、1条mobile/active,另有6条mobile/deleted、1条unicom/deleted和1条telecom/deleted,没有NULL或非法旧值;另有28条通道组成员、54条活动路由规则、69条签名报备任务、148条报备历史记录和6907条提交记录需要在未来迁移与回归时保护。
  • 未来数据迁移固定按旧值语义保守映射:单运营商转单元素集合,all转移动/联通/电信全选,已删除通道同样迁移;不得从通道名称、当前通道组关联或近期发送量自动推断并缩减能力。取消仍被对应运营商活动通道组引用的能力时必须由真实后端阻止,禁止自动删除关联或历史。
  • 未来实施属于跨数据库、通道管理、通道组校验、发送选路、签名/引流报备、批次生成、筛选、复制、审计和文档的高风险改造,必须采用“兼容字段与回填底座→开放多选写入”的分阶段发布。生产出现双运营商组合后,回滚下限必须是已支持新集合的兼容版本,不能回滚到只识别旧carrier单值的版本。
  • 规划验收用例已记录为TC-CHANNEL-CARRIER-MULTI-001007,当前均为“暂缓、未执行”,不计入现版本通过率,也不得作为现有系统Bug;本步骤未连接或修改预生产数据库,未修改通道账号、密码、启停状态、企业余额或客户连接,未发送、补发或重投真实短信。

2026-08-09 通道组按通道筛选(本地未提交)

  • 运营端“短信通道组管理”新增“通道”可搜索下拉筛选。页面首次加载并行请求真实GET /api/admin/channel-groupsGET /api/admin/channels,下拉显示全部真实通道的名称和编码;已删除通道显式标记,未加入任何组的通道也保留可选,未新增静态列表、Mock或localStorage。
  • 选定通道后按成员的精确channelId筛选通道组,与通道组名称条件取交集;筛选结果的总数和分页同步重算,条件变更后回到第一页。“重置”同时清空名称和通道条件。
  • 按React性能口径将通道选项和筛选结果都作为groups与查询状态的派生值计算,不使用effect复制派生状态,避免额外请求、重复渲染和状态偏移。
  • 前端TypeScript --noEmit --incremental false通过;Vite v8.1.5生产构建通过(2535 modules),仅保留既有约2.04MB单chunk告警;git diff --check通过。本地预览能正常加载运营端应用和登录页,但本地API未运行,请求返回502且无已登录会话,因此未伪造登录或Mock通道数据进行页面交互验收。
  • 本轮未连接预生产、未修改数据库或真实通道/通道组,未发送、补发或重投短信,也未修改余额或客户连接。代码和文档保持未提交、未推送、未部署。

2026-08-09 模板任务解耦与通道组筛选预生产发布记录(78b839f4

  • 模板删除与既有任务解耦、定时任务快照继续处理、通道组按通道可搜索筛选,以及已完成但暂缓实施的“通道运营商多选评估”文档记录,共11个有效源码、测试和文档文件提交为78b839f468f053ea3a1299e56418077b0dc11c99并推送origin/main。首次推送复现HTTP远端认证失败,未改动或输出凭据,使用既有凭据助手直接安全重试后成功。api/tsconfig.build.tsbuildinfo、根目录tsconfig.tsbuildinfooutputs/和空文件=未提交、未删除。
  • 发布前删除治理1 suite / 11 tests、发送链新增3个边界用例、排除本机Redis环境阻塞的API其余32 suites / 324 tests全部通过;API与前端TypeScript、Vite v8.1.5生产构建(2535 modules)和git diff --check通过,仅保留既有约2.04MB单chunk告警。
  • 精确Git归档outputs/cmpp-78b839f4-20260809-205832.tar.gz包含808个条目、2164322字节,本地与服务器SHA-256均为4024ed65beb6f950a609a90bee4d7bbf4c47ad7850b8e32fc1631fc34cbf1fd5,服务器tar完整性通过。
  • 部署前恢复资产位于/opt/cmpp-platform-backups/releases/20260809-205832-before-78b839f4。PostgreSQL备份postgresql.sql.gz为16756199字节、SHA-256=389f98e7901e9d03e72908000182da40defbdf3cfc4676ad038ad6c30f6f4c6e;运行源码runtime-source.tar.gz为2183000字节、SHA-256=216b0db65de6a46135272af87cdebd8a5613e3e886ba9046d6a5e2fd56027395;环境文件为895字节、SHA-256=7a26d83b062f9d7e9503e2a987f39a899510f8981be63be997bccfc988fbbc60。目录为0700,备份和校验单为0600,gzip、tar与sha256sum -c全部通过。首次pg_dump因Prisma连接串含schema=public专用参数而在运行目录切换前停止;移除该Prisma参数后在同一精确目录覆盖生成并完整校验,期间未发生迁移或服务重启。
  • 使用标准tools/deploy/production-deploy.sh成功完成依赖安装、安全缓解门禁、Prisma generate/migrate、前端/API/Gateway构建、Nginx校验及Gateway先于API重启。预生产仍为83条已完成migration且schema up to date,最终.deployed-commit=78b839f468f053ea3a1299e56418077b0dc11c99;上一完整运行目录保留为/opt/cmpp-platform.previous-20260809-205832,切换命令配置了部署失败自动恢复保护。
  • 部署后API、Gateway、Nginx、PostgreSQL、MinIO均为activeRedis PONG,内部API/Gateway/MinIO健康通过,无failed systemd unitRedis Stream消费者1、pending=0lag=0。API和Gateway发布后均无error级journal。
  • 从预生产服务器公网复核:运营登录、客户登录、API health和客户Swagger均为HTTP 200;API独立域名根路径、管理页面和管理通道组接口均为404,主站未认证通道组接口为401。生产前端包已包含“输入通道名称或编码搜索”,运行API源码已包含模板任务快照继续处理逻辑。
  • 9条active供应商通道发布重启后6条为connected 1/1;“会员营销-富泷”“移动物业-富泷”“联电物业-富泷”3条仍返回connect response status: auth failed。本轮未修改其账号、密码、启停状态或连接参数,只保留并报告供应商真实返回。
  • 发布依赖审计仍报告根项目3项high、API项目3项moderate和4项high;专用安全缓解门禁通过,未执行可能破坏兼容性的自动升级。本次没有执行任何真实模板、签名、通道或通道组删除,未发送、补发或重投短信,未修改企业余额、客户连接或供应商通道配置。

2026-08-09 签名发送质量多周期趋势完整回滚

  • 按用户明确要求撤回35de17a2d44702d3ec3e839362a37d6f2bf26c89及其部署记录e0c8f82bcfc21d4707c0ec168d19808959fcfd46。预生产运行目录已精确切回上一版本78b839f468f053ea3a1299e56418077b0dc11c99;被撤回版本完整保留于/opt/cmpp-platform.rolled-back-35de17a2-20260809-rollback,没有删除恢复资产。
  • 本次发布未新增migration,预生产仍为83条已完成migration,因此没有恢复数据库备份,避免覆盖发布后正常产生的短信、回执和业务数据。回滚前Redis Stream消费者1、pending=0lag=0;运行目录切换仅停止并按Gateway、API、Nginx顺序重启服务。
  • 回滚后API、Gateway、Nginx、PostgreSQL和MinIO均为activeRedis PONG,内部API/Gateway健康通过;公网运营登录、客户端登录及API health均为HTTP 200,发布后API/Gateway无error级journalRedis Stream继续为pending=0lag=0
  • 9条active供应商通道回滚重启后6条为connected;“会员营销-富泷”“移动物业-富泷”“联电物业-富泷”3条恢复为此前已记录的供应商connect response status: auth failed状态。本次未修改其连接配置,仅记录真实返回。
  • Git使用git revert --no-commit反向撤销上述两个提交,不使用resetcheckout覆盖工作区。恢复后的业务源码、需求文档、测试用例和结构契约与608662a(即78b839f4功能版本加其部署记录)一致,仅追加本回滚记录。
  • 回滚后运营统计专项1 suite / 28 tests通过,API正式TypeScript构建、前端TypeScript和Vite v8.1.5生产构建通过(2535 modules,仅既有约2.04MB单chunk提示),依赖安全缓解门禁及git diff --check通过。operations-r2字节哈希门禁在完全恢复上一版本内容后仍受该文件历史混合CRLF/LF行尾影响而误报,Git归一化内容与608662a无差异;未为通过门禁改写上一版结构契约哈希。
  • 回滚没有发送、补发或重投真实短信,没有修改数据库记录、企业余额、通道账号、密码、启停状态或客户连接;受保护的构建缓存、outputs/和空文件=继续不提交、不删除。

2026-08-10 签名清退预警与运营商级报备设计(待评审、未实施)

  • 已完整阅读用户提供的C:\Users\hectorzhao\Downloads\签名清退预警.md,并结合当前真实代码模型和预生产只读聚合重新评估。当前ChannelSignatureReportTask事实粒度为“签名 × 通道”,任务和记录均没有运营商字段;现有69条报备任务涉及28个签名、13个通道,38条当前通过任务都能找到通过轨迹,但不能据此自动拆成三网分别通过。
  • 新增评审稿docs/signature-retirement-alert-design.md,将完整实施拆为16步,固定先完成设计、需求和规划用例,再经用户评审后进入兼容数据底座。后续必须依次经过通道能力回填、运营商级签名任务、历史人工确认、发送链兼容双读、严格门禁、预警规则、检测快照、抑制/Webhook、页面改版和分阶段发布;不得在一次发布中同时迁移、切换发送和启用预警。
  • 原“通道运营商多选”暂缓需求重新纳入清退预警前置设计,但当前仍为“方案评审中、未实施”。通道目标能力为移动、联通、电信多选且共用一个单价;签名报备计划升级为“签名 × 通道 × 运营商”,继续复用ChannelSignatureReportTask/Record,不另建重复事实表。本需求明确不改造引流信息报备,reportType/drainageItemId不属于本需求业务维度。
  • 历史all通道只迁移为三网能力集合,旧报备任务保留为legacy_channel范围并显示“历史通道级通过(运营商未拆分)”;必须由运营人员依据供应商真实结果人工拆分确认,系统不得自动复制为三条运营商通过。严格运营商级发送门禁只能在活动历史未拆分数和兼容资格命中数清零后启用。
  • 已确认清退活跃量口径:企业按上游至少接受一次的业务短信去重,通道按messageRecordId + channelId去重;同一通道断连、超时或重试只计一个活跃量,切换到其他通道后各通道分别计一次。提交尝试、上游接受和最终送达分开展示,不把SubmitResp status=0称为最终送达成功。
  • 已确认规则下一检测日生效,恢复后再次低量形成新预警周期;临时抑制天数可配置,永久抑制从“抑制管理”取消且不补发历史通知;右上角只展示今日未读且未抑制数;颜色复用现有六档色阶;签名质量检测页面删除企业应用排行、通道占比、当天发送量和当天成功率。
  • docs/system-functional-test-cases.md已将原7条运营商多选用例调整为“规划、未执行”,并新增TC-SIGNATURE-CARRIER-REPORT-001010TC-SIGNATURE-RETIREMENT-001016。这些用例当前不计入现版本通过率,也不得被解释为代码已完成或当前系统Bug。
  • 本步骤只修改设计、需求、规划测试用例和测试进度文档;未修改源码、Prisma schema或migration,未连接或修改预生产数据,未发送、补发或重投真实短信,未修改通道账号、密码、启停状态、企业余额或客户连接。文件保持未提交、未推送、未部署,等待用户先行评审。

2026-08-10 签名清退预警与运营商级报备本地实现(未提交、未发布)

  • 用户确认设计后已按16步顺序完成本地最小充分实现:通道运营商多选、通道组及选路能力校验、运营商级签名报备、历史通道级任务人工拆分确认、兼容双读发送资格、清退规则/周期/检测快照、临时与永久抑制、已读消息、Webhook安全投递、顶部独立预警入口和两类30日热力图。引流信息报备保持原维度,未纳入本需求。
  • 修改继续复用ChannelSignatureReportTask/Record作为报备事实与轨迹;历史任务保持legacy_channel,不得自动伪造三网通过。严格运营商级门禁由SIGNATURE_REPORT_STRICT_CARRIER=true显式启用,当前默认关闭,后续必须等活动历史未拆分数和兼容资格命中数清零再分阶段切换。
  • 本地PostgreSQL迁移前已备份到C:\cmpp-platform-local\backups\cmpp-platform-before-signature-retirement-20260810-165721.dump(435753字节)。本地已完成84条migration;5条通道中3条历史空运营商按旧系统实际兼容口径回填为mobile,迁移后空集合0条、非法集合0条,并增加非空且只允许移动/联通/电信的数据库约束。历史报备任务1条,运营商级任务0条,未自动拆分;检测和开放周期唯一索引已核对。
  • 本地真实PostgreSQL上的清退统计SQL执行成功,返回提交尝试0、上游接受业务短信0、最终送达业务短信0,证明查询可由真实表执行;最终送达按真实分片审计和回执表归属目标通道,不把其他通道补发成功记到原通道,也不把SubmitResp status=0当作最终送达。
  • API全量测试35个suite/444项通过;真实Redis启动后发送链112/112通过;通道与清退专项、报备/发送配置/删除治理及发送链相关专项均通过。Prisma schema校验及84条迁移状态、API TypeScript构建、前端Vite生产构建、4份Gateway队列结构契约、Gateway全量Go测试和git diff --check通过;前端仅保留既有约2.05MB单chunk提示,差异检查仅输出既有LF/CRLF提示。
  • 本地PostgreSQL 5432、Redis 6379、API 3000和前端4173已启动供验收。API启动时尝试恢复本地活动通道,因未启动Gateway而记录连接失败;未修改任何生产配置,也未发送、补发或重投真实短信。经用户授权重置既有本地专用codex_local_admin临时密码、读取真实算术验证码并登录,未新建重复账号。
  • 全部代码、migration和文档均保持未提交、未推送、未部署;受保护的api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/和空文件=不删除、不提交、不归因于本需求。
  • 登录后浏览器验收发现并修复历史三网任务弹窗默认把移动、联通、电信全部设为“已通过”的问题。修复后所有运营商默认“请选择”,必须逐项确认,且“已通过”必须填写真实有效通过时间;前端禁用不完整提交,后端不再回退使用历史通道级时间或当前时间伪造运营商通过事实。同步新增TC-SIGNATURE-CARRIER-REPORT-006A
  • 修复后重新完成API专项3项、API TypeScript和前端生产构建,并精确重启本轮API/前端进程。浏览器复验历史拆分三项均为“请选择”且确认按钮禁用;通道编辑展示移动/联通/电信三个复选框,三项清空后显示“至少选择一个运营商”且未写入;报备明细显示“历史通道级(未拆分)”;清退预警5个页签、规则/Webhook弹窗、今日检测、顶部独立0条计数和两类30日热力图均正常,已确认删除的四个统计模块未出现,控制台日志为0。没有保存规则、Webhook或历史拆分,没有发送短信。

2026-08-10 签名清退自动调度与本地验收数据(未提交、未发布)

  • 用户确认改为每天北京时间04:00自动检测、08:00发消息。检测阶段现只推进周期、写幂等快照并冻结规则版本、预警标题和正文;08:00通知阶段才创建站内消息、聚合Webhook并立即触发投递。服务晚启动时按04:00、08:00两个时点顺序补偿,两个阶段均依赖数据库唯一键防重。运营页面“执行今日检测”按钮和POST /api/admin/signature-retirement/detect管理接口已删除,内部runDetection仅供调度和测试。
  • 本地真实造数新增2家验收企业、2个应用、3条停用验收通道(华东三网、移动联通、电信专线)、4个审核通过签名、6条运营商级报备通过任务和42条历史消息记录,覆盖稳定活跃、低量、零量及跨通道失败后补发四类场景。数据脚本为tools/local/seed-signature-retirement.mjs,使用固定qa-retirement-*标识,重跑前只清理自身数据,不进入发送队列、不连接真实通道。
  • 真实造数首次暴露旧ChannelSignatureReportTask_target_key仍按“签名×通道”唯一、会阻止同通道多运营商事实。migration现明确删除旧索引,并分别建立运营商级签名、历史通道级签名和引流任务三个条件唯一索引;本地数据库已同步调整,成功保存同一签名/通道的移动和联通两条任务。
  • 使用正式SignatureRetirementService按时间顺序回放T-30至T共31个检测日,生成341条真实检测快照;今天11个维度中9个预警、2个正常,08:00通知阶段幂等生成9条未读站内消息。浏览器真实API显示右上角9条、今日预警9条,列表包含4/8/0等活动量;企业和通道热力图均展示07-11至08-09共30列的真实渐进数据,页面文案明确“04:00自动检测,08:00生成站内消息并发送Webhook”,手动按钮已消失。
  • 分阶段真实数据库复核先删除今天9条验收消息,再重复运行04:00检测,消息数保持0;随后运行08:00通知阶段才恢复9条。最终API全量35个suite/444项、Prisma validate及84条migration状态、前后端生产构建和git diff --check通过;三个新条件唯一索引均存在、旧ChannelSignatureReportTask_target_key已不存在,同一签名/通道的移动与联通任务可同时保存。造数后浏览器控制台日志为0。

2026-08-10 签名质量检测模块顺序与热力图分页(未提交、未发布)

  • 按验收反馈将“签名通道发送质量”调整到页面最上方,企业、通道两张30日热力图依次下移;统计接口和真实数据口径不变。
  • 两张热力图分别增加独立的维度行分页,每页10行;各自页码互不影响,30日日期列继续保留表格内横向滚动。同步新增TC-SIGNATURE-RETIREMENT-018
  • 使用Node.js 24.14.0完成前端TypeScript与Vite 8.1.5生产构建(2538 modules,仅既有大chunk提示),git diff --check通过且只有既有行尾提示。精确重启本轮本地Vite预览后,以已登录运营账号和真实本地API验收:页面模块顺序为发送质量、企业热力图、通道热力图;两张热力图各自显示一套上一页/下一页和页码输入控件,当前真实造数分别为5、6个维度,均为第1/1页,控制台日志为0。

2026-08-10 热力图交互优化与未报备签名(未提交、未发布)

  • 企业、通道热力图日期列已调整为从左到右T-1T-30;行首只常驻签名、运营商及通道维度必要的通道名称,企业和企业应用改为签名悬停文案。两张热力图分别增加企业、企业应用、签名即时搜索,筛选后各自回到第一页且互不影响;格子悬停明确展示提交、上游接受、发送成功、成功率和阈值。
  • 新增真实后端GET /api/admin/signature-retirement/unreported-signatures,按所选北京时间自然日和SmsMessageRecord统计。短信实际运营商在任一未删除通道存在当前运营商级通过事实,或仍存在历史通道级通过事实时不计入;其余按签名×消息实际企业应用聚合,后端完成关键字、总数和分页。
  • 本地自清理造数扩展为2家企业、2个应用、3条停用通道、6个签名、7条运营商级报备通过任务和52条消息,新增“完全未报备”和“仅移动报备但提交电信”两类场景;未进入发送队列且未连接真实通道。正式服务回放31个检测日后生成403条检测快照,今天13个维度中11个预警、2个正常,重复通知阶段新增0条,幂等保持。
  • 真实PostgreSQL聚合返回“完全未报备”6条、“仅移动已报备但提交电信”4条;浏览器按企业B搜索后只显示后者4条。企业热力图按企业B搜索只保留3个相关维度,通道热力图仍保留全部7个维度;签名悬停属性显示真实企业和应用,格子悬停属性显示五项明确口径,日期首列为08-09、末列为07-11,控制台error/warn为0。
  • 清退专项7/7、API全量35个suite/446项通过,API与前端TypeScript、API正式构建、Vite 8.1.5生产构建通过(2538 modules,仅既有大chunk提示)。API全量用例本身12.573秒完成,但既有异步句柄使Jest不自行退出,本次使用--forceExit收尾并保留该提示;两次外层超时遗留的本轮Jest进程已按精确命令行确认后停止,未影响API、前端、PostgreSQL或Redis。

2026-08-12 未报备签名判定修正(未提交、未发布)

  • 生产只读核查确认【彩生活物业】2026-08-12北京时间自然日有4个号码级SmsMessageRecord,4条均为2个计费分片;2026-08-11另有2个号码级消息。因此页面当日显示4条正确,用户所见6条为相邻两日累计,不修改签名质量统计代码,也不增加额外列表说明。
  • “未报备签名”按确认口径改为系统签名库缺失:从signatureId IS NULL消息正文开头提取规范【签名】,仅在同企业应用不存在未删除同名SmsSignature时计入;不再用通道、运营商或报备任务通过状态判定。结果仍按正文签名和实际企业应用聚合、搜索和分页。
  • 使用生产数据只读回放新聚合SQL,【湘银物业】在2026-08-12正确返回266条,企业为“王斯评与聆界中转企业”、应用为“王斯评平台To百信互动物业”;全过程未写生产数据库、未发送或重投短信。
  • 签名清退专项9/9、API与前端TypeScript、API正式构建、Vite 8.1.5生产构建及git diff --check通过;Vite仅保留既有约2.08MB单chunk提示。代码按要求未提交、未推送、未部署。

2026-08-10 预警消息检索分页、抑制弹窗与备注列宽(未提交、未发布)

  • “今日预警”已调整为“预警消息”,后端按预警日期、企业、企业应用、签名和通道执行真实PostgreSQL筛选及分页;页面默认选中北京时间今日,仅查询今日,支持历史日期区间并固定每页10条。本地回放最近5个检测日后,今日共11条:浏览器验收第1页10条、第2页1条;选择近7天并按“跨通道”签名查询返回15条、2页,可见2026/8/9 08:00:00历史消息及真实企业应用名称。
  • 抑制操作已改为自研弹窗,在同一弹窗内选择临时抑制截止日期或永久抑制并填写必填原因;切换永久抑制后截止日期隐藏。取消抑制也使用自研弹窗并要求填写取消原因。浏览器只验证弹窗打开、模式切换和未填原因时确认按钮禁用,没有确认保存或取消任何抑制。
  • 报备记录“备注”列统一使用长文本列规范,桌面端设置为320px并允许表格内部横向滚动;docs/ui-design-guidelines.md新增全局约束:长文本列最小240px、建议280–360px并使用.ui-table__long-text。浏览器读取“备注”表头计算宽度及最小宽度均为320px。
  • 清退专项9/9、API全量35个suite/448项通过;API与前端TypeScript、API正式构建、Vite 8.1.5生产构建通过(2538 modules,仅既有约2.06MB单chunk提示),git diff --check通过且仅输出既有LF/CRLF提示。真实查询回放脚本重复执行新增0条,证明QA消息生成幂等;未发送短信、Webhook,未保存抑制,未修改生产或预生产数据。
  • 本轮代码、测试和文档继续保持未提交、未推送、未部署;受保护的api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/和空文件=不删除、不提交、不归因于本需求。

2026-08-10 签名清退预警预生产发布与慢启动兼容(已发布)

  • 签名清退功能提交55aa054005d07eef04891ce6ee0700ae629aee3f已推送后,首次预生产发布成功完成备份、依赖门禁、Prisma generate、84条migration应用和前后端/Gateway构建;服务重启后的API单次健康检查在固定3秒窗口内尚未监听3000端口,发布包装器按设计恢复上一运行目录。恢复后API、Gateway、Nginx、PostgreSQL、Redis和MinIO均为activeAPI health为200API journal没有启动异常,确认属于健康检查与正常慢启动竞态,不是代码构建或migration失败。
  • 权威tools/deploy/production-deploy.sh将API和Gateway检查改为最多60秒逐秒重试。为什么:Nest初始化和活动通道恢复耗时随生产数据量波动,固定等待会把正常慢启动误判为发布失败;超过60秒仍不可用才应终止并进入日志诊断和恢复流程。
  • 首次发布前恢复资产完整保留在/opt/cmpp-platform-backups/releases/20260810-205625-before-55aa0540;PostgreSQL、运行源码和环境文件均已通过格式、非空和SHA-256检查。20260810143000_add_signature_retirement_alerts已成功且仅应用一次,数据库当前84条已完成migration;重新发布依赖Prisma幂等状态,不重复伪造或手工标记migration。
  • 同步更新部署手册和TC-DEPLOY-HEALTH-001。本步骤没有发送、补发或重投短信,没有创建外部Webhook,没有修改通道账号、密码、启停状态、企业余额或客户连接。
  • 慢启动修复提交0eb27e4ac0473732a243b9461b704cb8874d3a27已推送并作为最终运行版本。精确Git归档outputs/cmpp-0eb27e4a-20260810-210142.tar.gz包含824项、2217777字节,本地和服务器SHA-256均为c33c783e4a1ace47c4c80d121277becc19b062d9a308810bb5102b2b668ccfcc。第二次标准部署显示无待执行migration,构建完成后API和Gateway在60秒窗口内通过健康检查并输出DEPLOY_OK;运行目录.deployed-commit已核对为0eb27e4a
  • 两套恢复资产均保留且权限收紧为目录0700、文件0600。迁移前备份/opt/cmpp-platform-backups/releases/20260810-205625-before-55aa0540中PostgreSQL为17548853字节、SHA-256=e2022d20946929639e5a6ba3de56883c3431d22d4c18db10a2a7a25d122ae450,运行源码为2188655字节、SHA-256=3c3f66fa16cefa1053fab4f27e8ae2a705ddd092cd19f9cbb2e4704e46cbb321;迁移后切换前备份/opt/cmpp-platform-backups/releases/20260810-210142-before-0eb27e4a中PostgreSQL为17554028字节、SHA-256=53221b396cff34d841d17ff6df39e533010504b533374df50f91a4c9423d563b。两套环境文件SHA-256均为7a26d83b062f9d7e9503e2a987f39a899510f8981be63be997bccfc988fbbc60;gzip、tar和校验单全部通过。上一运行目录保留为/opt/cmpp-platform.previous-20260810-210142,首次失败的新版本目录保留为/opt/cmpp-platform.failed-20260810-205625,未擅自删除。
  • 发布后源代码与数据库均为84条migration。18条通道回填结果为8条活动三网、1条停用三网、1条活动移动及8条已删除单网,运营商集合空值0、非法值0;69条既有报备任务全部保留为legacy_channel,没有自动复制为运营商通过。严格运营商门禁保持关闭,清退规则、Webhook、检测和消息均为0,因此启动补偿没有生成或外发预警。
  • API、Gateway、Nginx、PostgreSQL、Redis、MinIO均active,无failed systemd unit12026、17890、8090、3000、6379、5432和9000端口均监听。内部API/Gateway/MinIO健康通过,Redis PONGgateway.submit.commands消费者1、pending=0lag=0;公网运营登录、客户端登录、API health和客户Swagger为200,API专用域名根路径、管理页面和管理接口为404,主站未认证清退接口为401,公网CMPP 17890 TCP连通,发布后API/Gateway error级journal为0。
  • 9条活动通道恢复为6条connected 1/1;“会员营销-富泷”“移动物业-富泷”“联电物业-富泷”继续返回既有供应商authentication / connect response status: auth failed,本轮未修改账号、密码、启停状态或连接参数。依赖审计仍报告根项目3项high、API项目3项moderate和4项high,专用安全缓解门禁通过,未执行破坏性自动升级。
  • 最终发布没有发送、补发或重投真实短信,没有配置或投递Webhook,没有修改企业余额或客户连接。功能提交、慢启动修复和本发布记录均只包含有效源码、migration、测试和文档;api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/和空文件=继续不提交、不删除。

2026-08-10 删除历史待确认并自动转换历史签名任务(已发布)

  • 按最终业务口径删除签名清退预警页的“历史待确认”页签、数量、表格、人工确认弹窗、前端请求与类型,以及后端历史任务列表/确认DTO、Controller路由和Service逻辑;企业签名报备详情和状态弹窗同步移除“历史待确认”残留提示。
  • 新增第85条幂等migration 20260810214500_auto_split_legacy_signature_reports:旧legacy_channel签名任务按通道实际运营商集合补齐缺失的carrier_specific任务;旧状态为approved时三网通道的移动、联通、电信均记为已通过,approvedAt取migration执行时刻,其他状态原样转换且通过时间为空。已有运营商级事实不覆盖;全部适用运营商齐全后旧任务改为legacy_split并保留记录。
  • 企业签名页面新建运营商级“已通过”任务的现有逻辑保持不变:approvedAt取保存时刻。新增自动化用例明确验证新建任务写入Date,避免未来回归成空值或历史任务时间。
  • migration前已备份本地真实PostgreSQL到C:\cmpp-platform-local\backups\cmpp-platform-before-legacy-auto-split-20260810-2145.dump514656字节,SHA-256=f776feb92243afb117b648256f630ad826039985030c4fae21ea631f111a20ea。本地执行后legacy_channel=0legacy_split=1carrier_specific=10;新建3条运营商任务和1条旧任务完成记录,已通过运营商任务approvedAt空值为0。原SQL再次执行新增任务0、记录0,数量不变,证明幂等。
  • 清退与通道专项2个suite/52项通过;API全量分组35/35个suite、448/448项通过。API TypeScript构建、前端TypeScript与Vite 8.1.5生产构建、Prisma validate及85条migration状态、4份Gateway队列结构契约和git diff --check均通过;前端仅有既有大chunk提示。整体Jest命令受既有未关闭句柄影响未自行退出,按完整suite清单分两组在全部断言通过后--forceExit取得明确退出码0。
  • 本地浏览器使用真实API和PostgreSQL验收:页面只显示“预警消息、检测规则、Webhook、抑制管理”4个页签,“历史待确认”不可见;切换检测规则成功,页面无框架错误覆盖,控制台error/warn为0。仅重置本地专用codex_local_admin临时密码以解锁既有本地会话,未新建账号。
  • 功能提交2ecb24cf8d09dd428dfab0c682b33581959618ea已推送并成功发布。精确Git归档outputs/cmpp-2ecb24cf-20260810-225340.tar.gz为2218419字节,服务器共826个归档条目,本地和服务器SHA-256均为ddcae8619f987522b1a9d487b13cdcfd9a82ea2a2cc7993caa01a7a1253bcedc
  • 发布前恢复资产位于/opt/cmpp-platform-backups/releases/20260810-225550-before-2ecb24cf,目录0700、文件0600。PostgreSQL备份17570927字节、SHA-256=25e2ea99936f39210684f88325589458e2dd4666f32598a3730f6e0a0d689166;运行源码备份2245714字节、SHA-256=834b658dd6050ab1f894ea3c267b95fab299fcd7834f9625757091f476f10548;环境文件895字节、SHA-256=7a26d83b062f9d7e9503e2a987f39a899510f8981be63be997bccfc988fbbc60。gzip、tar和sha256sum -c全部通过,上一运行目录保留为/opt/cmpp-platform.previous-20260810-225550;发布包装流程配置了失败时数据库和运行目录恢复,本次未触发回滚。
  • 标准tools/deploy/production-deploy.sh成功完成依赖安全缓解门禁、Prisma generate/migrate、前端/API/Gateway构建、Nginx校验以及Gateway先于API重启。第85条20260810214500_auto_split_legacy_signature_reports仅应用一次,最终.deployed-commit=2ecb24cf8d09dd428dfab0c682b33581959618ea
  • 发布前有61条legacy_channel任务和64个缺失运营商目标;发布后legacy_channel=0,新增legacy_carrier_auto_split=64legacy_scope_auto_split=61条migration轨迹。16条由历史已通过任务新建的运营商任务approvedAt统一为北京时间2026-08-10 22:56:14.239且空值为0;原有运营商级任务未覆盖,历史任务全部保留为legacy_split
  • API、Gateway、Nginx、PostgreSQL和MinIO均activeAPI/Gateway/MinIO健康、Redis PONG、Stream消费者1、pending=0lag=0,运营端、客户端和公网API health均HTTP 200;部署后API/Gateway error和warning级日志为0,运行源码和前端产物均不存在legacy-report-tasks或“历史待确认”标记。
  • 9条活动通道重启恢复后6条connected 1/1;“会员营销-富泷”“移动物业-富泷”“联电物业-富泷”继续为发布前已知的供应商authentication失败。本轮未修改通道账号、密码、启停状态、企业余额或客户连接,没有手工发送、补发或重投短信,也没有修改Webhook。受保护的api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/和空文件=继续不删除、不提交、不归因于业务源码提交。

2026-08-12 利润报表收入口径调整(历史开发记录,已随 0cd3534 发布)

  • 利润报表“净消费”统一更名为“收入”。收入按每条最终成功短信的billingUnits × unitPrice发送时快照逐条计算后汇总,失败和未知短信不计收入;不再以SmsBillingRecord.billingStatus=charged/refunded决定利润报表收入。不同历史单价必须分别计算,不能使用当前应用单价倒算。
  • 通道维度继续仅将收入归属到短信最终提交所在通道,避免补发链路在多个通道重复计收;成本仍按各次提交的通道成本单价快照乘以成功分片数,利润=收入-成本,综合利润率=合计利润/合计收入。
  • 页面明细、筛选结果汇总、前端类型、列表API和CSV均移除返还数据;CSV表头改为“收入金额(元)”。数据库DailyProfitReport.refundCents暂时保留作既有数据和回滚兼容,新重算快照统一写0,不执行破坏性migration。
  • 本地PostgreSQL和Redis恢复后,使用正式ReportsService成功重算2026-08-08至2026-08-11。独立SQL按应用逐条复核成功计费条数 × 客户单价快照,与报表收入差异0条,重算行refundCents非0差异0条;本地现有成功样本单价均为0,非零及混合单价场景由专项自动化断言覆盖,未伪造数据库样本。
  • 报表专项9/9、API全量35个suite/450项通过;前端TypeScript、API TypeScript正式构建及Vite 8.1.5生产构建通过,Vite仅保留既有大chunk提示。依赖包装器因既有msgpackr-extract构建脚本未审批而未用于验证,改为直接调用已安装的本地Jest、TypeScript和Vite入口,未修改依赖审批或供应链配置。
  • 本轮未提交、未推送、未部署,未连接或修改预生产数据,未发送、补发或重投短信。受保护的api/tsconfig.build.tsbuildinfotsconfig.tsbuildinfooutputs/和空文件=继续不删除、不提交、不归因于本需求;依赖包装器临时生成的pnpm-lock.yaml已精确移除。

2026-08-12 热力图观察期、登录动画与金额样式(历史开发记录,已随 0cd3534 发布)

  • 修复签名报备通过后完整观察窗口内不生成快照的问题:04:00检测现在按T-1自然日保存单日提交、受理和成功量,观察期状态为observing,不创建预警周期、站内消息或Webhook;观察期结束后仍使用配置的15/30天窗口累计量判断预警。热力图将检测日映射到T-1活动日,每行增加30日受理短信合计并按合计降序排序。
  • 企业签名管理列表中的企业、企业应用名称改为常规400字重;签名名称和状态层级不变。客户端登录页增加纯展示Canvas粒子连线动画,Canvas不接收点击、不读取输入,组件卸载时取消动画帧,系统减少动态效果或页面隐藏时停止位移。
  • 新增统一MoneyText只读金额组件,运营端和客户端现有余额、授信、单价、消费、返还、充值、收入、成本、利润及短信计费等金额,小数点和小数部分使用统一次级文字色;输入框、CSV、复制文本和底层金额值不拆分、不改变。
  • 本地正式SignatureRetirementService在真实PostgreSQL执行2026-08-12检测,生成11条alert、2条healthy、6条observing快照;执行前后站内消息均55条、Webhook投递均0条,证明检测阶段不外发。浏览器真实API验收热力图首列为08-11、显示30日合计且合计491/134/65/0按降序,6个观察期格子可见;企业与应用字重为400;金额小数色为rgb(107, 114, 128);客户端登录Canvas为2560×1440并正常绘制,页面控制台error/warn为0。
  • API全量35个suite/451项、签名清退与利润专项18/18项、前后端TypeScript、API正式构建、Vite 8.1.5生产构建、4份Gateway队列契约、Gateway go test ./...go vet ./...通过;Vite仅保留既有约2.06MB单chunk提示,git diff --check仅有既有LF/CRLF提示。

2026-08-12 下游投递后台重投任务与分页数量(已完成,待发布)

  • 已确认第一版设计:按当前真实筛选条件和创建时快照建立后台任务,只允许 pending/failed/unconfirmed/rejected,不批量重投 delivered,等待连接/ACK 与真正跳过严格分开。
  • 已增加任务/任务项真实 PostgreSQL 模型、预检、创建、分批原子认领、ACK 闭环、暂停/继续/终止、操作审计,以及运营端任务列表和详情;下游投递列表同步增加每页 10/25/50 条选择。
  • 本地PostgreSQL已真实应用20260812153000_add_downstream_requeue_tasks,当前共86条migrationPrisma validate、专项4项、API全量36个suite/458项、API/前端TypeScript、API/Vite生产构建、4份Gateway队列契约、R10结构契约和git diff --check通过。R10稳定门面方法数同步为104。
  • 全量Jest的458项断言均通过;仓库仍有既有异步句柄导致不自行退出,使用--forceExit取得退出码0。新增后台任务扫描器已在相关启动定时器用例中显式关闭,复跑时不再产生缺少测试Prisma delegate的循环错误日志。

2026-08-12 网关提交异常人工标记已处理(已完成,待发布)

  • “网关异常 / 提交异常”对pending记录增加“已处理”按钮和自研确认弹窗;确认后真实调用后端,将记录原子更新为resolved、写resolvedAtmanually_resolved,保留原始异常证据,不重新入队、不发送短信。
  • 后端记录操作人和gateway.submit_dead_letter_resolved审计日志;非pending状态拒绝并发标记,重复读取已处理记录保持幂等。
  • 功能纳入API全量36个suite/458项验证;前端TypeScript、API正式TypeScript构建、Vite生产构建和git diff --check通过,Vite仅有既有大chunk提示。

2026-08-12 全局运营商标签色值调整(已确认,待发布)

  • 移动、联通、电信继续复用CarrierTag全局低饱和胶囊组件,仅按确认方案调整背景、文字和边框色值,不改变标签尺寸、字重或业务状态标签。
  • 前端TypeScript、Vite 8.1.5生产构建和git diff --check通过。使用真实本地API和PostgreSQL登录短信通道管理页,计算样式逐项核对为移动#E8F1F7/#2F6F91/#C9DDE9、联通#F6EAEA/#875758/#E8CECE、电信#F0ECF7/#73538F/#DDD1EA,页面已保留供用户预览。
  • 用户确认页面预览后授权提交、推送,仍未授权部署;仅重置既有本地专用codex_local_admin临时密码以恢复本地验收会话,未新建账号。受保护缓存、outputs/和空文件=不归因、不处理。