Files
lislgosms/docs/testing-progress.md
2026-09-21 19:28:50 +08:00

5233 lines
1.0 MiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第一版系统化测试进度
## 2026-08-26 发送拦截修复与预生产发布
- P0发送拦截修复提交`4a17df78b85f842f724dd0c405febc86f1c34d43`已推送并发布到预生产;部署标记回读一致。发布前有效恢复资产为`/opt/cmpp-platform-backups/releases/20260826T053341Z-before-4a17df7`PostgreSQL custom dump、运行源码、环境/systemd/Nginx配置、RPM/Python包清单及Fail2ban安装文件清单均纳入`SHA256SUMS`并通过校验,`pg_restore --list`和tar可读性通过。
- Alibaba Cloud Linux 4系统仓库不提供兼容的Fail2ban包;预生产按Fail2ban官方固定`1.1.0`源码安装,未增加永久第三方软件源。Fail2ban配置测试、服务状态、SSH、Nginx、nftables空封禁集合和安全代理Socket权限均通过。
- 数据库由90条推进至94条migration,实际新增Submit结果幂等、入站Inbox、Submit Outbox和上行eventId四条迁移。API、独立Send Worker、Gateway、安全代理、Fail2ban、PostgreSQL、Redis、Nginx均activeAPI/Gateway/前端健康,Inbox最终无pending/processingSubmit命令Stream为`pending=0/lag=0`。
- 发布后发现主API回调模式下未显式配置批量开关时,Gateway却默认启用批量回调;批量路由只存在于独立callback进程,导致`gateway.submit.results`一度累积到97条pending。预生产显式设置`GATEWAY_CALLBACK_BATCH_ENABLED=false`并重启Gateway后,PEL按幂等逐条回调从97持续降至0并连续六次保持`pending=0/lag=0`,未手工ACK或删除事件。
- 最小代码修复将批量回调改为仅在环境变量严格等于`true`时启用,并增加默认关闭单元测试、示例环境和发布门禁说明。全程未进行压力测试,未由测试人员主动发送、补发或重投短信,未修改通道账号、启停状态、企业余额、白名单、临时号段或测试账号;发布窗口存在预生产客户自然流量,均按真实链路处理。多Gateway P2未实施。
- 回调修复提交`8170f727a3c547e3c51d7308a08680ecac9ae1f0`已推送并热修复到预生产;热修复备份为`/opt/cmpp-platform-backups/releases/20260826T135700CST-before-8170f72-gateway`,包含当前PostgreSQL custom dump、运行源码、系统配置、旧Gateway二进制和部署标记,SHA-256、`pg_restore --list`及tar可读性均通过。热修复后又发现Gateway单独重启会使供应商连接变成`desired=0/connected=0`;在不修改通道配置的前提下按正确顺序重启API后恢复为`9/9`。发布脚本已改为独立callback(如启用)→Gateway→API→Send Worker,并增加顺序门禁,避免后续仅健康接口正常但供应商通道未恢复。
> 环境命名:`8.160.169.106:12026`Web/API)和 `8.160.169.106:17890`CMPP 入站)实例统一定义为“预生产环境”;`100.93.204.60`统一定义为“虚拟机测试环境”或“测试机”。“虚拟机”不得再用于指代预生产。历史记录中涉及这两个实例的验证和部署按其明确IP归属理解;`production-deploy.sh`、`NODE_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 均 active`3000/8090/12026/17890/9000` 正常监听,运营端、客户端和公网 API 均返回 200。Redis Stream 为 `consumer=1/pending=0/lag=0`,发布后 API/Gateway error 日志为 0,前端实际产物为 `index-C2qqOO8d.js` 和 `index-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 分别为 `12c372c9ccc65a815444b59cd5856864128b25f137a5fc141bec91084b2f0921`、`8100e7f88275e87fe7ccca89ceeb76443488335972076a767c6c29d64b944712`、`87ab2efd509b39849b0ee22ead1b4cf0568fba4ab8525c59b5c78da51c73bc86`。
- 本地定向 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 均 active`12026/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-api`、`cmpp-gateway`、`cmpp-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`,提供日期、企业、企业应用、通道、统计维度和服务端分页。
- 新增 `DailyReconciliationReport`、`DailyProfitReport` 真实 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 与运营端企业列表统一按当天 `refunded` 加 `released + relatedType=sms_message_record` 汇总;排除任务冻结转扣费时的 `released + relatedType=sms_batch_task`,避免把内部账务转换误当成返还。
- API 依赖升级到 NestJS `11.1.28`、Multer `2.2.0`,并通过 override 将 `@hono/node-server` 固定为 `1.19.13``npm --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_ID`NestJS 立即终结为 `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.sql`65MB)、`/opt/cmpp-platform/backups/source-20260715-120751.tar.gz`104MB)、`/opt/cmpp-platform/backups/cmpp-platform-20260715-120751.env`,均非空、权限 `600` 并完成 SHA-256 校验。
- 发布包本地与服务器 SHA-256 均为 `e1f14706389e6c42e89161422b07e6a409213dd54b9ae39b6bcc50dbba53f61e`;生产 `.deployed-commit=a758672436b3ebcd78aab91ba4a8e3cf68cbdfb0`43 条 migration 全部齐全且无待执行项。
- `cmpp-api`、`cmpp-gateway`、MinIO、Nginx、PostgreSQL、Redis 均 active`12026/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.tsbuildinfo` 和 `logs/`。发布前确认本地 `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.sql`65MB)、`/opt/cmpp-platform/backups/source-20260715-112406.tar.gz`20MB)和 `/opt/cmpp-platform/backups/cmpp-platform-20260715-112406.env`;三份文件均非空、权限 `600` 并完成 SHA-256 校验。
- 发布包本地与服务器 SHA-256 均为 `c26d2414df13e535f3ce69d838d299d80680f23576599f264b7043ad1eea713c`。生产成功应用 `20260715090000_track_downstream_manual_retries`、`20260715153000_remove_disconnected_downstream_sessions`,共 43 条 migration 全部齐全;非 connected 历史连接行已清为 0,下游人工重投字段已可查询。
- 生产 `.deployed-commit=e47432bc631bf37f4c6a6dcb3576ce3c86370b45``cmpp-api`、`cmpp-gateway`、MinIO、Nginx、PostgreSQL、Redis 均 active`12026/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 账号 `910887` 向 `18821203795` 提交验证码短信,应用已于 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`,无通道、`submitId` 和 `SmsSubmitRecord`。
- 生产 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=true` 和 `API_SEND_WORKER_CONCURRENCY=50`Redis `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 均为 active`12026/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=28dad93e3ed7adcc7791a92723200ffe19509999`API、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` 新增 `createdAt`、`resource+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 连接后,创建独立 `SmsMessageRecord`、`SmsSubmitRecord` 和操作日志,并向 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 --runInBand`、`npm --prefix api run build`、`npm 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,确认只处理 `Cmpp3DeliverReqPkt`CMPP 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` 新增 `interfaceEnabled`、`interfaceType` 持久化字段;企业应用创建、编辑、列表和 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:generate`、`npm --prefix api test -- sms-config.service.spec.ts send-chain.service.spec.ts`、`npm --prefix api run build`、`npm run build`、`git diff --check`、`npm --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`,复制日志补充 `sourceStatus` 和 `copiedStatus`,避免 active 通道副本自动占用上游连接。
- Gateway `ConnectChannel` 改为直接建立/复用真实上游连接池,并由连接池回写 `connected/failed/disconnected`、`currentConnections`、最近错误和断开时间;连接丢失时状态随真实连接数变化更新。
- 测试口径同步:
- `TC-ADMIN-003` 增加“连接状态必须来自真实上游连接池回写”的要求。
- `TC-ADMIN-016` 明确复制 active 通道后副本默认 `disabled`,且不会立即触发上游真实连接。
- 已执行:`npm --prefix api test -- channels.service.spec.ts --runInBand`、`npm --prefix api run build`、`go test ./internal/control ./internal/upstream`、`go build -o ..\\dist\\cmpp-gateway .\\cmd\\gateway`。
## 2026-07-09 线上通道 CMPP 版本修复
- 线上生产验证发现 3 个赛邮行业通道配置均指向 `121.40.172.212:7890`,其中 2 个已触发 Gateway 真实连接并失败,`CmppConnectionState.lastError` 为 `packetWriter.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` 固化到 `SmsMessageRecord`BullMQ 入队按 priority/normal 写入不同 job prioritySubmitCommand 契约、示例和 Go Gateway 队列结构已增加 `queuePriority`;当前实现覆盖优先队列插队的基础能力,持续高优先级流量下普通队列防饥饿策略仍需后续压测和调度增强。
- 2026-07-07 追加:Gateway 队列契约第 8 步已独立校验,`SubmitCommand` schema/example 要求 `queuePriority`Go Gateway `SubmitCommand` 结构可反序列化该字段,并通过 `npm run spike:contracts` 与 `npm run spike:gateway`。
- 2026-07-07 追加:第 9 步收口验证通过:`npm --prefix api run prisma:generate`、`npm --prefix api test -- sms-config.service.spec.ts send-chain.service.spec.ts --runInBand`、`npm run spike:contracts`、`npm run spike:gateway`、`npm --prefix api run build`、`npm 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.exe`、`C:\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。
### 已执行命令
```bash
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 个测试通过。
- Gateway`npm 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-001`、`TC-TEMPLATE-002`、`TC-TEMPLATE-003 / TC-RISK-005`、`TC-RISK-001`、`TC-RISK-002`、`TC-RISK-003`、`TC-RISK-004`、`TC-BILLING-001 / TC-TEMPLATE-005`、`TC-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-004`、`TC-SEND-005`、`TC-SEND-006`、`TC-SEND-007`、`TC-SEND-008`、旧版 `TC-SEND-009 / TC-SEND-010` 均通过。
- 2026-07-03 新增的通道组真实路由用例 `TC-SEND-010` 到 `TC-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-001`、`TC-BILLING-002 / TC-RECHARGE-001`、`TC-BILLING-003`、`TC-BILLING-004 / TC-BILLING-005 / TC-BILLING-006 / TC-BILLING-007`、`TC-BILLING-008 / TC-RECON-001 seed`、`TC-RECON-001`、`TC-DASHBOARD-001 / TC-STAT-001`、`TC-TRACE-001`、`TC-BILLING-009` 均通过。
- 验证了费用预估、人工充值、余额检查、冻结、扣费、释放、退款、短信计费记录、账务流水、dashboard/statistics、trace 和 reconciliation。
- 自动计费探测发现发送任务不会自动生成短信计费记录、账户交易流水,消息金额默认为 0,已在 `docs/testing-execution-step-6.md` 记录为发送计费集成缺口。
- 第 7 步客户/通道 CMPP 连接状态和 Gateway smoke 通过:
- `TC-GW-CONTRACT-001`、`TC-GW-001`、`TC-GW-002`、`TC-GW-003`、`TC-GW-004`、`TC-CMPP-STATUS-001 / TC-CHANNEL-001`、`TC-CHANNEL-ROUTE-001`、`TC-CHANNEL-METRIC-001`、`TC-CMPP-SESSION-001 / TC-CONNECTION-COUNT-001`、`TC-CMPP-STATUS-002 / TC-OPERATIONS-MONITOR-001`、`TC-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` 增加 `scheduledAt`、`canceledAt` 字段和 `status/scheduledAt` 索引。
- `CreateBatchTaskDto` 支持 `sendMode=scheduled`、`scheduledAt`。
- 新增定时任务取消和到点触发入口:`POST /api/client/send/batch-tasks/:id/cancel`、`POST /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 聚合连接状态。
- 新增应用密钥重置、应用/签名/模板状态变化、通道启停接口,并写入系统日志。
- 无效 `createdById`、`reviewerId` 改为明确 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 连接状态聚合。 |
### 已执行命令
```bash
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`:基于 `OperationLog` 和 `CmppConnectionState` 查询连接日志;保留 `/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` | 敏感词、全局黑名单、企业黑名单查询、创建、软删除和操作日志。 |
### 已执行命令
```bash
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 新增浏览器和业务闭环用例执行
### 执行环境
- API`npm --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 使用真实数据库。
### 已执行命令
```bash
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` 使用 `rechargeRecordsSeed` 和 `useState``submitManualRecharge` 只 `setRecords`。 | 页面提交调用 `POST /api/admin/billing/manual-recharges`,成功后刷新真实充值记录、账户余额、流水和日志。 |
| BUG-FE-002 | P0 | 运营端 Dashboard 仍使用 mock service 和静态排行,不能证明真实统计准确。 | `src/apps/admin/AdminHome.tsx` 引用 `adminService`、`hourlySendTrend`、`auditTrend`,指标从前端数组计算。 | 接入 `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.tsx`、`src/apps/client/ClientSystemLogsPage.tsx` 页面 smoke 可展示,但未证明调用真实日志 API。 | 接入真实日志 API,支持分页、筛选、详情、租户隔离,失败动作也可查。 |
| BUG-FE-005 | P0 | 企业应用 CMPP 状态和连接详情页面仍使用本地初始数据,未读取真实连接状态 API。 | `src/apps/admin/AdminEnterpriseApplicationsPage.tsx` 使用 `initialSmsApps`、`setSmsApps`,连接删除也是本地状态变更。 | 接入企业应用、连接状态、连接详情、连接删除/断开真实 API 或 Gateway 回写接口。 |
| BUG-API-001 | P1 | 通道创建参数缺失时返回 Prisma 500,而不是业务 400。 | 浏览器 smoke 第一轮 `POST /api/admin/channels` 缺少 `code/gatewayHost/gatewayPort/account/passwordCipher/srcId`API 返回 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 | 通道组省网/全国路由没有接入真实发送链路,手机号段库也未参与归属地识别。 | `SmsChannelGroupItem` 和 `ChannelRouteRule` 虽有 `carrier/province` 字段,`PhoneSegment` 有 `prefix/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`、连接 `connected`、`desiredConnections > 0` 且 `currentConnections > 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` | 通道发送地区默认值、通道组补发配置、禁止单通道路由规则。 |
### 已执行命令
```bash
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-010` 到 `TC-SEND-018`、`TC-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 build` 再 `vite 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
```bash
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 持久化字段:`email`、`phone`、`failedLoginCount`、`lockedUntil`、`lastLoginAt`、`deletedAt`。
- 登录入口拆分为 `/client/login` 和 `/admin/login`,两端均调用真实验证码和登录 API。
- 用户登录入口和用户表单统一文案为“用户名/登录账号”,提示可用用户名、邮箱或手机号登录。
- 运营端登录仅允许 `platform_admin`;客户端登录仅允许已关联企业的 `enterprise_admin`。
- 运营端用户管理接入真实 `/api/admin/users`,支持平台管理员和企业管理员的新增、编辑、启用/禁用、删除、改密;企业管理员必须关联企业。
- 客户端用户管理接入真实 `/api/client/users`,所有操作继承当前登录企业 `tenantId`。
- 启用/禁用、删除均通过确认弹窗执行;用户删除采用软删除,不破坏历史日志和业务记录。
- 连续 5 次登录失败后锁定 24 小时;登录成功清空失败次数和锁定状态。
### 已执行测试
```bash
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.ts`、`auth.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 失败展示错误态。
- 企业签名/企业模板运营端列表只展示真实短信配置数据;彩信相关菜单继续作为待开发边界,不计入第一版短信验收。
### 已执行命令
```bash
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` | 应用配置与列表在新增客户费率字段后继续通过。 |
### 已执行命令
```bash
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 位 `cmppAccount`Prisma 迁移 `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/submit`NestJS 按 `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_received`、`submit_accepted`、`submit_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/uplink`Gateway 向在线客户下发 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_URL`、`GATEWAY_SUBMIT_STREAM`、`GATEWAY_SUBMIT_GROUP`、`GATEWAY_SUBMIT_CONSUMER`、`GATEWAY_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` 增加 `applicationId`、`messageRecordId`、`matchStatus`、`matchReason`,并建立应用和匹配下发记录关系。
- 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=1`、`windowSize=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 配置入口补齐
### 本轮修复
- 运营端通道创建/编辑表单新增上游 `desiredConnections` 和 `windowSize` 输入,真实提交到 NestJS 通道 API,并规范化写入 `SmsChannel.config`。
- NestJS `ChannelsService` 对 `desiredConnections/windowSize` 增加正整数校验;通道激活后的 `ConnectChannel` 请求和发送链路 `SubmitCommand.upstream` 均复用该真实配置。
- Prisma 为 `SmsApplication` 新增 `cmppMaxConnections`、`cmppWindowSize` 字段;运营端短信应用创建/编辑表单新增 `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/lockExpiresAt`Gateway 回传并由 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`:认领后更新 `SmsUplinkMessage` 为 `matched`,选中候选置为 `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`。
- 未识别的运营商状态按失败处理,避免把未知回执误判为通过。
### 已执行命令
```bash
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 演示页面。
- 客户端短信发送详情、批量任务表格中明显偏窄的中文字段列已加宽。
### 已执行命令
```bash
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 视口下弹窗偏移或被截断。
### 已执行命令和浏览器验证
```bash
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` 下载。
- 运营端企业照片、企业签名材料、引流材料、报备回执导入均在真实上传成功后显示下载入口;图片类型文件显示点击预览入口。
- 客户端企业认证营业执照上传成功后显示下载入口,图片类型文件显示点击预览入口;提交认证时保存文件类型信息。
- 客户端签名列表对已保存签名材料显示下载入口,图片材料按文件名或类型显示预览入口。
- 客户端短信发送导入号码文件为前端解析文件,未生成后端文件对象;页面仅提供本地原始文件下载,不标记为真实后端归档。
### 已执行命令
```bash
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` 负责。
### 已执行命令
```bash
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 小时。
### 已执行命令
```bash
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/transactions` 和 `GET /api/client/billing/transactions`。
- 保留内部 `AccountTransaction` 写入能力,人工充值、扣费、释放、退款等真实计费动作仍可写入内部账务记录;本期不作为独立账单流水页面验收。
- 通用 `Table` 组件新增内置分页,默认每页 10 条;服务端分页页面关闭内置分页,避免双分页。
- 补齐手写列表和卡片列表分页:通道管理、通道组、充值记录、客户端应用、客户端充值套餐、客户端签名、客户端模板、客户端批量任务、客户端发送详情、运营端短信任务进度、运营端企业签名。
### 已执行命令
```bash
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 小时或关闭补发时均不再补发。
### 已执行命令
```bash
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 健康状态和典型号段归属地查询。
### 已执行命令与结果
```bash
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/1300001` 和 `nextCursor=1300001`,下一页返回 `1300002/1300003`,响应无 `total` 字段。
- 生产 API 搜索 `1882120` 返回“中国移动/上海/上海”;搜索“上海”首屏响应约 80ms。
- 生产 `cmpp-api`、`cmpp-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 企业充值流程瑕疵
### 本轮修复
- 企业新建/编辑页的图片“预览”改为站内弹窗展示,不再跳转或新开页面;下载仍走真实对象存储文件接口。
- 通用 `Input`、`Select`、`Textarea` 根据 `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`,与后续充值或消费后的当前余额无关。
### 已执行命令与结果
```bash
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.106`Prisma migration deploy 无待执行迁移,`cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均为 activeAPI/Gateway health、Redis 均通过。
- 生产管理员真实登录后只读调用 `GET /api/admin/billing/manual-recharges` 成功返回 2 条记录,响应包含真实 `balanceAfterCents`10000、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` 规范化过程静默丢弃。
- 网关密码保持安全策略:编辑时不回显已配置密码,留空不覆盖;输入新密码才更新真实通道配置。
### 已执行命令与结果
```bash
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-api`、`cmpp-gateway`、Nginx、MinIO 均为 activeAPI/Gateway health 正常。生产运行源码已确认包含流速校验、扩展位数持久化及 Gateway 队列字段。
- 通道组名称为空时已有前端提示“请输入通道组名称”,保存会在调用真实创建/更新 API 前中断;本轮复核后不重复改动。
- 通道编辑密码保持掩码且不回显:编辑时明确提示“留空保持不变,填写新密码才更新”;新建通道仍要求填写密码。
- 上述密码交互调整已于 2026-07-10 生产验证部署后再次核验:`cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均为 active,内外部 health/HTTP 检查通过。
- 短信记录列表修复:企业、应用、手机号、状态之外的提交日期、短信内容、通道名称筛选改为传给 `GET /api/admin/operations/messages`NestJS 通过 Prisma/PostgreSQL 执行内容、关联通道名和上海自然日范围查询,页面不再仅筛选已加载的前 500 条记录。
- 生产只读复现确认:短信记录 9 条均有真实 `SmsSubmitRecord`,其中 4 条已有真实 `SmsReceiptRecord`3 个通道均有 `CmppConnectionState` 和 `OperationLog` 连接日志。按一条生产记录的日期、内容、通道关键词组合查询,9 条中仅返回 1 条且条件均匹配。
- `OperationsService` 定向测试 12 项、API build、前端 build 均通过;已部署生产验证,`cmpp-api`、`cmpp-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 --runInBand`23 项通过)、`npm run build` 和 `git diff --check`;前端保留既有 Vite chunk size warning。
- 已部署生产验证:Prisma migration deploy 无待执行迁移,`cmpp-api`、`cmpp-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:generate`、`npm --prefix api test -- auth.service.spec.ts session-validation.middleware.spec.ts users.service.spec.ts --runInBand`3 suites、8 项通过)、`npm --prefix api run build`、`npm run build`、`git diff --check`;前端保留既有 Vite chunk size warning。
- 已部署生产验证:第 25 条 Prisma migration `20260710153000_add_user_session_version` 成功应用;`cmpp-api`、`cmpp-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-api`、`cmpp-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.ts`24 项通过)、`dictionaries.service.spec.ts`4 项通过)、`operations.service.spec.ts`12 项通过)、API build、前端 build 与 `git diff --check` 均通过;前端仍仅有既有 chunk size warning。
- 已部署生产验证:`cmpp-api`、`cmpp-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 build` 和 `git diff --check`;已部署生产验证,`cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均为 activeAPI/Gateway health 通过。生产源码和已构建静态资源均包含新的查询操作组与手机号段工作台样式;手机号段 API 继续返回真实 `total/page/pageSize`。
## 2026-07-11 CMPP 业务失败回执闭环
- 修复下游 CMPP 入站的审计缺口:客户已完成 bind、账号可识别且手机号参数合法后,NestJS 会先创建真实 `SmsBatchTask`、`SmsApiRequest` 和 `SmsMessageRecord`,再执行模板、签名/报备、风控和余额校验;不再因模板未报备等业务失败而直接丢弃客户 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.ts`34 项通过)、`npm --prefix api run build`、`go 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-api`、`cmpp-gateway`、Nginx、MinIO 均为 active`12026/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.ts`35 项通过)、`npm --prefix api run build`、`npm run build` 和 `git diff --check`;前端仅有既有 chunk size warning。
- 已将 `7b8424d9` 部署生产,migration `20260711210000_add_message_route_identity` 成功应用。`cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均为 active`12026/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/status` 的 `groupBy` 全量聚合。
- 短信任务进度不再为每个任务最多加载 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-api`、`cmpp-gateway`、Nginx、MinIO 均为 active`12026/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 号码仍进入短信记录。
- 客户端任务详情、任务短信明细和取消接口同时校验当前 `tenantId` 和 `sourceType=client`,不能通过内部批次 ID 读取或操作 CMPP 内部任务。
- 生产现状只读核对:`sourceType=cmpp` 2 个、`sourceType=admin_channel_test` 1 个、`sourceType=client` 0 个。部署后任务进度应显示 0 个客户批量任务,但不删除现有内部批次数据。
- 已执行 `send-chain.service.spec.ts + operations.service.spec.ts`2 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 migration`20260712113000_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-api`、`cmpp-gateway`、Nginx、MinIO 均为 active`12026/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 migration`20260712150000_link_report_field_library`。已执行 Prisma generate/validate、`channels.service.spec.ts + sms-config.service.spec.ts`2 suites、44 项通过)、API build 和前端 build;前端仅有既有 chunk size warning。
- 已提交并 push `87ae4a20`,随后以该提交生成发布快照并部署生产;部署前备份 PostgreSQL 和运行源码,migration `20260712150000_link_report_field_library` 已成功应用。生产 `.deployed-commit=87ae4a20``cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均为 active`12026/17890/8090/3000` 监听,API/Gateway health 和外部 HTTP 均通过。
- 生产数据库已确认 `ChannelReportField.drainageFieldId/reportType` 和 `DrainageReportMaterial` 存在。当前生产 `DrainageField=0`、`ChannelReportField=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=eab05958``cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均为 active`12026/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=ade06058``cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均为 active`12026/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`,四项服务 active`12026/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=19d47b45``cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均为 active`12026/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/drainage` 和 `drainageItemId`。保存引流资料时,根据企业应用的真实路由通道及其 `drainage/both` 字段自动生成 pending 任务和 create 记录;删除引流项时同步清理对应材料和任务。
- 企业签名引流列表、通道报备详情、报备任务页均按引流项和通道读取/修改同一任务,共享报备记录、导出和回执链路。企业签名三网状态改为引流任务真实汇总,不再使用 `drainageInfo.links.mobile/unicom/telecom` 静态值。
- 短信发送选路和最终通道二次校验明确增加 `reportType=signature`,引流通过任务不会误放行未报备签名。Prisma migrations`20260713153000_add_drainage_report_tasks`、`20260713154000_backfill_drainage_report_tasks`、`20260713155000_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`,四项服务 active`12026/17890/8090/3000` 监听,API/Gateway health 和外部 HTTP 200;前端产物已包含“短信签名审核”“按通道修改引流信息报备状态”“签名与引流信息报备任务”。生产现有 4 条任务均已回填为 `reportType=signature``DrainageReportMaterial=0`,因此没有伪造引流任务,待真实引流字段资料保存时自动生成。
- 部署后交付复核发现历史运营端新建的 draft 签名虽可在审核页筛选,但操作按钮只对 pending 开放。已改为 draft/pending 都可由运营直接通过或驳回,用于处理【安徽航天信息】等存量草稿;新增签名仍按新规则自动通过。修正提交 `ff3e5607` 已部署,二次备份时间戳 `20260713-174512`;生产 `.deployed-commit=ff3e5607`,四项服务、端口、API/Gateway health 和外部 HTTP 200 再次验证通过,部署后 API stderr 无新错误。
## 2026-07-13 引流信息独立审核与报备任务门禁
- 生产只读核查确认当前 `DrainageReportMaterial=0`、`reportType=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_workflow`Prisma 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.sql` 和 `source-20260714-095958.tar.gz`,最终修正部署前备份为 `/opt/cmpp-platform/backups/cmpp-20260714-100658.sql` 和 `source-20260714-100658.tar.gz`;发布包本地与服务器 SHA-256 一致。
- 生产 36 条 migration 全部应用,四项服务 active`12026/17890/8090/3000` 监听,API/Gateway health 和外部 HTTP 200,部署后 journal 无新 error。真实报备记录 API 返回 16 条且通道名称缺失数为 0;7 条系统记录为 `system`9 条旧人工记录为 `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=f08a73e19129f5249a5a9e0035c7ab63b80422d4``cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均 active`12026/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 会话,逐次校验用户状态和 `sessionVersion`Gateway 回调和 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=8c03663f245c12cd5e6aab28ad9eeb68ea60ed57``cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均 active`12026/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 分别为 `9677414932210841325`、`9687782471788644609`。这只能证明下游协议栈收到了 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/warn`delivered` 行的重投按钮可用且点击确实进入真实后端重投链路;因本地未运行 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=1ce02ef2066aa1ecd995b0a3b884304218adc008``cmpp-api`、`cmpp-gateway`、Nginx、MinIO 均 active`12026/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 >= 0`、`bottom <= 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` 退出既有异步句柄。
- 工作区完整改动已提交并 push`a7a4e8d9f6aba00b8137e5b70c59bdef67ed3b57``feat: polish reporting templates and shared controls`)。部署前确认本地 `main` 与 `origin/main` 一致,并备份生产 PostgreSQL、运行源码和环境配置至 `/opt/cmpp-platform/backups/releases/20260715-163418`;三份备份均通过 SHA-256 复核和压缩包完整性检查,其中数据库备份 SHA-256 为 `a59d3b7f4538f99cdc73a1092ac31628efa45bc38d4adf20a05d6a1f075ec5da`,运行源码备份为 `305c529fb94c71fd6e49f6228717b2ce93f14fff84a84e477d1f202f3192ef58`。
- 发布快照本地与服务器 SHA-256 均为 `489d6c969252403689dfdcca15b87e4f5a93b65187551fa6650451527366942e`。生产 `.deployed-commit=a7a4e8d9f6aba00b8137e5b70c59bdef67ed3b57`47 条 migration 全部齐全;`cmpp-api`、`cmpp-gateway`、MinIO、Nginx、PostgreSQL、Redis 均为 active`12026/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_workflow`、`20260715193000_scope_channel_report_fields_by_type`、`20260715194000_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_limit`Prisma 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/ratelimit`、`internal/control`、`internal/submitworker`API `operations.service.spec.ts`、`send-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 均为 `dc9fce751fce42bcf8ac14a4b9fd6a1d28a489469350904ee395db3ceb9dcab9`4 条 migration 成功应用,51 条齐全;首轮健康检查、端口、受保护异常 API 401 和静态资源均通过。由于随后发现并修复上述 Gateway 重启恢复缺口,最终运行提交和复验结果以修正发布记录为准。
- 启动恢复修正提交 `85ff0376` 已 push 并完成最终运行时发布;发布前第二次备份至 `/opt/cmpp-platform/backups/releases/20260715-183017`,数据库、源码、环境文件 SHA-256 分别为 `8d632d63db1afcad37889b445e3989819c15053d544f3a63239dca20cd0baecd`、`5ffc421046f436d5f8ed8178c7a884c4e476567826740d469f4560360304744d`、`87ab2efd509b39849b0ee22ead1b4cf0568fba4ab8525c59b5c78da51c73bc86`;最终运行发布包本地/服务器 SHA-256 均为 `930ac2a24bf6c1ee24cdfb2f90dff26d89bf7e1f9d84425aa800e66aa8ef4b9a`。
- 生产 51 条 migration 全部齐全;`cmpp-api`、`cmpp-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_requested` 与 `cmpp_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 侧栏布局影响,本轮未扩展修改全局响应式框架。
- 工作区完整改动已提交并 push`dcb6162dcf93a70e9886c978b07fdccee19dd657``feat: add HTTP API and complete client workflows`)。部署前确认本地基线与最新 `origin/main` 一致;生产 PostgreSQL、运行源码和环境文件备份目录为 `/opt/cmpp-platform/backups/releases/20260716-113511`,三份备份均非空并通过 gzip/tar 完整性及 SHA-256 校验,SHA-256 分别为 `e384e1f041c0638943a0eee4da1877169b3aa89c4b0da95e55908be598ed31e0`、`1e28149b8b9d068f797a68d66ea074c88a0a43f0efd0b26f0b2d94afc259db3f`、`87ab2efd509b39849b0ee22ead1b4cf0568fba4ab8525c59b5c78da51c73bc86`。
- 发布包本地与服务器 SHA-256 均为 `b49b51ef1acd2a0bb709ca91fbe0b98c16c80bc86f24b35b5dba141907cc7116`;生产原缺失的 `HTTP_API_MASTER_KEY` 已生成并以 `600` 权限保存,密钥内容未输出。migration `20260716110000_add_http_open_api` 已应用,52 条 migration 全部齐全且 schema 最新;生产运行提交为 `dcb6162dcf93a70e9886c978b07fdccee19dd657`。
- `cmpp-api`、`cmpp-gateway`、MinIO、Nginx、PostgreSQL 和 Redis 正常,`12026/17890/8090/3000/9000` 监听,API/Gateway health、Redis PONG、PostgreSQL readiness 和外部首页、运营端、客户端、客户 Swagger 文档均通过。两个 Redis 通道权威 TPS key 均恢复为真实值 100`gateway.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=1230`1280px 下均为 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 金额列统一升级为 `BigInt`migration `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 均为 100`gateway.submit.commands` 为 `pending=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=2`Gateway 返回 `result=0`,但只将首号码 `188****3795` 传入 NestJS 并创建一条 `SmsMessageRecord`;随后单独提交第二个号码 `131****0092` 才产生第二条记录。核查期间未修改生产配置、数据或进程。
- 根因为 Gateway 已完整解码 `DestTerminalId[]`,但处理时固定读取下标 `0`Gateway→NestJS 契约和 `submitInboundMessage` 也只有单数 `phoneNumber`NestJS 固定以 `phoneTotal=1` 创建内部批次和短信记录。当前行为属于“返回成功但静默丢失后续号码”,不是可接受的单号码范围限制。
- Gateway 入站契约新增完整 `phoneNumbers`,保留首号码字段兼容;NestJS 在任何业务落库前校验全部目标号码,并以最多 10 个并发的有界批次逐号码复用现有真实模板/签名、风控、余额、计费、队列和失败回执链路。每个号码创建独立 `sourceType=cmpp` 内部批次和 `SmsMessageRecord`API 返回全部内部 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 validate`git 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行删除;提交为`f02c33cbb7248410c189f75502d6e497fff7b355``feat: harden CMPP delivery and platform workflows`),已push至`origin/main`。按约束排除`api/tsconfig.build.tsbuildinfo`和`logs/`。
- 提交前门禁: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_id`、`20260720110000_add_receipt_identity`、`20260720113000_add_report_business_metrics`、`20260720114500_add_receipt_phone_number`,生产57条migration齐全且schema最新;CMPP多号码分组、回执唯一身份/目的号码、报表失败退款指标等目标列均已存在。
- 预发布运行提交为`f02c33cbb7248410c189f75502d6e497fff7b355`。`cmpp-gateway`、`cmpp-api`、Nginx、PostgreSQL、Redis和MinIO均active`12026/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 NULL` 且 `connectedAt` 也早于超时窗口时才删除,避免误清刚建立但首个心跳尚未到达的连接。回归测试先在旧实现上失败,修复后 `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` 均为 `ok`Redis `PONG`Gateway 监听 `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_ENABLED` 和 `SMS_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 + updatedAt` 的 `updateMany` 原子认领,认领态为 `manual_requeueing`Gateway 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.ts`与`prisma.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行删除;功能提交为`0f223f7f91d1bd24e7a2cc0ce6ce9ae3e3258b10``feat: 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-gateway`、`cmpp-api`、Nginx、PostgreSQL、Redis(实际unit为`redis`)和MinIO均active`12026/17890/8090/3000/9000/6379/5432`监听;API/Gateway health、Redis PONG、PostgreSQL readiness均通过。两个active上游通道`CH-1783566107506`、`CH-1783566107506-COPY-MRCXAK2W`均恢复为`connected/currentConnections=1`Redis中7个通道权威TPS配置存在;`gateway.submit.commands`的`cmpp-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`)
- 合并功能提交`a09036c67bd24ce7e4b9372aa24918fec9d8386f``fix: enforce application limits and signature format`)首次由另一会话推送时遇到Git HTTP认证失败;本次重新执行`git fetch`和`git push origin main`成功,发布前`HEAD`、`origin/main`均为该提交。未提交`api/tsconfig.build.tsbuildinfo`和`outputs/`;发布期间另一会话新增的`api/src/send-chain/send-chain.service.spec.ts`、`gateway/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_defaults`和`20260722173000_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-gateway`、`cmpp-api`、Nginx、PostgreSQL、Redis和MinIO均active`12026/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=8`Gateway同步返回唯一一个非0 `SUBMIT_RESP`且Msg_Id为0,不建立下游会话映射、不生成`SmsReceiptRecord`、不创建`CmppDownstreamDelivery`,不冻结或扣费。
- 新增API回归覆盖双号码整包超限、每号码审计记录及无回执/无冻结;新增Gateway真实CMPP2.0协议回归覆盖Bind后的`result=8`响应和不新增pending回执拉取。失败测试先在旧实现上分别暴露`accepted=true`和Gateway响应结构缺少业务结果码,修改后SendChain定向78项及Gateway inbound包通过。
- 功能提交`55019443c0015c65da94f0ad17ed274d77e6290a``fix: 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`。三份文件权限均为600`sha256sum -c`、数据库gzip和源码tar完整性校验通过。
- 发布包本地与服务器SHA-256均为`191c41d068b0f418bf04ca44cb4dbd25bcac765961b7b259136102256ba3ba5c`。使用`tools/deploy/production-deploy.sh`完成发布,无待执行migration;脚本先重启Gateway再重启API`.deployed-commit=55019443c0015c65da94f0ad17ed274d77e6290a`。
- 发布后`cmpp-gateway`、`cmpp-api`、Nginx、PostgreSQL、Redis和MinIO均active`12026/17890/8090/3000/9000/6379/5432`监听;API/Gateway health、Redis PONG、PostgreSQL readiness和60条migration状态通过。`gateway.submit.commands`为`pending=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_ASCII`。`20260722173000_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`均通过。
- 功能提交`e28288f6911da002dce39e0e5208609a40bc0e30``fix: repair SQL_ASCII signature encoding`)已push至`origin/main`。首次push遇到Git Credential Manager瞬时认证失败,原命令重试后成功;未提交`api/tsconfig.build.tsbuildinfo`和`outputs/`。
- 部署前PostgreSQL、运行源码和环境配置备份至`/opt/cmpp-platform/backups/releases/20260722-185147`。数据库备份4398661字节、SHA-256 `d0513ca2321bbd73859fd9e28d06380bda78e40383de50d919b13022fefc1976`;源码备份28618928字节、SHA-256 `aca65f5ac304063da476f56baaf1277a3c3487a0e1aefd6fa6f2d2dffebb87c7`;环境文件850字节、SHA-256 `189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7`。三份文件权限均为600gzip、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 PONG`gateway.submit.commands`为`pending=0、lag=0`7个通道TPS权威配置存在。两个active上游通道均为`connected/currentConnections=1`disabled通道的一条`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 新增 `CmppInboundLongMessage`、`CmppInboundLongMessageSegment` 及 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`)
- 功能提交 `b29576fcd118bea04416be0c9fc1bc2a4213d830``fix: reassemble inbound CMPP long messages`)已推送至 `origin/main`。首次 `git push` 遇到远端 HTTP `Failed to authenticate user`,在不改写提交和工作区的情况下使用原命令重试成功;提交未包含 `api/tsconfig.build.tsbuildinfo`、`outputs/` 和未关联的 `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 --check` 和 `npm 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 齐全;`CmppInboundLongMessage` 和 `CmppInboundLongMessageSegment` 两张表存在,发布后尚无长短信分组数据。`.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 PONG`gateway.submit.commands` 为 `pending=0、lag=0`10 个 `rate:gateway:channel:config:*` TPS 权威配置键存在,Prisma migration status 为最新。
- 5 条 active 上游通道在重启后的真实结果为 3 条 `connected/currentConnections=1``CH-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新增`lastReconnectAttemptAt`、`nextReconnectAt`、`lastErrorCategory`和`status + 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 条 migration`prisma 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.tsbuildinfo` 和 `outputs/` 按发布规则排除。
- 发布前 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:phase8`15000 条消息入队 3679.70 TPS,提交结果与回执完整闭环 549.52 TPS,达到 500 TPS 门槛;临时 Redis 已停止。
- 预发布部署前只读基线:`.deployed-commit=b29576fcd118bea04416be0c9fc1bc2a4213d830`,服务器 4 核、7499MB 内存、可用内存 6519MB、负载 0Gateway/API/Nginx/PostgreSQL/MinIO 正常,Redis `PONG`,发送 Worker 并发 50`gateway.submit.commands` 为 `pending=0、lag=0`。实际发布、备份、迁移、服务重启和预发布 TPS 结果待部署后补记。
## 2026-07-24 供应商连接恢复、运营整改与安全依赖合并发布(`afd3c960`)
- 合并提交 `afd3c960709b1660c18d028499c811321983cb22``feat: improve channel resilience and operations`)包含 43 个文件、1969 行新增和 299 行删除,已推送至 `origin/main`。第一次 push 仍遇到 Git HTTP 鉴权失败,未改写提交或 remote,直接重试后成功;`api/tsconfig.build.tsbuildinfo` 和 `outputs/` 未纳入提交。
- 部署前 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_schedule`、`20260723223000_default_application_task_phone_limit`、`20260723224000_add_report_submission_unknown_units`、`20260723225000_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 匹配均为 0`gateway.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 回执缺失复核与通讯交互日志(本地未提交、未部署)
- 预发布只读复核确认当前仍部署`afd3c960709b1660c18d028499c811321983cb22`。`13127620092`今日两次提交经“赛邮行业-王斯评中转”获得上游Msg_Id后停留submitted;该通道最后一条回执为2026-07-21 17:39:58(北京时间)。`18821203795`今日09:26“富泷物业-移动”测试提交上游Msg_Id `736025035345047554`5分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`事件的`received`和`failed`两条记录,失败耗时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..372`和`x=18..357`,控制台均为0条error/warn;截图保存在`outputs/protocol-interaction-logs/`。
- 当前改动保持未提交、未推送、未部署。预发布尚无新通讯日志表和页面,后续发布前必须执行备份、migration、Gateway先于API重启及发布后真实回执链路观察。
## 2026-07-24 通讯交互日志预发布发布(`0bfeb083`)
- 功能提交`0bfeb0839ee6b67611e13796f46c19fc05b88de9``feat: add protocol interaction observability`)已推送至`origin/main`。首次推送被内部Git服务以`Failed to authenticate user`拒绝,第二次因网络超时且远端未更新,第三次重试成功;提交未包含`api/tsconfig.build.tsbuildinfo`和`outputs/`。
- 发布门禁通过: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=0`、`lag=0`10个`rate:gateway:channel:config:*` TPS配置键存在。
- Gateway重启后5条启用上游通道中3条立即连接,“富泷物业-联通/电信”共享账号`C59748`首次被供应商返回`auth failed`;自动重连按`nextReconnectAt=11:00:58`执行后两条均恢复。最终5/5通道全部`connected/currentConnections=1/desiredConnections=1`,最近心跳持续刷新,`lastError`和`nextReconnectAt`清空。
- 公网首页、运营登录、客户端登录和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_RESP`和`CMPP_DELIVER`,并把每个报文各拆成`received/success`两行;真实下行`CMPP_SUBMIT`与`CMPP_DELIVER_RESP`此前未采集,因此箭头虽符合现有事件入口方向,但不足以表达完整交互并造成重复观感。
- 改为“一条数据库记录对应一个真实业务报文”:NestJS不再为同一入站报文分别写`received`和`success`,只落最终成功或失败结果;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补充供应商`SUBMIT`、`SUBMIT_RESP`、`DELIVER_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`)
- 功能提交`ca12f14b0007ee75f727d18e66791a669838b66e``fix: reconcile shared-channel receipts and protocol logs`)已推送至`origin/main`,首次推送即成功。提交包含另一会话留下的通讯日志方向/去重改动及本轮回执聚合修复;未提交`api/tsconfig.build.tsbuildinfo`和`outputs/`。
- 部署前备份位于`/opt/cmpp-platform/backups/releases/20260724-125251`PostgreSQL gzip 4426218字节、SHA-256 `0ae8714a29f753e4d313179e2471f6bff15d1d7dc996ef57d7052bb7ddd8a61d`;运行源码tar.gz 28655559字节、SHA-256 `40065d00c72273771abf63b430069332351586b02ac2462345eca045997a838c`;环境文件850字节、SHA-256 `189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7`。三份文件权限均为600gzip、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均active`12026/17890/8090/3000/6379/5432/9000`监听,API/Gateway health为okRedis PONG。`gateway.submit.commands`消费者1、`pending=0`、`lag=0`10个通道TPS配置键存在。
- Gateway重启后5条活动供应商通道有4条立即在线,“富泷物业-联通”首次鉴权失败并按数据库`nextReconnectAt=2026-07-24 12:59:31+08`自动慢重试;到13:00只读复核时5/5均为`connected/currentConnections=1/desiredConnections=1`,最近心跳持续刷新、`nextReconnectAt`与`lastError`清空。
- 公网首页、运营登录、客户端登录和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,000`、`10000.2500 → 10,000.25`、`10000.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_uplink`和`client_to_platform + deliver_resp`。通讯日志只描述真实协议报文;`CmppDownstreamDelivery`继续保存排队、发送、ACK、失败和重试业务状态,两者不合并。
- 新增migration`20260724143000_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`)
- 功能提交`e12bdf010e52584288effc626dc3b84a82dbc15f``fix: restore daily operations quality metrics`)已推送至`origin/main`。首次推送遇到内部Git服务瞬时`Failed to authenticate user`,原命令重试后成功;提交未包含`api/tsconfig.build.tsbuildinfo`和`outputs/`。
- 发布前门禁通过: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均active`12026/17890/3000/6379/5432/9000`监听,API health正常、Redis PONG。`gateway.submit.commands`消费者1、`pending=0`、`lag=0`3条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`失败回执并已完成企业侧投递;运营端通道测试`13127620092`、`15821447161`没有企业和应用归属,无需生成客户回执。三者业务结果统一归为“提交失败”,是否存在平台通知回执不再改变列表分类。
- 短信记录列表、CSV、详情和状态筛选按阶段拆分:`submit_failed`或`submitStatus=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.tsbuildinfo`和`outputs/`继续作为既有其他会话/构建产物保留。
## 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`)
- 功能提交`53736c96e817d3310039bcf4cf1d17dfd775c9a4``fix: align daily operations statistics`)已推送至`origin/main`。第一次推送仍被内部Git服务以`Failed to authenticate user`拒绝,保持提交和工作区不变后直接重试成功;`api/tsconfig.build.tsbuildinfo`和`outputs/`未纳入提交。
- 部署前PostgreSQL、运行源码和环境配置备份至`/opt/cmpp-platform/backups/releases/20260724-220938-before-53736c96`。数据库、源码、环境文件SHA-256依次为`e48700dee4dfbf4b1e9f66f8eb6e5b9ede8698d6aeedd01d87e5638e35e9747e`、`eca2a1a33dccc6d5bac9cee5bda55a8bc342845831e8609067e4ee6462784000`、`189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7`;权限、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秒、API`npm ci`约6秒;其余约25秒用于Prisma生成/迁移检查、前端/API/Gateway构建、管理员检查、systemd重启和固定3秒健康等待。当前每次发布都执行两次干净依赖安装、三套完整构建、备份/校验及发布后验收,因此用户感知的总耗时显著高于34秒的服务端脚本本身。
- 发布后Gateway、API、Nginx、PostgreSQL和MinIO均activeRedis PONG`12026/17890/8090/3000/6379/5432/9000`均监听,API/Gateway health正常。`gateway.submit.commands`消费者1、`pending=0`、`lag=0`3条active供应商通道均为`connected/currentConnections=1/desiredConnections=1`API、Gateway和Nginx自发布以来关键错误匹配为0。
- 直接调用已部署的真实`OperationsService`及PostgreSQL验证新SQL`2026-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.tsbuildinfo`、`outputs/`及未跟踪空文件`=`保持隔离,未纳入本次修改。
## 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.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`及未跟踪空文件`=`继续作为既有构建/临时产物隔离。
## 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修改提交`0857de09d82aec7233108fb6700c40a6183c21f8``fix: harden channel retry attribution and operations UI`)已推送至`origin/main`;首次推送被内部Git服务瞬时返回`Failed to authenticate user`,保持提交不变后重试成功。构建缓存`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`及临时`outputs/`、空文件`=`未提交。
- 部署前PostgreSQL、运行源码和环境配置备份至`/opt/cmpp-platform/backups/releases/20260726-213641-before-0857de09`SHA-256依次为`a9ec6f5c96f1dcd2f314e4c63e76b1d348f8320f8852667be5c2f7df933488c9`、`01140043ee1c640faa31b870b333771d9c57a6295ffdf0b54637db93321858dd`、`189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7`gzip、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均activeRedis`PONG``12026/17890/8090/3000/6379/5432/9000`均监听,内外健康页及运营/客户端入口HTTP 200,公网CMPP 17890可连接;Redis提交流消费者1、`pending=0`、`lag=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或账务证据,不自动冲正现有余额。
- 新migration`20260726223000_prevent_duplicate_retry_side_effects`为`SmsSubmitRecord`增加唯一`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均activeRedis`PONG``12026/17890/8090/3000/6379/5432/9000`监听,内外健康页、运营端和客户端入口HTTP 200,公网CMPP 17890可连接,发布后API/Gateway无error级日志。
- 四个启用通道均为`connected/currentConnections=1/desiredConnections=1`Redis提交流消费者1、`pending=0`、`lag=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.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`及空文件`=`属于既有构建/临时产物,不纳入源码提交。
- 功能提交`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=94aeacd3a20b4c838c59d67ba86ef466ff49ce03`API、Gateway、Nginx、PostgreSQL、MinIO均activeRedis`PONG``12026/17890/8090/3000/6379/5432/9000`监听,内外页面和健康接口HTTP 200CMPP 17890可连接,Redis Stream消费者1、`pending=0`、`lag=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`通过。
- 功能提交`df70b336a038fafab6afdcf24f1d35b7ade50744``fix: align signature review and admin operations`)及部署加固提交`7c1a0287a0b68e6f3ecdbd16243dd05bb8a263e1``chore: harden preproduction deployment`)已推送至`origin/main`。第一次功能提交推送被内部Git服务瞬时返回`Failed to authenticate user`,保持提交与工作区不变后重试成功;既有`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`及空文件`=`未纳入提交。
- 精确Git归档共441个文件、5939200字节,本机与服务器SHA-256均为`dcbdf236e1fbe0ecf6da87c3b5306f805661a5d35f89edbc466a00287b8da56f`。部署前数据库备份为`/opt/cmpp-deploy-backups/cmpp-20260727-221003-before-df70b336.sql`SHA-256 `cfc75e2a388454ec9f3a0b30ff14719c34e8cd8ff39908c7cf0eaac1f5a521a3`),环境备份为`/opt/cmpp-deploy-backups/cmpp-env-20260727-221003-before-df70b336.env`SHA-256 `189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7`),旧运行目录保留为`/opt/cmpp-platform.previous-20260727-221003`。
- 标准部署脚本完成依赖安装、安全门禁、Prisma生成和migration、前端/API/Gateway构建;新migration`20260727113000_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.sql`SHA-256 `64c23d625e606bb4a90d0fd6335472775a88c4ec7a107269684120cce1864ea3`)和`/opt/cmpp-deploy-backups/cmpp-env-20260727-221934-before-7c1a0287.env`SHA-256 `189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7`),旧运行目录保留为`/opt/cmpp-platform.previous-20260727-221934`。空快照环境下脚本自行创建`logs/api`和`logs/gateway`且一次启动成功,74条migration无待执行项,证明修复闭环。
- 部署后真实数据库直接验证待审核签名`【安徽航天信息】`返回`allowedActions=["approve","reject"]`、`blockedReasons=[]`且配置必填字段数为0,证明不再套用旧固定资格项。`SmsSubmitRecord`共530条,其中512条已回填通道组ID及名称;剩余18条无法唯一归因的测试或历史提交保持空值,未伪造归因。真实`OperationsService`可返回当天charged计费企业消费排行(首位“启瑞中转企业”77220内部计费单位)及包含`acceptedCount/submitFailureCount`的签名统计。
- `.deployed-commit=7c1a0287a0b68e6f3ecdbd16243dd05bb8a263e1`API、Gateway、Nginx、PostgreSQL、MinIO均activeRedis`PONG``12026/17890/8090/3000/6379/5432/9000`均监听。Gateway重启后3个客户CMPP账号因旧进程连接行尚在90秒心跳期限内首次重连收到连接数限制,超时清理后均由客户端自动重连成功,最终4个客户CMPP应用均有实时心跳;4个启用供应商通道也全部恢复`connected/currentConnections=1/desiredConnections=1`。Redis Stream消费者1、`pending=0`、`lag=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 保持兼容,不迁移历史文件。
- 利润报表成本改为“提交时通道成本单价快照 × 该次提交成功短信分片数”。新数据优先按 `SmsMessageSegmentAudit` 中 `receiptStatus=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`时无条件拒绝执行,预发布部署不会写入演示数据。
- 发布前重新确认`HEAD`与`origin/main`均为`352a6293b47f95653fbb079f2cf528fba4d59818`,工作区修改来自前序多个会话,按用户明确要求统一归入本次发布;`outputs/`、空文件`=`、`api/tsconfig.build.tsbuildinfo`和`tsconfig.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`异步句柄提示。
- 汇总功能提交`99c8c7c68b5eb7cd0f63f0c70d376c257cc18c61``feat: 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-99c8c7c6`SHA-256依次为`9c3fee92363483ba78a43bd24173acfd1ccfc37aee39ccdd7da84df8043e340f`、`3ef84c58775c0dbf90b7e0b8c19e1caac8350afbef214e49d6dde91ec1bc1e49`、`189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7`gzip、tar和`sha256sum -c`全部通过;旧运行目录保留为`/opt/cmpp-platform.previous-20260728-203034`。
- 标准部署脚本完成两套`npm ci`、依赖安全门禁、Prisma生成、前端/API/Gateway构建及Gateway先于API重启;新migration`20260728153000_stage_report_material_import_reviews`应用成功,预发布共75条migration。演示企业计数为0,证明本地签名质量演示脚本未执行、未写入预发布数据。
- 部署后`cmpp-api`、`cmpp-gateway`、Nginx、PostgreSQL和MinIO均activeRedis`PONG``12026/17890/8090/3000/6379/5432/9000`均监听,API/Gateway health、公网首页、运营端、客户端和API health均HTTP 200,公网CMPP 17890 TCP可连接。Redis Stream消费者1、`pending=0`、`lag=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.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`及空文件`=`继续保留且不纳入代码提交。
## 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生产构建、Gateway`go test ./...`与`go vet ./...`、依赖安全门禁和`git diff --check`通过;Vite仅保留既有大chunk提示,Jest保留既有`--forceExit`异步句柄提示。
- 应用内浏览器接管检查确认当前没有已登录运营会话,目标路由被真实鉴权守卫跳转至图形验证码登录页;未绕过验证码,因此发布前未把登录页冒充为两个页签的视觉验收。发布后仍需在有效运营会话下复核两页签桌面和平板宽度。
## 2026-07-28 `95c052e9` 预发布记录
- 功能提交`95c052e9ea987f58c34002543331c2b75f36c642``fix: 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-95c052e9`SHA-256依次为`637d39d2c34a7aa888584b745797e34f966e14508bd1e95930fa7aaa9df97b46`、`33519dae970b725a603d71fd24cb3c6ea917652de2fb8f4962386ec968c73e13`、`189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7`;旧运行目录保留为`/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=95c052e9ea987f58c34002543331c2b75f36c642`API、Gateway、Nginx、PostgreSQL、MinIO和Redis均active`12026/17890/8090/3000/6379/5432/9000`均监听,API/Gateway health与Redis PONG通过。`gateway.submit.commands`消费者1、`pending=0`、`lag=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.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续视为构建/临时产物,不纳入提交。
## 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依次为`ea6471078f202f3115a7dc839dc57f96e4d535f7390cbb6a76b0ccfe742442b9`、`eee5bc85d6ad3bd52f163a68634a48ef8003b9498b687b0b354095000926c259`、`189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7`。
- gzip修正归档1794162字节,本地与服务器SHA-256均为`1c05f83affdbf7388d665cbfe241c497606dd293f54e2aa01026e62ed56bd803`。修正发布前备份位于`/opt/cmpp-platform-backups/releases/20260728-232640-before-fbacb745`PostgreSQL、运行源码和环境文件SHA-256依次为`2018116642f58ebd9af961cd989d54b1f70a8ccaaf8e5fa0d279b5819b068bc6`、`01d9ca07994188205006f40489d6349b2672c438d11653d96ea1bbc6ae084801`、`189f4f67e9d52f3c1ce751d1005c08667b1b4efcd0c576aaa5ad3249c822e4e7`。
- 标准`tools/deploy/production-deploy.sh`完成依赖安装、安全门禁、Prisma、前端/API/Gateway构建和Gateway先于API重启。新migration`20260728223000_optimize_list_pagination`应用成功,预生产共76条migration且无待执行项。
- 发布后真实`OperationsService`在与问题复现相同的`2026-07-27`至`2026-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均active`12026/17890/8090/3000/6379/5432/9000`监听;内外健康接口、首页、运营端和客户端均HTTP 200,公网CMPP 17890可连接。Redis Stream消费者1、`pending=0`、`lag=0`API/Gateway近10分钟error级journal为0。
- 4条active供应商通道均为`connected 1/1`;最近120秒活跃下游客户连接为0。本轮未发送、重投或补发真实短信,未修改通道账号、密码、启停状态、企业余额或客户连接。
## 2026-07-29 企业应用列表 Prisma 字段回归修复(发布前)
- 预生产企业应用页面和企业应用黑名单页面 HTTP 500 已定位为列表查询 `omit` 错误引用 DTO/响应别名 `passwordCipher`;真实 `SmsApplication` 模型只保存敏感字段 `secretHash`Prisma 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.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/` 和空文件 `=` 继续作为构建或临时产物保留,不纳入提交。
## 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`、本地 `HEAD` 与 `origin/main` 均为 `500f43f673408900c3d658051d67cf0602f6005a`。工作区中不同会话形成的上述有效源码、测试和文档统一纳入本次授权范围;`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/` 和空文件 `=` 继续作为构建缓存或临时产物排除。
- 预生产只读基线确认 `.deployed-commit=500f43f673408900c3d658051d67cf0602f6005a`76 条 migration 已应用且与源码目录一致。API、Gateway、Nginx、PostgreSQL、Redis、MinIO 均 active`12026/17890/8090/3000/6379/5432/9000` 监听,内外健康接口和首页、运营端、客户端均 HTTP 200。
- 发布前 Redis Stream `gateway.submit.commands` 消费者 1、`pending=0`、`lag=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` 预生产发布记录
- 功能提交 `c0a4317a7ea641bab39294e596f58f859edfca73``feat: 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`。三份文件权限为 600gzip、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 均 active`12026/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=0`、`lag=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:41``01:50:42`,正确北京时间为 `09:19:41``09: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_review`的`SmsBatchTask`。这些独立查询与原 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.mjs` 和 `docs/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.json`和`tools/quality/verify-admin-api-r1.mjs`。门禁确认183个运营端方法、60个客户端方法、7个会话方法及9个HTTP核心函数的实现哈希与拆分前一致,同时确认`adminApi`、`clientApi`、`portalSessionApi`和`fileDownloadUrl`稳定导出仍存在;R0门禁继续通过。
- Node.js v24.16.0下前端TypeScript检查及Vite v8.0.16生产构建通过,2456个模块完成转换;API全量28 suites / 381 tests、API TypeScript正式构建、Gateway`go 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.json`和`tools/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生产构建、Gateway`go 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.ts``SmsConfigModule`仍只注册并导出稳定门面,不扩大NestJS provider图。
- 新增`docs/contracts/sms-config-r3-methods.json`和`tools/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生产构建、Gateway`go 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.json`、`docs/contracts/admin-enterprise-signatures-r4.json`、`tools/quality/verify-report-materials-r4.mjs`和`tools/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生产构建、Gateway`go 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.ts`。`ChannelsModule`仍只注册并导出稳定门面,没有扩大NestJS provider图。
- 新增`docs/contracts/channels-r5-methods.json`和`tools/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生产构建、Gateway`go 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.ListenAndServe`、`DisconnectAccount`、`PushReceiptWithResult`和`PushUplinkWithResult`等公开入口、`cmd/gateway`及控制服务调用方式保持不变。
- 原实现按登录认证、Submit与报文转换、下游会话注册、回执/上行Deliver、ACK追踪与SubmitResp顺序屏障、待投递恢复扫描、协议日志、共享HTTP传输八个职责迁移到9个聚焦文件。现有`presence.go`和`recovery.go`保持原样;没有跨package改接口或形成新的运行时依赖。
- 新增`docs/contracts/inbound-r6-declarations.json`和`tools/quality/verify-inbound-r6.go`。门禁逐项确认迁移前93个声明的文件归属和实现哈希一致,并锁定稳定启动入口、控制服务三个调用入口及12项关键协议测试。SubmitResp先于排队回执、会话唯一所有权、原始Msg_Id恢复和多实例恢复锁等复杂边界补充了原因注释,没有改写实现。
- 入站定向测试32项全部通过;Gateway`go 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.Submit`、`ConnectChannel`、`DisconnectChannel`和`ConnectionState`等公开契约,以及`cmd/gateway`、控制服务和Submit Worker调用方式保持不变。
- 原实现按Manager与连接池注册、连接池生命周期、物理连接与读循环、重连状态机、窗口/心跳、Submit与分片、回执/上行Deliver、协议日志、ConnectionState与API回调九个职责迁移。既有`long_message.go`已独立承担长短信拆分和上行组装,本轮保持原样。
- 新增`docs/contracts/upstream-r7-declarations.json`和`tools/quality/verify-upstream-r7.go`。门禁按接收者类型分别确认迁移前68个声明的文件归属和实现哈希一致,避免混淆连接池与物理连接的同名方法;同时锁定Manager稳定入口、控制服务调用、既有长短信函数及15项关键状态机测试。
- 为慢鉴权重连、手工断开停止条件、每连接窗口所有权、长短信逐分片结果、未决提交唤醒和回执tracker等复杂边界补充原因注释,未修改业务实现、常量或时序。
- 上游定向测试18项全部通过;其中本地重连集成测试使用真实TCP监听模拟供应商端点,先确认连接失败,再启动端点并验证自动恢复连接。Gateway`go 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.json`和`tools/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生产构建、Gateway`go test ./... -count=1`与`go 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.json`和`tools/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生产构建、Gateway`go test ./... -count=1`与`go 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提交域依赖方向、既有测试替换点和调用可观察性。日志上下文继续使用`SendChainService`NestJS模块仍只注册稳定门面。
- 新增`docs/contracts/send-chain-r10-completion.json`和`tools/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生产构建、Gateway`go test ./... -count=1`与`go vet ./...`、依赖安全门禁、R0R10全部结构门禁及`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.css``global.css`从12270行缩减为11800行;共享给通道组的`.channel-confirm`保留全局,375px下连接摘要规则随页面迁移。`main.tsx`的tokens/global/components加载顺序未变。
- 新增`docs/contracts/admin-channels-r11.json`和`tools/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正式构建、Gateway`go test ./... -count=1`与`go vet ./...`、依赖安全门禁、R0R11全部结构门禁及`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.css``global.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.json`和`tools/quality/verify-admin-sms-task-progress-r11.mjs`,门禁确认164行文本入口、六个聚焦模块、全部真实API边界、十一项交互文案、专属/共享样式归属和375px详情布局。入口物理行数为163,门禁按末尾换行计为164,均低于220行上限。
- 本地应用内浏览器使用已存在的真实运营账号会话,解锁后真实API返回1条客户批量任务`BT-1783075838138-a886dd56`。不存在批次号查询返回真实空列表,重置再查询恢复1条;详情展示2个号码、2条计费、中国移动2个和未识别省份2个;号码列表真实返回`13800138000`、`13900139000`,按`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正式构建、Gateway`go test ./... -count=1`与`go vet ./...`、依赖安全门禁、R0R11全部结构门禁及`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`调用保持:`listOperationMessages`、`listTenants`、`listEnterpriseApplicationOptions`、`listMessageSegmentAudits`和`exportOperationMessages`。默认昨日到今日、提交失败覆盖、平台失败回执说明、运营端测试说明、通道尝试排序、发送接入号拼接和分片审计排序均保持原实现;没有引入barrel、mock、静态列表或localStorage。
- 将短信记录筛选、卡片、状态、详情、通道路由、分片审计和900px/780px响应式规则迁入433行`AdminSmsRecordsPage.css``global.css`从11527行缩减为11098行。多个运营页面共享的`.template-modal-title`、`.muted`和`.ui-table__empty`保留全局。
- 新增`docs/contracts/admin-sms-records-r11.json`和`tools/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;该用例定向重跑通过,随后Gateway`go test ./... -count=1`与`go 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.css``global.css`从11098行缩减为10881行。共享筛选、确认文案、弹窗标题、堆叠和表单布局继续保留全局。
- 窄屏视觉初检发现页面CSS后加载可能覆盖原全局780px筛选单列规则;在页面CSS显式恢复该规则并加入结构门禁。修正后375×812视口实测页面宽度375px、文档滚动宽度375px,筛选区单列、两个输入均未造成页面级横向溢出。这是拆分阶段发现并修复的样式加载顺序风险,未进入提交或部署。
- 新增`docs/contracts/admin-enterprise-applications-r11.json`和`tools/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正式构建、Gateway`go test ./... -count=1`与`go vet ./...`、依赖安全门禁、R0R11全部结构门禁和`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 → AppRoutes`。`global.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.json`和`tools/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正式构建、Gateway`go test ./... -count=1`与`go vet ./...`、依赖安全门禁、R0R11全部结构门禁和`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.json`和`tools/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`口径获得全量通过并保留开放句柄提示。Gateway`go test ./... -count=1`与`go 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.tsx`的`tokens → reset → shell → global → components → AppRoutes`顺序不变。新增`docs/contracts/shared-components-r11.json`和`tools/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、Gateway`go test ./... -count=1`与`go 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.json`和`tools/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、Gateway`go test ./... -count=1`与`go vet ./...`、依赖安全门禁、全部17个R0R11结构门禁和`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.tsx`和`ClientBillingPage.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.json`和`tools/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、Gateway`go test ./... -count=1`与`go 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`,本地分支为`main``HEAD`与`origin/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结构门禁全部通过;Gateway`go test ./... -count=1`、`go vet ./...`、依赖缓解安全门禁和Git差异检查通过。
- `api/tsconfig.build.tsbuildinfo`、根目录`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续作为构建缓存或临时产物保留在本地,不纳入提交、不删除、不错误归因。未发送、重投或补发真实短信,未修改真实通道账号、密码、启停状态、企业余额或客户连接,本轮明确不部署。
## 2026-07-31 `ca4f591a` 工作区汇总提交记录
- 业务功能、两条migration、R0-R11渐进式拆分、结构契约、测试脚本和同步文档已形成提交`ca4f591a``feat: add phone frequency controls and modularize codebase`),共216个文件、46214行新增、28329行删除。
- 提交继续排除`api/tsconfig.build.tsbuildinfo`、根目录`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`;这些本地缓存及临时产物未删除。本文档记录将单独提交并与功能提交一同推送到`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=4b9127e1abb78e8ca858fb67d8f4f09d453a3819`、`origin/main=0af671b4ed4713912e703defd08791f164d4eb25`,远端仍为本地祖先且不存在分叉。
- 第二次执行`git push origin main`成功,远端`main`从`0af671b4`快进到`4b9127e1`,功能提交`ca4f591a`、验证记录`461a65f8`和认证阻塞记录`4b9127e1`均已到达远端。首次失败属于凭据助手当时提供的认证状态被服务器拒绝,重试时已取得有效凭据,不涉及代码、分支或合并冲突。
- 本次只提交和推送代码,没有执行部署;预发布环境运行版本、服务、数据库migration、Redis Stream、供应商通道和客户连接均未改变。
## 2026-07-31 `37ffce40` 预生产发布记录
- 用户明确授权发布到预生产。发布前重新执行`git status --short --branch`、`git diff`、`git fetch --prune`并分别核对`HEAD`与`origin/main`,确认二者均为`37ffce40b274e218e6e64210ac9f0f4db88106c8`。工作区仅保留既有`api/tsconfig.build.tsbuildinfo`、根目录`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`,均未纳入发布、提交或删除,也未发现其他会话新增的未知业务修改。
- 发布前预生产`.deployed-commit=c0a4317a7ea641bab39294e596f58f859edfca73`,数据库共76条migrationAPI、Gateway、Nginx、PostgreSQL、Redis、MinIO均为active,目标端口均监听,Redis返回`PONG`Stream消费者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_controls`和`20260730114500_add_phone_frequency_whitelist`均已应用;预生产现有78条migrationPrisma确认数据库schema up to date`PhoneFrequencyHit`、`PhoneFrequencyState`、`PhoneFrequencyWhitelist`三张新表存在。
- 发布后`.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返回`PONG``gateway.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.tsx`在`RealseV2.0/c0a4317a`至`37ffce40`之间无差异,本次缺少成功反馈不是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=deleted``OperationLog`存在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 diff`、`git fetch --prune`并分别核对`HEAD`与`origin/main`,二者均为`ecc3d7a5045b7669d102f4c81cd2f011b207b3b5`且无分叉。`RealseV2.0`注解标签仍指向`c0a4317a7ea641bab39294e596f58f859edfca73`,既定代码回滚基线有效。
- 发布前预生产实际运行`37ffce40b274e218e6e64210ac9f0f4db88106c8`,源码与数据库均为78条migration。API、Gateway、Nginx、PostgreSQL和MinIO为activeRedis实际端口监听且返回`PONG``gateway.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);Gateway`go test ./... -count=1`和`go vet ./...`、19个Node结构门禁、2个Go结构门禁、依赖缓解安全门禁及`git diff --check`全部通过。Jest仅保留既有`--forceExit`开放句柄提示,Vite仅保留既有约2.01MB单chunk提示。
- `api/tsconfig.build.tsbuildinfo`、根目录`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续作为构建缓存或临时产物排除,不提交、不删除、不错误归因。发布和验证过程禁止发送、重投或补发真实短信,禁止修改真实通道账号、密码、启停状态、企业余额或客户连接。
## 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均为active`redis-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返回`PONG``gateway.submit.commands`消费者组为`cmpp-gateway`,消费者1、pending=0、lag=0、entries-read=3047。部署后约95秒内API/Gateway error级journal均为0,关键字检查无`panic/fatal/unhandled/exception/error`120秒内活跃下游客户连接为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.tsbuildinfo`、`outputs/`和空文件`=`继续保留且不纳入本轮归因,未发送短信、修改余额、通道配置或客户连接。
## 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`。migration`20260803190000_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_TIMEOUT`HTTP建立一个失败Webhook,CMPP为每个请求回执的原始分片建立失败状态报告。只有全部应建投递持久化后才写`timeoutReceiptQueuedAt`;建单中断时下一轮扫描继续补齐,退款仍由原消息级幂等键保证一次。
- 验证结果:Prisma format、validate、generate和API TypeScript正式构建通过;新增逐片目标/Registered_Delivery/HTTP超时及中断恢复测试后,定向3 suites / 117 tests、API全量32 suites / 407 tests通过,保留既有Jest开放句柄`--forceExit`提示及预期场景日志。Gateway`go test ./... -count=1`与`go vet ./...`通过,并新增不同原Sequence_Id生成不同回执Msg_Id的专项测试。
- 本轮没有修改或清理工作区中既有的引流识别、审核筛选、查询布局和其他会话修改;构建缓存、`outputs/`和空文件`=`继续保留。代码按用户要求未提交、未推送、未部署;没有发送、补发或重投短信,没有修改预生产数据库、企业余额、通道配置或客户连接。
## 2026-08-03 跨会话工作区整合与提交前完整回归
- 汇总当前工作区全部有效修改后,组合范围确认为四组:客户端今日消费与运营统计、审核日期和共享查询布局、引流信息识别与统计、CMPP逐分片回执及72小时超时失败回执。3条新增migration按`20260803113000`、`20260803140000`、`20260803190000`顺序衔接;本地真实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和插件耗时提示。
- Gateway`go test ./... -count=1`和`go 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.tsbuildinfo`、`outputs/`和空文件`=`继续作为构建缓存或临时产物排除,不提交、不删除、不错误归因。本轮未部署、未发送/补发/重投短信,也未修改预生产数据库、企业余额、通道配置或客户连接。
## 2026-08-03 `530a65de` 预生产发布记录
- 用户明确授权发布最新代码。发布前重新执行`git status --short --branch`、`git diff`、`git fetch --prune`并核对`HEAD`与`origin/main`,确认二者均为`530a65de809a1d2dee7000642bc99c1e483c15f6`。工作区仅保留既有`api/tsconfig.build.tsbuildinfo`、根目录`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`,没有把构建缓存或临时产物纳入发布,也未发现待提交的业务代码。
- 发布前预生产`.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_detection`、`20260803140000_fix_default_drainage_detection_rule_patterns`和`20260803190000_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返回`PONG``gateway.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` 直连源站使用可信 Lets Encrypt 证书并返回 200。
- 本轮服务器配置备份位于 `/opt/cmpp-platform-backups/config/20260805-100601-cloudflare-origin-restriction`、`20260805-102234-api-letsencrypt`、`20260805-102550-sms-aop` 和 `20260805-102614-http-api-origin-env`。未修改防火墙、安全组、CMPP 17890、短信数据、通道、余额或客户连接;业务代码保持未提交、未推送、未部署,生产环境变量已预置但需代码发布后页面才会展示新的公网 API 地址。
## 2026-08-05 旧 IP:12026 登录短时过渡与撤销(已恢复 HTTPS-only,未提交)
- 真实故障确认为 HTTPS 切换后服务器设置 `SESSION_COOKIE_SECURE=true`API 发送的 Secure 会话 Cookie 无法被 `http://8.160.169.106:12026` 接收;因此登录接口成功后,受保护页面恢复会话失败并重新跳回登录页。
- 为保留旧 IP 登录入口,预生产环境临时改为 `SESSION_COOKIE_SECURE=false` 并只重启 `cmpp-api.service`。进程环境已确认读取 `false`,API 服务 active 且重启后无 error 级 journal;IP 首页、运营登录页和健康接口均返回 200`sms.lisglo.com` 经 Cloudflare/AOP 的健康接口及 `api.lisglo.com` 健康接口也均返回 200。
- 该短时方案保留了 `HttpOnly`、`SameSite=Lax` 和运营/客户端独立 Cookie,但 HTTPS 入口也会使用非 Secure 的过渡期 Cookie,已有登录用户可能需要重新登录;用户随后决定不接受该长期代价。临时调整前的配置备份位于 `/opt/cmpp-platform-backups/config/20260805-105501-ip-login-cookie-compat`。
- 用户复核安全代价后决定不再保留 IP 直接登录,也暂不新增灰云管理域名证书。预生产已于 11:04 将 `SESSION_COOKIE_SECURE` 恢复为 `true` 并只重启 API;进程环境确认读取 `true``sms.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`及migration`20260806100000_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到本地或预生产数据库,未连接预生产、未发送/补发/重投短信,未修改真实通道配置、账号密码、启停状态、企业余额或客户连接;代码按要求保持未提交、未推送、未部署。`*.tsbuildinfo`、`outputs/`和空文件`=`继续作为其他会话/构建产物保留,不删除、不提交、不归因。
## 2026-08-06 `RealeseV2.3` 工作区合并与推送前验证
- 用户授权将当前工作区全部有效业务代码合并、提交并推送,版本名称按用户给出的精确拼写定为`RealeseV2.3`。合并范围包括:HTTPS双域名与HTTP API公网地址、运营端待审核角标轻量轮询、供应商长短信整条级成功回执及网关异常双Tab;三组需求、测试、部署说明和进度记录均随代码纳入。
- `git fetch --prune --tags`后本地`HEAD`与`origin/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=1`与`go vet ./...`19个`.mjs`结构门禁、R6/R7 Go结构门禁、依赖缓解安全门禁和`git diff --check`。Vite仍只有既有大chunk警告,Jest仍使用`--forceExit`结束既有开放句柄。
- 提交范围排除`api/tsconfig.build.tsbuildinfo`、根目录`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`;这些缓存或临时产物继续保留在工作区,不删除、不提交。本轮未连接或修改生产/预生产服务、数据库、通道、余额或客户连接,未发送、补发或重投真实短信。
## 2026-08-06 `RealeseV2.3` 预生产发布记录
- 发布目标为annotated tag`RealeseV2.3`对应提交`8ad8e6179305f7be3046fc761826c6f1c1b9e4c2`。发布前预生产`.deployed-commit=530a65de809a1d2dee7000642bc99c1e483c15f6`,数据库81条migrationAPI、Gateway、Nginx、PostgreSQL、Redis、MinIO均active,关键端口全部监听,API/Gateway health与Redis PONG通过。5条active供应商通道均为`connected 1/1`,最近120秒客户下游连接为0Redis Stream消费者1、`pending=0`、`lag=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 date`SmsReceiptAnomaly`表存在,发布时记录数为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/1`Redis Stream仍为消费者1、`pending=0`、`lag=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_LOCKED`2026-08-09 11:10:45运营端登录成功后,前端在11:10:47立即请求`/auth/session/lock`11: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-014`至`TC-AUTH-016`仍需代码发布后在预生产使用真实会话复测。
- 本轮未提交、未推送、未部署,没有发送、补发或重投真实短信,没有修改数据库、企业余额、真实通道配置或客户连接。既有`api/tsconfig.build.tsbuildinfo`、根目录`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续保留,不删除、不提交、不归因。
## 2026-08-09 签名删除预检与多通道报备汇总修复(本地未提交)
- 删除预检现已将`approved`、`abandoned`等报备终态排除在“未结束报备任务”之外;预生产只读核对的三条任务`cmrxc3rgk004017nks1bktp9n`、`cmrxc3rgo004217nkw9enwk72`、`cmrxc3rgr004417nk887sg9ef`均为`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`已删除,既有`tsbuildinfo`、`outputs/`和空文件`=`仍受保护。
## 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`通过。
- 本步骤只修改前端展示、共享色阶工具及需求/用例/进度文档,没有修改后端、数据库或真实统计接口,没有连接预生产、发送/补发/重投短信,也没有修改真实通道、企业余额或客户连接。代码按要求保持未提交、未推送、未部署;其他会话和前一步已有修改、`tsbuildinfo`、`outputs/`及空文件`=`继续保留并保护。
## 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=1`及`go 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`字段及migration`20260809130000_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/reconciliation`、`profit`和`quality`在原有分页响应中新增`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=1`及`go 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.tsbuildinfo`、`outputs/`和空文件`=`未提交、未删除。
- 精确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条已完成migration`ProtocolInteractionLog.phoneNumber`字段存在;最终`.deployed-commit=4724b9db6a99bec15350e37978d3fb165ee74bb9`。
- 部署后API、Gateway、Nginx、PostgreSQL、MinIO均activeRedis PONG,内部API/Gateway/MinIO健康通过,无failed systemd unit。公网运营登录、客户端登录、API health和客户Swagger`/api/client-docs`均为200API专用域名根路径、管理页面和管理API均为404,公网CMPP 17890纯TCP连通。Redis Stream消费者1、`pending=0`、`lag=0`17个通道TPS配置键存在。
- 新通道组删除影响接口已出现在部署后Swagger路径中,未认证访问返回401;前端生产包包含“等待供应商提交结果”和历史数据保留完整文案。对真实PostgreSQL最近三个活动通道组只读执行同口径统计,均得到正常应用2、已删除应用0、组内通道3、等待供应商提交0;没有点击或调用确认删除。现有浏览器无登录会话,未绕过验证码或伪造登录态,登录后UI弹窗交互仍可作为后续人工验收项。
- 发布前数据库状态为9条active通道、连接状态9条connected;重启后6条active通道恢复`connected 1/1`3条富泷通道返回供应商`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`,子对象另写操作日志。通道删除后,同事务按剩余未删除通道重算受影响签名报备汇总;活动通道组、直接路由、活动连接及关联模板的活动发送任务仍保持硬阻断。
- 修正模板活动任务终态口径:`SmsSendTask`的`approved/rejected`和`SmsBatchTask`的`finished/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.tsbuildinfo`、`outputs/`和空文件`=`继续保护,不归因、不删除、不提交。
## 2026-08-09 级联删除治理预生产发布记录(`7804f64c`)
- 级联删除治理9个有效源码、测试和文档文件提交为`7804f64ced19435b15b981d2fcb7f8c7e934e33f`并推送`origin/main`;首次推送因远端认证失败,使用既有Git凭据助手安全重试后成功。构建缓存`api/tsconfig.build.tsbuildinfo`、根目录`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`未提交、未删除。
- 精确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=0`、`lag=0`API和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-001`至`007`,当前均为“暂缓、未执行”,不计入现版本通过率,也不得作为现有系统Bug;本步骤未连接或修改预生产数据库,未修改通道账号、密码、启停状态、企业余额或客户连接,未发送、补发或重投真实短信。
## 2026-08-09 通道组按通道筛选(本地未提交)
- 运营端“短信通道组管理”新增“通道”可搜索下拉筛选。页面首次加载并行请求真实`GET /api/admin/channel-groups`和`GET /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.tsbuildinfo`、`outputs/`和空文件`=`未提交、未删除。
- 发布前删除治理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,备份和校验单为0600gzip、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=0`、`lag=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=0`、`lag=0`;运行目录切换仅停止并按Gateway、API、Nginx顺序重启服务。
- 回滚后API、Gateway、Nginx、PostgreSQL和MinIO均为activeRedis PONG,内部API/Gateway健康通过;公网运营登录、客户端登录及API health均为HTTP 200,发布后API/Gateway无error级journalRedis Stream继续为`pending=0`、`lag=0`。
- 9条active供应商通道回滚重启后6条为connected;“会员营销-富泷”“移动物业-富泷”“联电物业-富泷”3条恢复为此前已记录的供应商`connect response status: auth failed`状态。本次未修改其连接配置,仅记录真实返回。
- Git使用`git revert --no-commit`反向撤销上述两个提交,不使用`reset`或`checkout`覆盖工作区。恢复后的业务源码、需求文档、测试用例和结构契约与`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-001`至`010`、`TC-SIGNATURE-RETIREMENT-001`至`016`。这些用例当前不计入现版本通过率,也不得被解释为代码已完成或当前系统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.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`不删除、不提交、不归因于本需求。
- 登录后浏览器验收发现并修复历史三网任务弹窗默认把移动、联通、电信全部设为“已通过”的问题。修复后所有运营商默认“请选择”,必须逐项确认,且“已通过”必须填写真实有效通过时间;前端禁用不完整提交,后端不再回退使用历史通道级时间或当前时间伪造运营商通过事实。同步新增`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-1`至`T-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提示。该修正后续已随提交`16135e5a`发布。
## 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、建议280360px并使用`.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.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`不删除、不提交、不归因于本需求。
## 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 PONG`gateway.submit.commands`消费者1、`pending=0`、`lag=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.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续不提交、不删除。
## 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.dump`514656字节,SHA-256=`f776feb92243afb117b648256f630ad826039985030c4fae21ea631f111a20ea`。本地执行后`legacy_channel=0`、`legacy_split=1`、`carrier_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=64`和`legacy_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=0`、`lag=0`,运营端、客户端和公网API health均HTTP 200;部署后API/Gateway error和warning级日志为0,运行源码和前端产物均不存在`legacy-report-tasks`或“历史待确认”标记。
- 9条活动通道重启恢复后6条`connected 1/1`;“会员营销-富泷”“移动物业-富泷”“联电物业-富泷”继续为发布前已知的供应商`authentication`失败。本轮未修改通道账号、密码、启停状态、企业余额或客户连接,没有手工发送、补发或重投短信,也没有修改Webhook。受保护的`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续不删除、不提交、不归因于业务源码提交。
## 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.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续不删除、不提交、不归因于本需求;依赖包装器临时生成的`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`、写`resolvedAt`和`manually_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/`和空文件`=`不归因、不处理。
# 2026-08-12 下游重投、异常处置、未报备签名及运营商标签预生产发布(已发布)
- 最新功能提交`16135e5a3ef69e22011e483e5a74dd8a36699189`已成功发布;精确Git归档`outputs/cmpp-16135e5a-20260812-173616.tar.gz`共834项、2246057字节,本地与服务器SHA-256均为`f4cb42a2ffed9bf4fba1e43656433a6e1b2de5ba2af52bcb0193c9f77ce56c21`。运行目录`.deployed-commit`已核对为该提交。
- 发布前恢复资产位于`/opt/cmpp-platform-backups/releases/20260812-174041-before-16135e5a`PostgreSQL、运行源码和环境文件均通过`sha256sum -c`;上一运行目录保留为`/opt/cmpp-platform.previous-20260812-174041`。部署流程完成依赖安全缓解门禁、Prisma generate/migrate、前端/API/Gateway构建、Nginx校验、服务重启和健康检查,未触发回滚。
- 第86条migration `20260812153000_add_downstream_requeue_tasks`仅应用一次,数据库当前86条已完成migration`DownstreamRequeueTask`与`DownstreamRequeueTaskItem`两张真实任务表均已核对存在。
- API、Gateway、Nginx、PostgreSQL、Redis与MinIO均为active12026、17890、8090、3000、6379、5432和9000端口均监听。内部API/Gateway/MinIO健康通过、Redis PONG`gateway.submit.commands`消费者1、`pending=0`、`lag=0`。公网运营端登录、客户端登录和API health均HTTP 200,公网CMPP 17890 TCP连通,发布后API/Gateway warning级journal为0。
- 依赖审计仍报告根项目3项high、API项目3项moderate和4项high,专用安全缓解门禁通过;本次未执行`npm audit fix`或破坏性依赖升级。发布过程没有发送、补发或重投真实短信,没有修改通道账号、密码、启停状态、企业余额或客户连接。
- 受保护的`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续不删除、不提交、不归因于本次发布记录。
# 2026-08-12 签名质量检测未报备签名聚合热修复
- 发布后生产日志确认签名质量检测页底部`GET /api/admin/signature-retirement/unreported-signatures`返回500;根因是结果标识使用`extracted.tenant_id/application_id`,但PostgreSQL聚合只分组了关联表主键和签名,生产数据执行时严格报`42803`。该故障仅影响只读未报备签名统计,不涉及签名通道发送质量、短信发送、计费或回执数据写入。
- 最小修复为将原始企业、应用字段加入`GROUP BY`,保持“正文签名 × 实际企业应用”业务口径、搜索、计数和分页不变;同步新增`TC-SIGNATURE-RETIREMENT-029`,防止测试桩只验证返回映射而遗漏真实PostgreSQL语法约束。
- 签名清退专项9/9、API TypeScript正式构建和`git diff --check`通过。热修复提交`4c70978da4e3bd22ea159313c95b36ca18d150d6`已推送,并采用API最小热发布:备份位于`/opt/cmpp-platform-backups/releases/20260812-175436-before-hotfix-4c70978d`,只替换本次API源码/编译产物并重启`cmpp-api`,未重启Gateway、Nginx或短信通道。
- 发布后运行标识已核对为`4c70978d`,API和Gateway健康通过。使用生产真实PostgreSQL执行与接口相同的完整聚合SQL成功返回1组、266条短信,未再出现`42803`;热发布后的API日志没有新增`ExceptionsHandler`或Prisma聚合异常。现有浏览器没有可接管的登录页,因此未伪造账号会话;页面可由用户直接刷新验收。
# 2026-08-13 Gateway响应截断与NestJS请求体容量修复(本地未提交、未发布)
- 只读复核确认Gateway通用API传输方法使用`io.LimitReader(resp.Body, 64*1024)`静默截断响应;待投递回执恢复查询单批100条时,生产真实JSON已可超过该边界并形成`unexpected end of JSON input`。本轮将完整响应上限调整为4MiB,并额外读取1字节识别超限:超过边界返回明确容量错误,不再把传输截断伪装成JSON语法错误。
- NestJS关闭框架自动注册的默认100KiB body parser,显式注册普通JSON/URL-encoded 2MiB解析器;仅`/api/client/send/imports/*`先注册25MiB JSON解析器。两类JSON解析器继续保存`rawBody`,公网HTTP API验签和幂等正文哈希语义不变;导入业务层原始正文20MiB限制保持不变。
- 域名链路重新核对:客户导入使用`sms.lisglo.com`私有API,其标准Nginx上限50MiB已覆盖25MiB解析需求;`api.lisglo.com`只开放单条HTTP API、客户Swagger和健康检查,不承载文件导入,因此本轮不错误扩大API专用域名或开放私有路由。
- 新增专项自动化:Gateway可完整解析约128KiB合法响应,超过4MiB返回`api response exceeds 4194304-byte limit`且不出现截断JSON错误;同一份约3MiB JSON在导入路由返回200、保留完整rawBody,普通路由返回413。API容量专项2/2、API全量37套/460项、API TypeScript正式构建、Gateway inbound专项、Gateway全量`go test ./... -count=1`及`go vet ./...`、4份Gateway队列契约和`git diff --check`均通过。
- 19份既有结构门禁中10份通过、9份失败;失败均来自当前`HEAD`在本轮开始前已经存在的契约漂移(下游重投/异常处置API、通道排序、签名弹窗、签名质量查询、报备导出、运营商集合、定时调度、长文本样式和签名查询),与本轮新增/修改文件无交集。本轮不为通过门禁而顺手刷新或改写其他会话业务契约,保留为既有基线问题单独治理。
- 本轮没有发送、补发或重投短信,没有修改通道账号、密码、启停状态、企业余额、客户连接或生产数据;代码保持未提交、未推送、未部署。受保护的`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`不删除、不提交、不归因。
# 2026-08-13 充值回执操作人员、看板精简与运营商标签统一(待提交、未发布)
- 充值记录列表接口使用充值单既有`operatorId`批量查询真实用户,返回`displayName`(缺失时回退`username`)作为`operatorName`;充值回执新增“操作人员”,历史无操作人的系统记录展示“系统”。未新增字段或migration,避免复制姓名造成历史数据与用户资料不一致。
- 运营看板删除“今日签名发送统计”和“今日签名发送统计 - 含引流”两个模块及其分页状态;今日活跃签名继续使用真实发送质量接口聚合。指标文案调整为“今日消费金额”,主数字直接复用与今日发送总量相同的`metric-card strong`样式。
- 企业应用管理的状态、到达率、单价列宽均从130px缩至104px,字段和操作未隐藏。全局审计运营商数据展示后,监控、通道/通道组、应用路由、签名和报备、清退、短信审核、批次号码、发送记录及客户端发送详情统一复用`CarrierTag`;筛选选项、图表图例、导出和说明文字保留纯文本,三网通道展开为三个标签。
- API全量37套/460项、充值和HTTP容量专项14/14、前后端TypeScript、Vite 8.1.5生产构建、Gateway全量测试与`go vet`、4份Gateway队列契约、企业应用R11、短信记录R11、企业签名R4结构契约和`git diff --check`均通过;Vite仅保留既有约2.07MiB单chunk提示。企业签名R4哈希只按本次经验证的运营商标签JSX同步更新,未放宽模块边界。浏览器连接本地页面时既有登录会话已失效,未输入账号密码或验证码,因此页面级视觉验收未完成。
- 本轮与此前未提交的HTTP/Gateway容量修复一并进入待提交范围,未发送、补发或重投短信,未修改通道配置、余额、客户连接或生产数据;受保护缓存、`outputs/`和空文件`=`不删除、不提交、不归因。
# 2026-08-13 下游投递后台重投任务安全整改与页面优化(已发布)
- 已将`docs/downstream-requeue-task-design-20260812.md`确认的完整设计口径合并进平台需求和系统测试文档;独立设计稿继续作为审计输入保留,不以现有实现反向改写设计结论。
- 预检严格使用企业、应用、类型、状态、北京时间日期和关键词筛选,不再把单一状态扩为全部状态;预检生成绑定操作人、筛选和`snapshotAt`的15分钟服务端签名凭证,创建接口不再接受前端重传的范围,仅按签名快照在真实PostgreSQL重新物化任务项。
- 新增任务扫描数据库租约、`processing`两分钟认领租约恢复和每应用秒级原子限速窗口;多实例/重叠扫描不能突破每应用配置速率。客户无connected连接时进入`waiting_connection`,连接恢复后回队列;写出进入`waiting_ack`不清零,只有有效ACK清零,ACK超时/拒绝按应用累计并达到阈值后自动暂停和审计。
- 新增完整任务项分页接口,支持状态、消息ID、错误和跳过原因查询;终止将尚未开始和等待连接项置为`unprocessed`,不撤回处理中或已写出项。任务列表增加状态筛选和分页,页面补齐企业—应用联动、中文状态、创建人、原因、进度及结果数;创建弹窗重做命中/可重投/跳过/应用信息层级和安全边界,详情可查询全部历史项而非最近50条。
- 新增向前兼容migration`20260813150000_harden_downstream_requeue_tasks`,只增加任务应用级失败计数、扫描租约和速率窗口表,不删除或改写历史投递/ACK。已在明确指向`localhost:5432/cmpp_platform`的本地真实PostgreSQL应用,当前本地87条migration且schema up to date;未连接或修改预生产数据库。
- 后台任务专项7/7通过,覆盖严格预检、签名凭证、服务端物化、完整分页、processing恢复、离线等待和ACK自动暂停;API全量37套/463项、Prisma format/validate、API及前端TypeScript正式构建、Vite 8.1.5生产构建(2541 modules)均通过,仅保留既有约2.08MB单chunk提示。新增任务明细分页使`SendChainService`稳定门面方法由104增至105,对应R10结构契约已按真实新增接口精确同步并通过;`git diff --check`通过。
- 浏览器优先接管现有会话后确认本地真实API与PostgreSQL服务可访问,但现有浏览器没有已登录页面,访问下游投递页被正常引导到运营端登录;本轮未读取、猜测或重置凭据,也未绕过登录,因此创建弹窗、任务列表和详情的登录后视觉验收留待具备既有会话时补充。
- 功能提交`433b2ee56f6016ad8afff1bac73f510b8fd53083`已推送并成功发布。精确Git归档`outputs/cmpp-433b2ee5-20260813-120852.tar.gz`共840项、2268178字节,本地与服务器SHA-256均为`456cf284a8e38ff532c646de93ec5dfcc378b9acecb1cec58497782cdb155755`;运行目录`.deployed-commit`已核对为该提交。
- 发布前恢复资产位于`/opt/cmpp-platform-backups/releases/20260813-121038-before-433b2ee5`,目录权限0700、文件0600PostgreSQL备份41149565字节、SHA-256=`818442b23c0450786543b445ac444be65ac2d03f9a84039fa02dee90bacdeefa`,运行源码备份2275942字节、SHA-256=`1222f7718ebb2ae0da58434ca2836408154215e9c121e5e1c9423a7b40538e52`,环境文件895字节、SHA-256=`7a26d83b062f9d7e9503e2a987f39a899510f8981be63be997bccfc988fbbc60``sha256sum -c`、gzip和tar校验均通过,上一运行目录保留为`/opt/cmpp-platform.previous-20260813-121038`。
- 标准发布完成依赖安全缓解门禁、Prisma generate/migrate、前端/API/Gateway构建、Nginx校验以及Gateway先于API重启。第87条migration`20260813150000_harden_downstream_requeue_tasks`仅应用一次,迁移记录完成且无回滚/错误日志;新增`DownstreamRequeueRateWindow`表、3个索引以及任务租约/应用失败字段均真实存在。
- API、Gateway、Nginx、PostgreSQL、Redis与MinIO均active,内部API/Gateway/MinIO健康、Redis PONG`gateway.submit.commands`消费者1、`pending=0`、`lag=0`。公网运营端、客户端和API health均HTTP 200,公网CMPP 17890 TCP连通;发布时间窗API/Gateway warning级日志为0。
- 首次前台SSH执行因本地等待窗口关闭而收到终止信号,包装流程按设计恢复PostgreSQL和原运行目录,运行标识回到`4c70978d`、migration回到86条、服务全部active;确认恢复资产完整后改为服务器后台日志方式重新执行并成功,未并发重复部署。
- 本轮没有创建真实重投任务、调用真实Gateway重投、发送短信、修改通道配置、余额或客户连接。既有`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续保护,不归入业务提交。
# 2026-08-14 Prometheus 系统监控(本地未提交、未发布)
- 运营端“系统管理”新增独立“系统监控”页面,保留原“发送监控”业务职责。页面使用平台React、ECharts和通用组件原生实现,不嵌入Grafana、Prometheus或第三方iframe;支持近1小时、24小时、7天,展示CPU、内存、根磁盘、网络、负载、运行时长、六类核心systemd服务和Prometheus活动告警。
- 新增只读`GET /api/admin/infrastructure-monitoring/overview`。后端只接受`1h/24h/7d`白名单,按固定PromQL并行访问Prometheus5秒超时;浏览器不能提交PromQL或访问9090/9100。缺失序列返回`null`Prometheus异常返回`available=false`并清空指标和趋势,不用0、Mock、静态数据或localStorage伪装。
- 新增Debian/Ubuntu幂等安装脚本、Prometheus抓取配置和告警规则。Prometheus与Node Exporter只监听`127.0.0.1`,默认保留30天且限制8GB;脚本备份既有配置和override、运行`promtool`校验,只重启两个监控服务,不重启API、Gateway或其他业务服务。本轮未在预生产执行脚本。
- 专项Jest 1套/4项、API全量38套/467项通过,覆盖范围白名单、Prometheus HTTP响应契约解析、固定60秒step、服务别名、活动告警、不可用无陈旧数据及监控地址安全约束;全量Jest仍因仓库既有异步句柄使用`--forceExit`收尾。API正式TypeScript、前端TypeScript、Vite 8.1.5生产构建、两个Shell脚本语法及`git diff --check`通过;Vite仅保留既有约2.10MB单chunk提示。
- 浏览器优先检查现有页面:本地运营端无有效登录Session,被正常引导到带算术验证码的登录页;未绕过登录、未读取或填写验证码,因此登录后桌面与窄屏视觉验收尚未完成。真实Prometheus/Node Exporter集成和告警触发验收必须在明确授权安装的测试或预生产窗口执行,当前不以单测替代真实基础设施验收。
- 本轮代码、配置和文档保持未提交、未推送、未部署,没有发送、补发或重投短信,没有修改通道账号、密码、启停状态、企业余额、客户连接或预生产数据。既有构建缓存、`outputs/`和空文件`=`继续保护;并行会话新增的Fail2ban设计与测试文档不属于本需求,不修改、不归因。
# 2026-08-14 Fail2ban 安全检测与人工封禁第一版(本地实现完成、未发布)
- 新增真实 PostgreSQL 安全规则、事件、告警、封禁和保护网段模型及第88条 migration `20260814150000_add_security_detection`;九类默认规则覆盖运营端/客户端登录、SSH、CMPP认证与协议滥用、HTTP错误密钥/签名/重放和Nginx恶意扫描。应用事件按事件键幂等并使用PostgreSQL advisory transaction lock串行聚合;Fail2ban命中作为其自身窗口已达到阈值的聚合事件处理,不会再要求重复达到第二层阈值。
- 运营端新增“安全控制 / 安全检测与封禁”自研页面,使用真实API展示总览、告警、规则、封禁记录和保护名单;规则修改、封禁、解封、忽略和保护名单写操作要求近期重新认证。封禁时长为固定枚举,执行器由服务端按入口映射,浏览器不能传jail、action、shell或执行器参数;系统私网/回环等内置保护和人工CIDR保护在调用代理前拦截。
- 新增独立Go `cmpp-security-agent`、Unix Socket固定协议、report-only Fail2ban action/filter、Nginx real-IP deny、nftables timeout set和systemd加固。NestJS部署身份改为专用非root `cmpp-api`,安全事件入口新增独立内部令牌;agent不使用shell拼接,规则/Nginx配置校验或reload失败会恢复旧文件,只有真实执行器回读命中后数据库才标记`blocked`。
- 登录、OpenAPI鉴权和Gateway已接入结构化安全事件;错误HTTP密钥只保存不可逆账号指纹,证据字段统一过滤password/secret/token/signature/access-key。反向代理地址只在TCP来源属于`TRUSTED_PROXY_IPS`时信任`X-Forwarded-For`,避免客户端伪造来源IP。
- Prisma schema validate、API与前端TypeScript、API全量40套/472项、Fail2ban专项和Gateway控制器3套/11项、Gateway全量`go test ./...`、Vite 8.1.5生产构建、3个Shell脚本语法和`git diff --check`通过;Vite仅有既有约2.11MiB单chunk提示,全量Jest仍使用`--forceExit`收尾既有异步句柄。
- 浏览器优先接管本地路由,`/admin/security-detection`在无有效Session时正确跳转运营端登录并保留返回地址,控制台error/warn为0;未读取、重置或猜测账号,登录后页面视觉与交互验收尚未完成。真实Fail2ban、Nginx、nftables、Unix Socket和第88条migration未在本机数据库或预生产安装/执行,必须在具备恢复资产和文档保留测试IP的授权发布窗口完成,当前不以Mock替代集成验收。
- 本轮未发送、补发或重投短信,未修改通道账号、密码、启停状态、企业余额、客户连接或预生产数据;`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续作为受保护项排除提交。
# 2026-08-14 Prometheus 与 Fail2ban 两次提交本地部署复核(未推送、未发布)
- 从侧边会话已经落到本地 `main` 的两个提交开始复核:`b78faa1aa24a89830892b511a6cb17cc5a5fbe68`Prometheus 系统监控)和 `d30d9ea4d0ec8a46154dfb1e39a9bba2156ec455`Fail2ban 安全检测)。复核时本地 `HEAD=d30d9ea``origin/main=96e475d`,本地领先2个提交;本轮没有再次提交、推送或发布。
- migration 前已将本地真实 PostgreSQL 备份到 `C:\cmpp-platform-local\backups\cmpp-platform-before-d30d9ea-20260814-111254.dump`637967字节,SHA-256=`523ecc82b55b5575ebe78fc4d253c5ec44932a76a51209130442f619e1971089`。Prisma generate、validate、migrate deploy/status均通过;`20260814150000_add_security_detection`真实应用一次,本地数据库由87条升级为88/88条migration,九类默认安全规则均存在且配置版本为1。
- 本地API以正式构建产物运行在3000端口,前端Vite生产预览运行在4173端口,API health与前端HTTP均为200。为避免本地Gateway连接真实供应商,本轮只编译和测试Gateway,没有启动8090;因此API日志中的活动通道恢复和供应商状态对账失败是预期的本地Gateway离线结果,未修改任何通道参数,也未触发短信提交。
- API全量40套/472项、API TypeScript正式构建、前端TypeScript与Vite 8.1.5生产构建、Gateway `go test ./... -count=1`及`go vet ./...`全部通过;Vite仅保留既有大chunk提示。Prometheus、Fail2ban、nftables和Linux systemd在Windows本机不可用,三个部署Shell及标准发布/初始化Shell均通过Bash语法检查,但不以语法检查冒充Linux真实安装验收。
- 正式服务层连接真实本地PostgreSQL和真实不可达的 `127.0.0.1:9090` 验证:监控概览返回 `available=false`,所有指标为`null`、趋势为空,非法范围`30d`返回400;安全检测写入保留测试地址`203.0.113.10`的一条 `http_invalid_api_key` 事件,证据中的访问密钥已存为`[REDACTED]`,同一`eventKey=local-qa-d30d9ea-http-invalid-api-key`第二次上报命中幂等去重且未达到告警阈值。该真实本地测试事件保留作审计证据,没有创建封禁或调用安全代理。
- 未认证HTTP请求访问监控总览、安全总览和规则列表均返回401。经用户明确授权,只临时替换本地专用 `codex_local_admin` 的密码哈希完成图形验证码登录;登录后立即恢复原密码哈希、失败计数和锁定时间,未新建账号、未变更session版本。浏览器桌面验收确认监控页切换到近1小时并刷新后仍明确显示Prometheus不可用且没有Mock/缓存数值;安全页显示24小时事件1条、安全代理不可用,并从真实数据库展示9条规则及`1/1`版本。390×844窄屏下两页核心内容和交互可用,控制台warning/error为0;安全页五个页签在窄屏中文字换行偏碎,记为非阻断视觉问题。
- 19份既有结构门禁中11份通过、8份失败;失败集中在后台重投/异常处置API、通道/发送质量哈希、报备导出、运营商集合、定时调度、全局长文本样式和签名查询等既有契约漂移,与这两个提交新增文件无交集,本轮不顺带改写其他模块契约。`git diff --check`通过。
- 本轮没有发送、补发或重投真实短信,没有修改真实通道账号、密码、启停状态、企业余额或客户连接。既有`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`继续保护;本段测试记录是本轮新增的唯一业务工作区修改。
# 2026-08-14 Prometheus 与 Fail2ban 本地服务器部署及真实集成验收
- 经用户明确授权,将本地`HEAD=d30d9ea4d0ec8a46154dfb1e39a9bba2156ec455`及当前工作区的部署修复安装到全新Ubuntu 24.04测试节点`100.93.204.60`;未把该节点当作预生产。部署前只读盘点确认4核、7.8GiB内存、根盘约98GiB且无既有平台目录/数据库/环境文件,恢复基线位于`/opt/cmpp-platform-backups/releases/20260814-135221-before-d30d9ea-localserver`API回环修复前增量备份位于`/opt/cmpp-platform-backups/releases/20260814-144709-before-api-loopback`。
- 基础源码归档SHA-256=`c9e0b4ba5895b0d434a3335dcc6044f291779337841bb19b636bbed5d91b1b96`,首轮修复overlay=`24c5720dd0da6fab1b745d3c976cfc70d1a2f1b49da13443157a0ae89eac1bad`API回环修复overlay=`3d6cdd45a87e12fcad50a10d18862a1527c6a36fae2b18391142c0fba61e717e`;运行标识写为`d30d9ea4d0ec8a46154dfb1e39a9bba2156ec455+localfix.3d6cdd45a87e`。生成的本地管理员凭据以0600权限保存在服务器`/home/hector/cmpp-platform-admin.txt`,未写入仓库或测试记录。
- 已安装Node 22.21.1、Go 1.26.0、PostgreSQL 16.14、Redis 7.0.15、Nginx 1.24、Fail2ban 1.0.2、Prometheus 2.45.3及Node Exporter 1.7。由于该LAN的DNS/代理返回不可路由的fake-IP,安装期间备份原DNS、hosts和APT源后改用清华Ubuntu镜像并为必要下载域名写入临时hosts固定解析;这些固定解析仅为安装绕行,网络恢复后应按恢复资产移除。首次部署因MinIO官方二进制跳转GitHub后不可达,依照部署文档临时使用真实服务器文件存储驱动`local`,没有用Mock或localStorage伪造对象存储;后续已按用户提供的MinIO二进制完成正式切换,证据见下方补充记录。
- 第88条migration真实应用,Prisma报告88 migrations且schema up to date`SecurityDetectionRule`真实9条,`configVersion/effectiveVersion`均为1。该全新节点的通道、短信记录、下游重投任务和安全封禁记录均为0,未连接真实供应商或客户。
- 真实Linux集成检查通过:API、Gateway、安全代理、PostgreSQL、Redis、Nginx、Prometheus、Node Exporter及Fail2ban均activeAPI/Gateway/Prometheus健康、Redis PONG、PostgreSQL ready、Nginx语法和Fail2ban配置通过。Prometheus两个target均为`up`,配置有效且告警文件12条规则通过`promtool`9090/9100仅监听127.0.0.1。安全代理Unix Socket为0660 root:cmpp-securityNestJS用户`cmpp-api`无sudosystemd与Fail2ban action共同指向`/opt/cmpp-platform/dist/cmpp-security-agent`nftables专用IPv4/IPv6 timeout set存在,Fail2ban sshd jail运行。
- 部署中发现并修复三项真实Fresh-Install缺陷:安全代理systemd与Fail2ban action旧路径漂移;Ubuntu默认gzip与发布脚本重复声明导致`nginx -t`失败;NestJS文档要求回环但代码默认监听全网卡。前两项由安装/发布静态门禁保护,第三项新增`API_HOST`并默认127.0.0.1。修复后服务器`ss`确认3000/5432/6379/8090/9090/9100均为回环,外部探测12026和17890可连、3000/9090/9100不可连,Nginx入口`/api/health`返回200。专项部署门禁、API TypeScript正式构建、Shell语法和`git diff --check`通过。
- 内置浏览器两次导航该Tailscale地址均在页面加载阶段超时;用户随后明确要求改用系统Chrome,Chrome控制扩展同样在新建页导航阶段超时,而同机PowerShell对同URL返回HTTP 200,判定为浏览器控制链路到Tailscale HTTP地址的环境阻塞。两次尝试均未到验证码或登录提交;管理员密码哈希、失败次数和锁定时间已从临时数据库备份恢复,临时备份表已删除。未绕过图形验证码,也未把登录后桌面/窄屏视觉验收伪报为通过。页面构建与真实后端/基础设施证据已通过,登录后视觉及范围切换仍需用户在本机Chrome手动打开页面,或共享已打开的具体标签页后补验。
- 本轮没有发送、补发、重投短信或创建重投任务,没有修改真实通道账号、密码、启停状态、企业余额或客户连接。工作区修复与文档尚未提交、推送;`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`及空文件`=`继续作为受保护项,不删除、不提交、不归因。
## MinIO 正式切换补充(2026-08-14
- 用户提供`D:\迅雷下载\minio.linux-amd64.RELEASE.2025-09-07T16-13-09Z`,本地与服务器SHA-256均为`7c5bd8512c6e966455b1d198209358b2d191c77a83ab377c4073281065fb855f`;服务器`file`确认其为静态链接Linux x86-64 ELF,运行版本为`RELEASE.2025-09-07T16-13-09Z`、Go 1.24.6。
- 切换前确认`/var/lib/cmpp-platform/object-storage`文件数为0,并将环境、MinIO环境、systemd单元和本地对象存储目录备份到`/opt/cmpp-platform-backups/releases/20260814-151145-before-minio`。安装后`cmpp-minio`与API均activeAPI使用`OBJECT_STORAGE_DRIVER=minio`9000/9001只监听127.0.0.1/::1,外部探测均不可连接。
- 使用API同款MinIO Node客户端真实创建`cmpp-platform` bucket,并执行测试对象写入、读取内容比对和删除,三步均成功且测试对象已清理。API健康、Gateway、Prometheus、Node Exporter及Fail2ban继续active;未创建业务附件记录、短信、重投任务或通道连接。
# 2026-08-14 系统监控恢复、标题去重与全局预警菜单(测试服务器已部署)
- 用户在`100.93.204.60`真实页面看到系统监控整体降级。只读诊断确认Prometheus、Node Exporter、API、MinIO均active,两个采集target均为`up`,CPU、内存、磁盘、网络、负载、运行时长和systemd查询单独执行都成功;直接运行实际`InfrastructureMonitoringService`后捕获到systemd查询HTTP 400Prometheus明确返回`unknown escape sequence '.'`。根因是TypeScript字符串只向PromQL传递单反斜杠`\.`,而Prometheus字符串层要求双反斜杠后再交给RE2。
- systemd固定PromQL改为TypeScript四反斜杠字面量,实际查询文本正确传递双反斜杠;专项测试锁定请求参数。整页降级行为继续清空陈旧数据,但新增仅含错误摘要的服务端warning,不记录PromQL、地址或凭据。部署后真实服务返回`available=true`、综合状态`healthy`、核心服务6/6、1小时CPU趋势56点,API发布后无新增监控不可用warning。
- 系统监控内容区删除重复的大号`<h1>系统监控</h1>`,保留平台通用页头、说明、状态、时间范围和刷新操作。构建产物与部署源码静态核对确认重复标题不存在。
- 右上角铃铛由签名清退直接链接改为“预警中心”弹层,分开显示“签名清退预警”和“安全检测与封禁”;审核待办继续使用独立图标和菜单。签名项读取今日未读且未抑制消息数,安全项新增轻量`GET /api/admin/security-detection/notification-summary`,只统计`open/acknowledged/block_failed`总数与严重数,不轮询完整总览、规则或安全代理。任一域失败由`Promise.allSettled`独立降级,不清空另一域。
- 本地监控/安全专项2套8项、API全量40套473项、前后端TypeScript和Vite生产构建全部通过;全量Jest仍因既有异步句柄使用`--forceExit`收尾,Vite只保留既有大chunk提示,`git diff --check`通过。
- 发布归档`outputs/cmpp-monitor-alert-fix-20260814-152652.tar.gz`及服务器副本SHA-256均为`8a00a02714ced5311b25fbc3e1cfc17f3d1a38759f1499db78c52089bc0b60b7`。发布前PostgreSQL、环境和运行源码恢复资产位于`/opt/cmpp-platform-backups/releases/20260814-152719-before-monitor-alert-fix`,三项SHA校验、源码tar目录和pg_restore清单均通过;运行标识为`d30d9ea4d0ec8a46154dfb1e39a9bba2156ec455+localfix.monitor-alert.8a00a02714ce`。
- 经用户明确要求,在该空白测试服务器真实PostgreSQL创建可清理的`qa-bell-alerts-*`预警验收数据:2条签名清退未读消息,关联一个`interfaceEnabled=false/status=disabled`的QA应用和两条QA签名;3条安全告警通过真实内部安全事件接口按规则阈值触发,使用文档保留IP`203.0.113.101-103`,其中critical 1条。铃铛真实汇总为2+3=5;封禁记录0、短信记录0,没有调用安全代理封禁、Gateway提交或供应商连接。
- Chrome中已存在登录后的测试服务器页面,但浏览器控制扩展在接管该标签页阶段持续超时,因此未伪报点击和响应式视觉验收通过。服务器真实服务、数据库、接口服务层、构建产物和静态契约均已验收;用户刷新页面即可查看,后续以用户截图继续视觉核对。
- 本轮没有发送、补发或重投短信,没有修改真实通道账号、密码、余额或客户连接。代码和文档尚未提交、推送;受保护的`*.tsbuildinfo`、`outputs/`及空文件`=`继续保留,不归因或提交。
# 2026-08-14 后台重投支持客户端已确认记录与创建/列表样式优化(本地未部署)
- 后台任务可重投状态由`pending/failed/unconfirmed/rejected`扩展为`pending/failed/unconfirmed/rejected/delivered`;状态筛选为`delivered`时,预检将客户端已确认记录计入可重投数并在真实PostgreSQL任务项保存`previousStatus=delivered`。`awaiting_ack`继续由预检计为不可重投且创建接口明确拒绝,避免确认窗口内并发写出。
- 执行器不是简单放开当前`delivered`状态:只有冻结快照原状态已经是`delivered`的任务项才允许再次调用Gateway;任务创建时为失败/待投递等状态、执行前才收到迟到成功ACK的项目会以“创建任务后已被客户确认”跳过。该判断用于保留运营明确选择已确认记录时的重复投递能力,同时防止其他任务范围意外扩大。
- 创建弹窗将原生无统一样式的`textarea`替换为平台`Textarea`,增加必填标识、少于5字错误、说明、200字计数、统一焦点态和重复投递风险提示。后台任务列表使用独立内容边框和圆角,桌面卡片边缘保留24px、行内保留20px,窄屏收敛为16px;标题区和分页同步使用设计间距。
- 已同步`docs/downstream-requeue-task-design-20260812.md` V1.1、平台需求和系统测试用例,新增已确认批量重投、迟到ACK保护及桌面/窄屏视觉用例。专项Jest 10/10、API全量41套/477项、前后端TypeScript、API正式编译、Vite 8.1.5生产构建(2549 modules)、SendChain R10结构契约和`git diff --check`通过;Vite仅保留既有约2.11MiB单chunk提示。Operations R2结构门禁仍因本轮开始前已有的`sendQuality`查询哈希漂移失败,与本次下游重投文件无交集,未为通过门禁改写其他会话业务契约。
- 本地真实PostgreSQL为88/88条migration且schema up to date。使用现有失败投递在单一数据库事务中临时改为`delivered`,真实验证状态白名单命中1条并成功物化`previousStatus=delivered`任务项1条,随后强制回滚;事务后原投递恢复`failed`且测试任务持久化数为0。该验证没有启动任务扫描、调用Gateway或发送短信。
- 本轮尚未部署测试服务器或预生产,因当前需求只授权修改且交接约束要求部署另行明确授权;没有创建真实重投任务、发送/补发/重投短信、修改通道账号、密码、启停状态、企业余额或客户连接。既有监控/预警工作区修改及`*.tsbuildinfo`、`outputs/`、空文件`=`继续保护,不归因于本次改动。
# 2026-08-14 服务内部Prometheus指标、阈值与测试机部署
- 在现有工作区上增量实施,未reset/checkout或覆盖其他会话改动。API新增独立`127.0.0.1:9464/metrics`,仅使用路由模板、HTTP方法和状态的低基数标签;Gateway回环`8090/metrics`新增Go运行时、上下游连接、Submit结果/耗时及Redis Stream pending/lag/最旧年龄。两者均只在内存计数,不写业务PostgreSQL或Redis。
- 测试机`100.93.204.60`安装Ubuntu发行版`prometheus-postgres-exporter 0.15.0`、`prometheus-redis-exporter 1.54.0`和`prometheus-nginx-exporter 1.1.0`,开启MinIO回环原生指标;Prometheus现实际采集`prometheus/node/cmpp-api/cmpp-gateway/postgresql/redis/minio/nginx`8个target,全部`up`。
- 规则扩展至61条,覆盖主机资源、API 5xx/P95/事件循环、Gateway worker/连接/队列年龄、PostgreSQL连接/死锁、Redis内存/淘汰/拒绝连接、MinIO容量/离线盘、Nginx可用性和Prometheus自监控。比例告警有最低错误样本量,Warning/Critical范围不重叠;`promtool check rules/config`通过,8个规则组计算失败计数全为0,部署后无活动告警。
- Recording Rules真实返回API P95约0.048s、Gateway pending/lag均0、PostgreSQL连接使用率3%、Redis连接10/已用约1.78MB、MinIO容量使用率约20.8%/离线盘0、Nginx活跃连接4。系统监控页新增六组“服务关键指标”卡片,只读取`cmpp:service_*`聚合;缺失指标显示破折号/待采集,不以0伪造。
- 外部真实TCP探测确认仅业务端口12026可连接;3000、8090、9000、9090、9100、9113、9121、9187、9464全部从LAN不可连接。各监控进程当时CPU合计约0.4%Prometheus RSS约101MB、三个新Exporter RSS合计约57MB;各8个target抓取耗时0.0008至0.037s,明显低于15s周期,TSDB当时5790条series。
- 本地API专项2套5项、API全量41套/477项、API/前端TypeScript、Gateway全量`go test ./... -count=1`和`go vet ./...`通过;测试机Vite 8.0.16生产构建、API/Gateway构建和健康检查通过,仅保留既有大chunk提示。API/Gateway/Prometheus发布后warning级journal为0。
- 完整恢复资产位于`/opt/cmpp-platform-backups/releases/20260814-164653-before-service-metrics`,包含PostgreSQL、运行源码、环境/监控/Nginx/systemd配置,SHA-256和gzip校验通过。`20260814-164636-before-service-metrics`是因`pg_dump`不接受Prisma `schema` URL参数而立即停止的不完整目录,不可用于恢复;未删除以保留证据。当前运行标识为`d30d9ea4d0ec8a46154dfb1e39a9bba2156ec455+workspace.service-metrics.28575bc8a7d8.minio`。
- Edge现有测试机页面会话未登录,访问系统监控被正常引导到带图形验证码的登录页;未代填或绕过验证码,因此登录后页面视觉验收留待用户使用已有测试账号查看。本轮未发送、补发或重投短信,未修改通道账号/密码/启停、余额或客户连接;代码未提交、未推送、未发布预生产。
# 2026-08-14 跨会话工作区合并复核
- 合并复核覆盖系统监控恢复与预警菜单、服务内部Prometheus指标/Exporter/阈值、Fail2ban部署路径修复,以及后台重投支持客户端已确认记录和创建/列表样式优化。Git不存在未合并文件或冲突标记;共同修改的API模块、全局布局/样式、部署脚本、平台需求、系统用例和进度记录均已逐项核对,没有发现状态口径、路由、样式选择器或部署时间线互相覆盖。
- 测试机静态包只读核对显示当前已部署“服务关键指标”,但尚未包含“重复投递风险”和已确认重投的新表单文案,证明服务指标会话使用定向发布,没有把尚未授权部署的下游重投改动意外带入测试机;两项发布记录保持一致。
- 合并后统一回归通过:API全量41套/477项、前后端TypeScript、API正式编译、Vite 8.1.5生产构建(2549 modules)、Gateway全量`go test ./... -count=1`与`go vet ./...`、SendChain R10、生产部署和安全代理静态契约、5个Shell脚本语法、真实本地PostgreSQL 88/88 migration状态及`git diff --check`。Vite仅保留既有约2.11MiB单chunk提示;Operations R2仍因本轮开始前已有的`sendQuality`查询哈希漂移失败,与本次合并文件无交集。
- 本次合并没有发送、补发或重投短信,没有创建后台重投任务,没有修改通道账号、密码、启停状态、企业余额或客户连接;提交范围继续排除`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件`=`。
# 2026-08-14 系统监控阈值与预警入口优化(进行中)
- 系统监控将“服务关键指标”移至活动告警正上方,标题说明明确使用 Prometheus;新增十组固定指标警告/严重阈值设置。配置真实写入 PostgreSQL,使用版本条件并发认领,promtool 校验、原子替换和回环 reload 成功后才推进生效版本,失败保留旧生效值。
- 右上角预警中心新增“系统监控告警”及数量/严重数,读取独立 Prometheus 活动告警汇总并跳转活动告警锚点;继续使用 `Promise.allSettled` 隔离签名、安全与监控域故障。安全检测页移除重复大号标题,说明明确使用 Fail2ban。
- 新增 migration `20260814173000_add_infrastructure_alert_settings`。本机 Prisma Client 生成、前后端 TypeScript 与 API 正式编译已通过;测试机恢复资产、migration、Prometheus规则校验、真实告警数据、浏览器验收和提交/部署结果待本轮后续补记。
- 首次测试机规则验收发现 Redis 未配置 `maxmemory` 时除零结果会误触发 Critical pending,立即补回 `redis_memory_max_bytes > 0` 固定保护,并补回 API 5xx 窗口至少 5 次错误的最低样本门槛;该真实验收缺陷未按通过处理。
- 第二次真实应用验证发现 API 原子 rename 后的规则文件未继承 `prometheus` 组,Prometheus reload 返回 500;数据库按设计保持旧生效版本并标记 failed。安装器将托管目录修正为 2750 SGID,确保新文件继承 `prometheus` 组,随后必须以同一真实配置重试并验证 effective。
## 发布与真实验收结果
- 功能提交 `6ccc102`、比例保护修复 `0cd0944`、规则目录权限修复 `2216d00` 已部署测试机;当前 `.deployed-commit=2216d00d511ef4daa57b44ad33cfd3e7411b913e`。API、Gateway、Prometheus、PostgreSQL、Redis、MinIO、Nginx 全部 activeAPI/Gateway 健康,发布后 API warning journal 无记录。
- 测试机已完成 89/89 migration。真实阈值应用从失败版本 2 重试到版本 3,数据库 `configVersion=3/effectiveVersion=3/applyStatus=effective`;托管目录为 2750、组 `prometheus`,原子生成文件为 0640、组 `prometheus`。promtool 验证基础 61 条、托管 20 条和 QA 2 条规则,Prometheus 8/8 targets up。
- 测试数据使用真实 Prometheus 规则 `/var/lib/cmpp-platform/monitoring/cmpp-qa-preview-alerts.yml` 创建 2 条隔离演示告警(1 Warning、1 Critical,均带 `qa_preview=true` 且文案说明不代表真实故障);轻量汇总真实返回 `count=2/criticalCount=1`,错误 Redis pending 已消失。
- 恢复资产分别为 `/opt/cmpp-platform-backups/releases/20260814-175325-before-6ccc102`、`/opt/cmpp-platform-backups/releases/20260814-175946-before-0cd0944`、`/opt/cmpp-platform-backups/releases/20260814-180307-before-2216d00`,均包含 PostgreSQL、源码、环境及监控/Nginx/systemd 配置并通过 SHA-256、pg_restore 与 gzip 校验。
- 本机监控专项 2 套 6 项、前后端 TypeScript、API 正式编译、Vite 生产构建和 git diff check 通过;API 全量回归两次分别在 120 秒和 300 秒到达执行时限,未取得完整通过证据,因此不记为通过。外部 Edge 当前停留测试机登录页,因没有现成登录会话且页面含验证码,本轮未代填或绕过验证码,登录后视觉验收由用户直接查看。
- 本轮没有发送、补发或重投短信,没有创建后台重投任务,没有修改通道账号、密码、启停状态、企业余额或客户连接;QA 数据仅为测试机 Prometheus 演示规则。
# 2026-08-16 系统监控弹窗滚动与活动告警已读(测试机已部署)
- 阈值设置表单移除自身 `max-height/overflow`,仅保留平台通用 Modal 内容区滚动,消除双层滚动区域。
- 新增逐管理员活动告警已读设计:真实 PostgreSQL 保存 `fingerprint + userId + activeAt + readAt`;服务端回读 Prometheus 校验当前触发周期后幂等 upsert。页面活动告警保持原始数量,铃铛轻量汇总只统计当前管理员未读,告警以相同标签重新触发但 activeAt 改变时重新计入未读。
- 新增 migration `20260816100000_add_infrastructure_alert_reads`、单条已读接口、操作日志及前端“标记已读”按钮。接口只接受当前仍活动且 `fingerprint + activeAt` 完全匹配的触发周期;重复请求保持原 `readAt` 且不重复写操作日志。
- 功能提交 `482f7ac1ae4c219e47aeaac8735c0584b7d120f2` 已部署测试机,当前 `.deployed-commit` 与该提交一致。发布前恢复资产位于 `/opt/cmpp-platform-backups/releases/20260816-150521-before-482f7ac`,包含 PostgreSQL、运行源码、环境及平台配置,SHA-256、`pg_restore --list` 和 gzip 校验通过。
- 测试机已完成 90/90 migrationAPI、Gateway、Prometheus、PostgreSQL、Redis、MinIO、Nginx 全部 activePrometheus 8/8 targets up,发布时间窗 API warning 日志为 0。
- 使用测试机既有隔离 QA Prometheus 规则和真实 PostgreSQL 验证:活动告警 2 条,其中 1 条标记已读后页面仍保留 2 条,当前管理员铃铛未读数降为 1,严重未读数为 1;重复标记返回相同 `readAt`,对应操作日志只有 1 条。数据库保留 1 条 QA 已读记录,便于页面同时展示“已读”和“标记已读”状态。
- 监控专项 2 套 8 项、Prisma format/generate、前后端 TypeScript、API 正式编译、Vite 生产构建和 `git diff --check` 通过;Vite 仅保留既有大 chunk 提示。本地真实 PostgreSQL 不可用,`prisma migrate deploy` 返回 Schema engine error,因此没有伪造依赖或把本地 migration 记为通过,migration 已在测试机真实 PostgreSQL 验证。
- 最终浏览器控制会话没有可接管的现有标签页,未绕过图形验证码或另行创建登录会话,因此登录后弹窗滚动和按钮视觉点击未伪报为通过;代码样式契约、真实接口、数据库、Prometheus 与测试机部署均已验收,用户刷新测试机现有登录页面即可查看。
- 本轮没有发送、补发或重投短信,没有创建后台重投任务,没有修改通道账号、密码、启停状态、企业余额或客户连接;`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`和空文件 `=` 继续作为受保护项排除提交。
# 2026-08-17 CMPP压测优化第一步:纯观测分段(本地未部署)
- 按首轮压测瓶颈方案先实施V0纯观测,不调整SubmitResp快路径、并发窗口、Stream Worker模型、风控、计费、路由、幂等、事务或供应商回调状态机。API入站增加固定阶段直方图,覆盖应用查询、长短信分片、提交预检、模板匹配、任务/API请求/消息持久化、内容检测、风控与频次、计费、入队、完整提交和总耗时。
- Gateway入站增加`decode/api_roundtrip/response_write/handler_total`,供应商下发增加`stream_wait/rate_limit_wait/connection_wait/supplier_rtt/api_callback`。供应商RTT只围绕真实连接Submit往返计时,API回写单独计时;阶段和结果均为代码白名单,指标不含手机号、企业、应用、通道、连接、消息、Submit或任务ID。
- API TypeScript正式构建通过;`metrics.service.spec.ts`与`gateway-events.controller.spec.ts`共8项通过。Gateway全量`go test ./... -count=1`及`go vet ./...`通过,4份Redis Stream消息契约与SendChain R10结构门禁通过;上游R7契约按本轮`Manager.Submit/connectionPool.submit`观测边界同步后通过。
- 入站R6契约已同步本轮`handleSubmit`实现哈希,但门禁首先被开始前已存在且源码未修改的`authentication.go/authRequest`哈希漂移阻塞;没有为通过本轮门禁而重写或归因该认证声明。`git diff --check`通过,仅输出工作区既有的LF/CRLF提示。
- SendChain专项大套件执行120项,其中115项通过;5项走真实BullMQ连接时因本机`127.0.0.1:6379`拒绝连接而超过5秒,测试进程同时留下Redis重连句柄。未启动或伪造Redis,因此本轮不把该套件记为全通过;该阻塞不影响两个独立指标专项和TypeScript正式构建证据,后续应在具备真实Redis的隔离测试环境补跑语义回归。
- 本轮未连接预生产或测试虚拟机、未发起压力流量,未发送、补发或重投短信,未修改通道账号、密码、启停状态、企业余额或客户连接;未提交、未推送、未部署。开始前已有的`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`及空文件`=`继续保护,不归因于本轮。
# 2026-08-20 CMPP压测优化V2:持续有界Submit Worker(测试环境已发布;预生产保持现状)
- 根据首轮压测报告中供应商提交峰值约14.24次/秒、Redis Stream lag峰值684、API平均耗时82.5ms且VM资源未饱和的证据,V2只重构Gateway供应商Submit Worker,不提前实施入站SubmitResp快路径或V3/V4异步Outbox。
- 原实现每次`XREADGROUP Count=10`后启动协程并等待整批全部完成,慢任务形成批次屏障。V2改为默认64槽位、最大1024的持续有界工作池:任一任务结束立即按空闲槽位继续领取;成功、终态拒绝或死信均保持单消息独立ACK,失败消息继续留在PEL按既有`MinIdle/MaxFailures`恢复。
- Pending恢复对本进程在途消息ID去重,并在`XAUTOCLAIM`返回后回查真实PEL,避免原任务恰好ACK时的竞态重复Submit;该处注释解释了为什么必须同时检查内存活动集合和Redis事实。新增`GATEWAY_SUBMIT_WORKER_CONCURRENCY`及`cmpp_gateway_submit_worker_slots{state=configured|in_flight}`,不增加实体标签。
- Worker专项连续20轮通过;Gateway全量`go test ./... -count=1`、`go vet ./...`、4份Stream契约、R6/R7与SendChain R10结构门禁通过。R6额外将当前HEAD中未被本轮修改的认证/Server/HTTP声明哈希与契约重新对齐,不归因于V2业务修改。
- 使用仅监听`127.0.0.1:16379`的本地真实Redis 8.8补跑API观测与SendChain回归,3套121项全部通过;测试后临时Redis已确认停止。Jest仍按仓库既有`--forceExit`口径收尾异步句柄。
- 2026-08-20发布前核对:本地`HEAD=origin/main=c4f36fc50d7906dfb2f97c881e9ea43c6a64c370`;本段操作目标实际为预生产`8.160.169.106`,其`/opt/cmpp-platform/.deployed-commit=433b2ee56f6016ad8afff1bac73f510b8fd53083`。此前记录中将该目标写成“虚拟机”属于环境称谓错误,现明确更正为“预生产”;API/Gateway/PostgreSQL/Redis/MinIO/Nginx均active。用户要求预生产保持当前状态,不执行回退或后续测试环境发布动作。
- 预生产发布前恢复资产位于`/opt/cmpp-platform-backups/releases/20260820-100554-before-v2-worker`,包含PostgreSQL、运行源码、环境文件和平台配置;`SHA256SUMS`、数据库gzip及源码/配置tar均验证通过。精确发布包`outputs/cmpp-v2-worker-20260820-101239.tar.gz`共923项、2854923字节,本地及预生产服务器SHA-256均为`cd7bb8d05e7bf9a77ced4522948e0f00b8f25f6b5477eb93037e2a0000b7da5d`,排除了`.env`、`node_modules`、`outputs`、`*.tsbuildinfo`和空文件`=`。
- 标准全量发布完成前端/API/Gateway构建并将数据库从87条推进到90条migration,但在任何服务重启前被系统安全代理安装闸门阻断:Aliyun Linux 4当前启用仓库没有`fail2ban`包。未擅自增加第三方系统源;随后从恢复资产重新构建并恢复原`433b2ee`的API与前端运行产物,仅重启Gateway启用V2。因此API/前端仍为原运行版本,数据库保留3张向前兼容的监控/安全增量migration,当前运行标识明确写为`433b2ee56f6016ad8afff1bac73f510b8fd53083+gateway-v2.cd7bb8d05e7b`,不伪装为全量工作区已发布。
- Gateway于北京时间10:27:17重启成功,新PID监听17890,回环健康检查通过;`cmpp_gateway_submit_worker_slots{state="configured"}=64`、`in_flight=0``gateway.submit.commands`消费者1、`pending=0`、`lag=0`。原4条真实下游连接受90秒旧心跳租约影响,首次重连被连接上限拒绝并出现2次连接协程`close of closed channel` panicGateway进程未退出,旧租约自动过期后4条连接全部恢复,PostgreSQL心跳持续更新。该重启恢复现象作为后续独立稳定性缺陷保留,不通过手工修改客户连接规避。
- 预生产发布后观察到1条既有真实Stream命令由新Worker接受:总提交耗时68.288ms、Stream等待0.927ms、限速等待0.168ms;供应商RTT样本与API回调样本也已按新指标拆分,处理后PEL和lag均为0。随后30秒被动窗口没有新Stream命令,无法形成V2容量/TPS结论;本轮没有主动发压、发送、补发或重投短信。预生产6项核心服务保持activeGateway RSS约18MB;完整容量复测必须在`100.93.204.60`虚拟机测试环境使用已确认隔离的供应商模拟器执行。
- 测试环境发布结果:用户明确指定`100.93.204.60`为V2发布目标,并再次确认该地址才是“虚拟机测试环境”。取得用户提供的`hector`账号授权后完成只读预检:Ubuntu 24.04、原运行标识`482f7ac1ae4c219e47aeaac8735c0584b7d120f2`、90条migration、6/6测试供应商连接、下游连接0、Stream `pending=0/lag=0`。发布前恢复资产位于`/opt/cmpp-platform-backups/releases/20260820-104529-before-v2-worker-test`,包含PostgreSQL、运行源码、环境及平台配置,全部SHA-256、gzip和tar校验通过。
- 测试机使用同一精确归档`cmpp-v2-worker-20260820-101239.tar.gz`SHA-256再次核对为`cd7bb8d05e7bf9a77ced4522948e0f00b8f25f6b5477eb93037e2a0000b7da5d`;标准`production-deploy.sh`完成两套依赖安装、安全缓解门禁、Prisma generate/migrate、前端/API/Gateway与安全代理构建、Fail2ban配置测试、Nginx校验、服务重启及健康检查,90条migration无待应用项。测试机运行标识为`c4f36fc50d7906dfb2f97c881e9ea43c6a64c370+workspace.v2.cd7bb8d05e7b`。
- 发布后API、Gateway、安全代理、PostgreSQL、Redis、MinIO、Nginx、Prometheus及四类Exporter均activeAPI/Gateway健康、前端HTTP 2003000/8090/9464继续只监听回环,17890按测试CMPP入口监听。Prometheus真实返回8个target为`up`Gateway测试供应商连接6/6、下游连接0`cmpp_gateway_submit_worker_slots{state="configured"}=64`、`in_flight=0`Stream消费者1、`pending=0`、`lag=0`。发布时间窗API/Gateway/安全代理journal无warningAPI/Gateway文件日志无新增ERROR/Exception/panic/fatal。本次只发布和只读验证,没有主动发送、补发或重投短信,也没有修改测试通道账号、密码、启停状态、余额或客户连接。
- 代码保持未提交、未推送。开始前已有的`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`及空文件`=`继续保护;本轮生成的发布包位于既有`outputs/`目录,不扩大提交范围。
# 2026-08-20 CMPP压测优化V2:测试环境阶梯复测
- 仅对`100.93.204.60`虚拟机测试环境执行隔离压测;供应商端为本地CMPP模拟器`100.91.249.119:17900`,没有连接或改变预生产`8.160.169.106`,没有发送真实短信,也没有修改通道账号、密码、启停状态、企业余额或客户连接。测试环境运行标识复核为`c4f36fc50d7906dfb2f97c881e9ea43c6a64c370+workspace.v2.cd7bb8d05e7b`API、Gateway、PostgreSQL和Redis最终均为active。
- 按停止线先执行100条受控突发,再执行10条/秒和20条/秒各60秒。100条突发全部收到成功SubmitResp、无拒绝和连接错误,但P50/P95/P99为2972/5555/5808ms,因此不直接跳到高档;10条/秒实际599条,SubmitResp 599/599成功、无拒绝和连接错误,P50/P95/P99为35/268/1317ms20条/秒实际1199条,SubmitResp 1199/1199成功、无拒绝和连接错误,P50/P95/P99升至1110/5580/7767ms。20条/秒P95超过5秒停止线,因此没有执行30/40/50条/秒,未把未执行档位记为通过。
- V2 Worker目标已获得正向证据:10条/秒阶段Stream最大pending 15、lag 0、最大在途15,结束后排空;20条/秒阶段最大pending 43、lag 0、最大在途43,结束后同样`pending=0/lag=0`。20条/秒窗口供应商Submit尝试约1290次,约21.5次/秒,明显高于首轮旧实现约14.24次/秒且没有重现lag 684;供应商阶段平均`stream_wait≈3.55ms`、`rate_limit_wait≈0.15ms`、`connection_wait≈0.006ms`、`supplier_rtt≈149.16ms`。测试窗口主机CPU峰值约53.87%、内存使用峰值约27.49%,不是资源饱和。
- 新瓶颈位于客户入站SubmitResp路径而不是Redis Stream Worker。1898条业务消息的API分段平均总耗时约256.20ms,其中`risk_frequency≈95.73ms`最大,其后为`queue_publish≈37.69ms`、两次`application_lookup`合计约32.62ms、`template_match≈28.91ms`、`submission_precheck≈17.30ms``complete_submit`平均约239.41ms。20条/秒时客户端P95达到5.58秒而API平均仍为0.256秒,结合单连接窗口表明入站连接串行处理/排队仍在放大尾延迟,下一步应实施受窗口约束的连接内并发,或把SubmitResp收敛为“最小校验+幂等持久化”后异步执行风控、计费和路由。
- 数据库按实际首条`queuedAt=2026-08-20 03:01:47.980`对账,恰好新增1898条:最终delivered 1859、failed 11、submitted 2828条submitted与模拟器配置的28次不回执一致。供应商模拟器同期收到2048次Submit尝试,其中2013次接受、35次拒绝,发送并收到ACK的回执均为1985次,错误0;Gateway重试解释了尝试数高于业务消息数。客户端进程在收集窗口内看到的receipt数量包含异步到达,不能直接替代数据库和模拟器最终对账。
- 本轮所有1898条记录仍识别为`mobile`,未覆盖联通、电信,优先级在20条/秒下也未表现出隔离优势:priority P95约5991msnormal P95约4791ms。因此“修复号段/运营商识别后验证移动、联通、电信六通道容量及优先级隔离”继续保持P1未完成。
- 本轮新增测试辅助脚本`lg-cmpp-stress-lab/scripts/run-v2-stage.ps1`,只根据档位和持续时间生成一次性客户端配置并调用既有真实CMPP压测客户端,不引入mock、静态结果或localStorage。完整复测报告及原始结果保存在短信平台测试项目;代码仍未提交、未推送,预生产保持原状。
# 2026-08-20 CMPP压测优化V3:受窗口约束的连接内并发(开发中)
- V0/V2已按用户授权提交为`b9a71fe`,提交范围为入站/供应商阶段指标、持续有界Submit Worker、契约和同步文档;`*.tsbuildinfo`、`outputs/`、自动产生的`pnpm-lock.yaml`及空文件`=`继续排除并保护,未推送。提交前Gateway全量测试、`go vet`、API TypeScript正式编译和`git diff --check`通过。
- V3保持API风控、计费、路由、持久化和SubmitResp业务结果语义不变。认证接口新增返回真实`cmppWindowSize`Gateway对同一认证连接按`min(应用窗口, GATEWAY_CMPP_INBOUND_MAX_CONCURRENCY, 1024)`并发处理Submit,窗口满时停止继续读取形成TCP背压。登录、心跳和Deliver ACK不纳入Submit槽位,SubmitResp继续以原Sequence_Id关联并允许按完成顺序返回。
- 项目内gocmpp服务循环只对CMPP2/3 Submit启用并发;连接退出前等待已接受的在途处理完成后才调用会话清理,代码注释解释了这是为了防止迟到API处理重新注册已关闭连接。新增聚合指标`cmpp_gateway_inbound_submit_slots{state=configured|in_flight}`,不带账号、应用、连接或消息标签。
- 专项集成测试已证明窗口2时,第1个Submit被API阻塞后,第2个Submit可进入API并以自身Sequence_Id先返回;释放后第1个响应仍按原Sequence_Id返回。Gateway全量`go test ./... -count=1`和`go vet ./...`、项目内gocmpp测试/vet、API TypeScript正式编译、真实隔离Redis上的SendChain 113/113项、4份Stream契约、R6的102声明/14项关键测试、R7及SendChain R10门禁和`git diff --check`通过。Windows本机`go test -race`因Go工具链未启用CGO而无法运行,未伪报通过;将在Linux测试环境部署前补跑。测试环境恢复资产、部署和阶梯压测待后续补记。
- 当前只修改本地代码,没有连接或改变预生产运行版本;预生产只读标识仍为`433b2ee56f6016ad8afff1bac73f510b8fd53083+gateway-v2.cd7bb8d05e7b`。V3只允许发布到`100.93.204.60`虚拟机测试环境。
- V3首次测试环境发布后10条/秒为599/599成功、P50/P95/P99=36/78/206ms20条/秒为1199/1199成功,但P50/P95/P99=1143/5294/7107ms,仍触发5秒停止线,因此没有继续30/40/50。Prometheus同时显示认证阶段10个连接合计窗口320,但压测期入站in_flight始终为0;代码复核发现首次消息完成后`rememberDownstream`用消息级快照覆盖`byConn`时没有继承连接的`windowSize/submitInFlight`,使后续请求退回串行。该次20条/秒结果不作为修复后V3容量结论。
- 最小修复让消息级快照共享原连接窗口和原子在途计数器,并增加“消息注册后窗口32及聚合槽位仍保持”的回归断言;需重新完成Gateway/API回归、R6契约、提交、测试环境发布与10/20阶梯复测后再判断V3效果。
# 2026-08-20 CMPP压测优化V3:修复后测试环境发布与阶梯复测
- V3主实现提交为`0757a69`,消息注册后连接窗口继承修复提交为`e9c7333`;均只保存在本地`main`,未推送。最终发布目标仅为`100.93.204.60`虚拟机测试环境,运行标识为`e9c73333b37746dd8a5f35628e4fe8fdfe02237c+workspace.v3fix.467865d78510`。预生产`8.160.169.106`未发布、未回退、未压测。
- 发布前分别建立`/opt/cmpp-platform-backups/releases/20260820-114900-before-v3-inbound-test`和`/opt/cmpp-platform-backups/releases/20260820-121100-before-v3-window-fix-test`两套恢复资产,均包含PostgreSQL自定义格式备份、运行源码和平台环境配置;`SHA256SUMS`、`pg_restore --list`和tar可读性校验通过。最终修复包`outputs/cmpp-v3-inbound-fix-20260820-121000.tar.gz`共900项,SHA-256=`467865d785109f47869f6ea44e2c1f9b09c6368a812bc859ae56989caf086899`,排除了`.env`、依赖、`outputs`、`*.tsbuildinfo`、`pnpm-lock.yaml`和空文件`=`。
- 标准发布流程完成依赖安装、安全/发布门禁、Prisma检查、前端/API/Gateway构建、Nginx校验和服务重启;90条migration无待应用项。API、Gateway、Nginx、PostgreSQL、Redis、MinIO和监控服务最终均active,测试供应商连接6/6Stream消费者1且最终`pending=0/lag=0`,本轮没有Gateway Submit死信。
- 修复后阶梯结果:10条/秒实际599条,599/599受理,P50/P95/P99=`38/66/197ms`20条/秒实际1199条,1199/1199受理,`942/1427/1641ms`30条/秒实际1799条,1799/1799受理,`1266/2033/2085ms`40条/秒实际2399条,2397条SubmitResp成功、2条返回result=9`2637/3912/5201ms`。两次失败均为优先应用sequence=6等待API响应头满10秒后超时;因此40条/秒不满足零拒绝停止线,没有继续50条/秒。
- V3获得直接正向证据:20条/秒P95由V2的5580ms降至1427ms,压测期入站并发最大21;30条/秒仍无拒绝、无连接错误,入站并发最大55。当前可确认安全档位由10条/秒提升到30条/秒,拐点位于30至40条/秒。40条/秒时入站并发最大150,说明连接内窗口确实生效,不再退回串行。
- 新瓶颈转移到供应商工作池及同步回写链路:20/30/40条/秒时64个Worker槽均打满,Stream lag峰值分别约48/642/1212,测试后均排空。全窗口供应商尝试6569次,其中成功6331、失败238;成功供应商RTT平均约1040ms,成功连接等待平均约519ms,成功API回调单次平均约337ms。40条/秒最终触发两个上游API 10秒超时,V4应优先把供应商结果改为幂等Outbox/异步回调,释放Worker槽位,并保留可恢复重试和逐条ACK语义。
- 5996条业务消息均由API返回201并真实持久化,与四档客户端业务数完全一致;40条/秒的两次Gateway超时发生在API完成持久化之后,不能重投。最终状态为delivered 5768、failed 57、submitted 171,优先/普通分别为1861/4135条,全部仍识别为mobile`GatewaySubmitDeadLetter`新增0。测试客户端有限回执收集窗口不替代数据库最终状态。
- API全窗口平均`total≈1647.72ms`、`complete_submit≈1550.89ms`、`risk_frequency≈677.38ms`、`queue_publish≈242.43ms`、两次`application_lookup`合计约191.44ms、`template_match≈189.90ms`;并发消除了连接串行放大,但这些同步阶段随负载明显增长。主机CPU峰值约55.56%、内存使用峰值约32.55%,不是CPU或内存饱和。
- 优先级隔离仍未通过:40条/秒priority P95约3912ms、normal P95约3911ms,且两次SubmitResp拒绝都发生在priority连接;全部5996条均为mobile,联通/电信及六通道容量仍待号段识别修复后测试。原始目录名继续沿用既有`lg-v2-*`脚本标签,但被测运行标识和代码均为V3修复版,正式结论以运行标识为准。
- V3回归已通过Gateway全量`go test ./... -count=1`、`go vet ./...`、项目内gocmpp测试/vet、API TypeScript正式编译、真实隔离Redis上的SendChain 113/113、4份Stream契约、R6 102声明/14项关键测试、R7、SendChain R10及`git diff --check`。Linux测试机补跑`-race`时因网络无法下载仅供测试的`miniredis`和`golang.org/x/text`依赖而阻塞,未伪报通过,也未伪造外部依赖。
- 本轮只使用隔离供应商模拟器,没有发送、补发或重投真实短信,没有修改通道账号、密码、启停状态、企业余额或客户连接。`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`、`pnpm-lock.yaml`和空文件`=`继续作为受保护项排除提交。
# 2026-08-20 CMPP压测优化V4:供应商结果幂等Outbox、测试环境发布与阶梯复测
- V4将供应商分片结果和聚合结果先写入Redis Stream `gateway.submit.results`API回调由独立持续有界工作池执行,供应商Submit工作槽不再等待API往返。分片事件ID为`submit:<submitId>:segment:<index>`,聚合事件ID为`submit:<submitId>:aggregate`Lua脚本保证分片去重键与XADD原子、聚合XADD与原命令XACK原子、成功回调XACK与XDEL原子。失败事件保留在PEL并由`XAUTOCLAIM`恢复,回收阈值30秒高于10秒HTTP超时,避免多Gateway实例在回调仍执行时并发重领。
- 第91条向前兼容migration `20260820130000_add_submit_result_idempotency`为`SmsSubmitRecord`增加唯一可空`resultEventId`和`resultProcessedAt`。API重复收到同一已完成事件直接返回当前消息,冲突事件ID拒绝;测试覆盖重复回调不重复计费、重试或下游业务副作用。新增第5类Gateway队列契约示例,Outbox指标覆盖回调Worker槽位和结果Stream pending/lag。
- 本地验证通过:Gateway全量`go test ./... -count=1`及`go vet ./...`API 42套/483项断言全部通过,API与前端TypeScript正式编译、Vite生产构建、5份队列契约、R0/R6/R7及SendChain R10结构门禁、`git diff --check`均通过。全量Jest在断言完成后仍因仓库既有异步句柄不自行退出,本轮未把人工终止后的进程伪报为完整退出码0;使用本机真实Redis补跑,不伪造外部依赖。
- 仅发布到`100.93.204.60`虚拟机测试环境;预生产`8.160.169.106`只读复核标识保持`433b2ee56f6016ad8afff1bac73f510b8fd53083+gateway-v2.cd7bb8d05e7b`,未发布、未回退、未压测。测试环境发布前恢复资产位于`/opt/cmpp-platform-backups/v4-20260820T052241Z`,包含PostgreSQL自定义格式备份、运行源码、环境和systemd配置;`pg_restore --list`、源码tar可读性及`SHA256SUMS`全部通过。
- 最终运行包`outputs/cmpp-v4-runtime-final-20260820-141323.tar.gz`共827项、1641927字节,本地与测试机SHA-256均为`a63885439ed53d53a3a012048d5fd1a9aa67772503fd778ec510ec6a38a9944f`,排除依赖、构建产物、`outputs`、`*.tsbuildinfo`、`pnpm-lock.yaml`和空文件`=`。测试环境运行标识为`485af688d21ee0bdb98281f4c20d151d69f7889f+workspace.v4.a63885439ed5`;第91条migration仅应用一次,API、Gateway、安全代理、MinIO、PostgreSQL和Redis健康,最终供应商连接6/6,两条Stream均`pending=0/lag=0`。
- 首轮默认32槽10条/秒恰逢重启积压回执回放,599/599受理但回执2536、P95=3294ms;积压排空后再测仍为P95=671ms。把测试配置收敛为8槽后,10条/秒599/599、P50/P95/P99=`39/146/304ms`、回执603。基于该对照,代码、示例环境和发布文档的默认值同步改为8;32槽不作为推荐配置。
- 8槽正式阶梯结果:20条/秒1199/1199受理、P50/P95/P99=`45/1129/1259ms`30条/秒1799/1799受理、`1081/1626/1885ms`40条/秒2399/2399受理、`2049/2330/2386ms`。三档均无连接错误;相对V320/30/40条/秒P95分别由1427/2033/3912ms降至1129/1626/2330ms,且40条/秒从2条10秒超时改进为零拒绝,确认安全档位由30提升到40条/秒。
- 解耦证据:20条/秒命令Stream未投递lag峰值0,结果Outbox峰值`pending=8/lag=242`后归零;30条/秒峰值约`pending=8/lag=1076`40条/秒峰值约`pending=9/lag=1639`,压测结束后约36秒归零并连续保持0/0。40条/秒时供应商命令与结果回调已分开排队,结果回调积压不再占用供应商Submit槽;但Outbox回落时间已成为容量判定的一部分,不能只看客户SubmitResp。
- 50条/秒触发停止线:因客户端背压只生成2790条而非约2999条,2787条成功、3条等待API满10秒后返回result=9P50/P95/P99=`6765/7236/7789ms`throttled ticks=3184。结束后命令Stream一度`pending=64/lag=489`、结果Outbox`pending=8/lag=1690`;命令约1分钟内、结果随后约20秒内归零。日志显示API饱和时协议遥测和连接状态回调超时,并暴露既有`CmppDownstreamConnection`创建/更新的P2002/P2025竞态;未出现`resultEventId`唯一键冲突或Outbox事件失败。停止后未继续上探。
- 整个窗口客户侧共9984条业务提交,真实PostgreSQL按`queuedAt`精确新增9984条;窗口内7922条实际供应商提交记录全部具有非空且互不重复的`resultEventId`,重复事件组0、Gateway Submit死信0。提交结果为accepted 7392、rejected 147、timeout 383;客户有限回执收集窗口和重连积压回执不替代数据库/Stream对账。最终确认40条/秒为当前测试环境安全档,50条/秒瓶颈转为API/数据库同步入站及遥测争用,后续应继续V1的重复查询/零散写入合并和P1分阶段指标分析。
- 本轮只连接隔离供应商模拟器`100.91.249.119:17900`,没有发送、补发或重投真实短信,没有修改真实通道账号、密码、启停状态、企业余额或客户连接。压测原始目录沿用既有`lg-v2-*`名称,但被测运行标识与结论均为V4;完整V4报告保存在短信平台测试项目。受保护的`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`、`pnpm-lock.yaml`和空文件`=`继续排除提交、不删除、不归因。
# 2026-08-20 CMPP压测优化V5:API入站数据库往返治理(本地完成、待授权发布复测)
- 接管复核确认本地`HEAD=67b760a5992d7ae10d7889fe6765e895d238ab3d`、`origin/main=c4f36fc50d7906dfb2f97c881e9ea43c6a64c370`,本地领先5个提交;测试环境只读标识仍为`485af688d21ee0bdb98281f4c20d151d69f7889f+workspace.v4.a63885439ed5`,预生产只读标识仍为`433b2ee56f6016ad8afff1bac73f510b8fd53083+gateway-v2.cd7bb8d05e7b`。本轮没有发布、回退、提交或推送。
- V4高负载证据显示两次`application_lookup`合计约191.44ms、`risk_frequency`约677.38ms、`queue_publish`约242.43ms。代码复核确认每个目标号码会重复查询入口已取得的应用/企业/IP白名单;任务风控与号码频控各自调用默认规则检查,旧实现每次按5条规则逐条查询,单条短信可产生两轮共约10次存在性SQL;通用入队又回查刚创建的任务和消息。
- V5复用Submit入口已经校验的应用快照并显式传入每个目标号码,删除第二次`application_lookup`;默认规则完整性改为30秒短TTL和并发单飞,正常完整状态使用一次聚合count,失败立即清除缓存,实际生效规则、应用规则和号码频控状态仍逐消息读取;缺失时继续走既有逐规则确认和创建逻辑。刚持久化的单条CMPP内部消息使用已知taskId、messageRecordId和queuePriority直接添加BullMQ任务,不再回查任务和消息;普通批量任务继续使用原通用入队路径。
- 只读测试环境PostgreSQL `EXPLAIN (ANALYZE, BUFFERS)`确认应用查询使用`SmsApplication_cmppAccount_key`,执行约0.046ms;默认规则聚合检查使用`RiskRule_applicationId_code_key`并命中5行,执行约0.047ms。现有索引已经匹配查询,因此本轮不增加猜测性索引或migration;测试环境未安装`pg_stat_statements`,没有为诊断修改数据库扩展或配置。
- 本地API TypeScript正式编译通过;API全量42套487项全部通过,其中`RiskReviewService`与`SendChainService`专项覆盖默认规则并发单飞/短缓存/失败重试/缺失恢复、单Submit只查一次应用、已知消息直接入队且不回查任务/消息,以及既有多号码、模板、频控、计费、补发和回执回归。5份Gateway队列契约、R0、R6、R7、R10和`git diff --check`通过;R9门禁在本轮已更新的`enqueueBatchTask`哈希通过后,被HEAD既有且本轮未修改的`dispatchDueScheduledTasks`哈希漂移阻断(契约期望`8fd154...`、当前方法`37db96...`),未为通过本需求门禁而改写或归因该并行历史。Jest使用`--forceExit`收尾仓库既有异步句柄;首次从仓库根目录误启动时扫描受保护`outputs/`并使用错误转换配置,未修改或删除其中任何文件,随后在`api`目录按项目配置重跑通过。
- 当前尚未部署虚拟机测试环境或执行V5阶梯压测;`TC-CMPP-PERF-V5-005`需在取得明确发布授权、建立PostgreSQL/运行源码/环境恢复资产后执行。没有发送、补发或重投真实短信,没有修改通道账号、密码、启停状态、企业余额或客户连接;`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`、`pnpm-lock.yaml`和空文件`=`继续保护、不归因。
# 2026-08-20 CMPP压测优化V5:测试环境发布、阶梯复测与优先队列验收
- V5代码提交为`14f993c1f8e4ef5075a16c64ee8e46987054e21e`,未推送。仅发布到`100.93.204.60`虚拟机测试环境,运行标识为`14f993c1f8e4ef5075a16c64ee8e46987054e21e+workspace.v5.e38b3598c8de`;预生产`8.160.169.106`只读标识复核仍为`433b2ee56f6016ad8afff1bac73f510b8fd53083+gateway-v2.cd7bb8d05e7b`,未发布、未回退、未压测。
- 发布前恢复目录为`/opt/cmpp-platform-backups/v5-20260820T073310Z`,包含PostgreSQL自定义格式备份、运行源码、环境/systemd配置和原运行目录Git元数据。`pg_restore --list`、tar可读性和`SHA256SUMS`均通过;数据库、源码、环境资产SHA-256分别为`1d72b72b8702b66494f6c63384ba11fb7414982aac3b3dba4f2bbcf32691c6d5`、`cfa4679ffeef64d0a5d13b198bac272b53b9b01a4887371503d76591cca8d44e`、`f8aa632d622556d709d1ddaba0610e5eeeb604075ad92b8f81aa945b16c6f251`。V5运行包`outputs/cmpp-v5-runtime-20260820-153020.tar.gz`为2407264字节,本地与测试机SHA-256均为`e38b3598c8debc00d32c336831d172b492119199a7d8c843dfb774c16711fd22`。
- 标准发布完成依赖、安全/发布门禁、Prisma生成与迁移、前端/API/Gateway/安全代理构建、Nginx校验、重启和健康检查;91条migration无待应用项。API、Gateway、安全代理、MinIO、PostgreSQL、Redis、Nginx、Prometheus最终均active,隔离供应商连接6/6,命令与结果Stream最终均`pending=0/lag=0`。首次构建因部署目录旧Git元数据不能完成Go VCS stamping而在服务重启前停止;该元数据移入恢复目录并校验后,以`GOFLAGS=-buildvcs=false`按同一标准脚本重新发布成功,没有删除恢复资产。
- 原压测脚本重复使用历史`1380000xxxx`号码池,首轮10条/秒有8条被真实24小时号码频控拒绝,因此该轮明确作废、未计入V5容量。没有清除或篡改Redis/PostgreSQL频控状态;测试脚本增加可配置手机号前缀,正式五档分别使用尚无频控记录的`1390000/1370000/1360000/1350000/1340000`号码池,全部经真实API、PostgreSQL、Redis、Gateway和隔离供应商链路,且数据库均识别为mobile。
- V5正式阶梯结果:10条/秒599/599受理,P50/P95/P99=`30/105/1736ms`20条/秒1199/1199`552/735/808ms`30条/秒1799/1799`685/890/1464ms`40条/秒2399/2399`1016/1748/3111ms`。四档均为0拒绝、0连接错误,双Stream均在下一档前排空;相对V410/20/30/40条/秒P95由`146/1129/1626/2330ms`降至`105/735/890/1748ms`40条/秒继续为安全档。
- 50条/秒生成2999条,但只收到2991个SubmitResp,缺8个响应,因此按零丢响应停止线判定失败;已收到响应P50/P95/P99=`2586/2896/3895ms`0显式拒绝、0连接错误。结束时命令Stream为`pending=64/lag=1407`,约75秒后排空;结果Outbox随后也恢复0/0,所有服务保持active且API/Gateway错误日志筛查为空。该档属于可恢复过载,不作为安全容量;当前结论仍为40条/秒健康、50条/秒不健康。
- Prometheus按各60秒窗口附近75秒区间计算的API阶段平均值显示,10/20/30/40/50档`application_lookup`约为`1.42/51.04/65.54/108.64/247.65ms``risk_frequency`约`4.34/115.10/143.61/229.05/519.32ms``queue_publish`约`4.71/70.79/101.17/163.46/383.60ms``complete_submit`约`18.99/479.58/610.03/992.49/2285.77ms`。V5减少固定数据库往返后40条/秒P95继续下降,但50条/秒时同步风控、入队和持久化仍随数据库并发竞争放大,下一阶段应针对这些阶段继续做查询合并/事务缩短,而不是把50条/秒宣称为安全容量。
- 优先队列在真实积压下通过验收。BullMQ配置为priority=1、normal=10030条/秒时优先任务`queuedAt`至首条`SmsSubmitRecord.createdAt`的P50/P95=`0.786/0.988s`,普通任务为`14.678/26.282s`40条/秒分别为`2.996/3.916s`与`45.017/58.536s`。低负载10/20条/秒两类接近,符合无积压时无需插队的预期;高负载差异证明优先任务能够越过普通积压持续取得发送Worker。SubmitResp按优先/普通拆分在40条/秒P95为`1727/1741ms`,说明上游受理没有饿死普通连接。50条/秒优先任务也优于普通任务,但两类均出现几十秒下游等待,不能用优先级掩盖总容量过载。
- 本轮优先级结论只覆盖3个priority应用与7个normal应用混合、移动号段和现有六个隔离供应商账号;联通、电信号段及六通道跨运营商容量/优先级隔离仍未完成,不外推为全运营商结论。完整报告和原始`events.jsonl/summary.json`保存在短信平台测试项目。没有发送真实短信,没有修改通道账号、密码、启停状态、企业余额或客户连接;受保护的`api/tsconfig.build.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`、`pnpm-lock.yaml`和空文件`=`继续排除提交、不删除、不归因。
# 2026-08-20 完整处理500条/秒第一阶段:PostgreSQL耐久Inbox快路径(提交前验证)
- 第一阶段把CMPP Submit同步路径收敛为账号/状态/IP/Src_Id/协议最小校验和一条`CmppInboundSubmissionInbox`持久化;Gateway按已鉴权连接、Sequence_Id和载荷生成稳定请求键。重复相同Submit返回原持久化MessageId,相同请求键的冲突载荷拒绝。多号码保留稳定子MessageId,长短信在完整重组后才写Inbox,Worker处理完整正文。
- 独立`cmpp-send-worker`进程持续以默认32槽领取Inbox;短事务使用`FOR UPDATE SKIP LOCKED`和300秒过期租约,处理在领取事务外完成,失败按有上限指数退避回到pending。priority应用在领取阶段优先且类内FIFOBullMQ继续使用priority=1、normal=100。API角色不再运行发送Worker或周期扫描;Worker拥有独立Prisma连接池入口和127.0.0.1:9465指标。
- 新增持久幂等预留:日发送配额与`SmsApplicationDailyUsage`同事务写`SmsApplicationDailyReservation`,号码频控计数与`PhoneFrequencyReservation`同事务提交,余额冻结继续使用业务键;任务、API请求和短信主记录合并为一个短事务并使用确定性任务号/请求号。租约回收或进程重启不会重复计量、计频、冻结或创建业务主记录。
- Prisma新增第92条migration `20260820170000_add_cmpp_inbound_submission_inbox`,包含Inbox、日配额预留和号码频控预留三张真实PostgreSQL表及领取/租约/应用索引。发布脚本增加快路径/Worker强制门禁、systemd分进程、安全drop-in、Worker日志目录、健康检查和Prometheus target/告警;需求、系统用例、模块路线图和生产发布文档同步更新。
- 提交前验证:Prisma generate/validate、API TypeScript正式构建、前端TypeScript与Vite生产构建通过;API全量42套489项通过,Gateway全量`go test ./... -count=1`和`go vet ./...`通过,5份Stream契约、依赖/安全/部署门禁、R0/R6/R7/R10及`git diff --check`通过。R6契约只新增/更新本轮`submit.go`的稳定请求键声明。R9仍先被HEAD既有`dispatchDueScheduledTasks`哈希漂移阻断,与本轮文件和既有V5记录一致,未为通过本任务错误吸收该并行历史。Jest仍用`--forceExit`收尾仓库既有开放句柄,Vite仅保留既有大chunk告警。
- 当前尚未提交、部署或压测;下一步在排除受保护文件后提交,随后仅对`100.93.204.60`测试环境建立并校验PostgreSQL、运行源码、环境/systemd恢复资产,应用migration和独立Worker,再用隔离供应商执行同口径阶梯压测。预生产不发布、不回退、不压测;不发送、补发或重投真实短信,不修改真实通道账号、密码、启停状态、企业余额或客户连接。
## 2026-08-20 第一阶段测试环境首轮部署、UTC修复与连接池容量补丁
- 第一阶段提交`0b63bcd74e8f8be8b85aaa5f58a5e8ea7fdc636c`已部署到`100.93.204.60`测试环境。发布前恢复资产位于`/opt/cmpp-platform-backups/p1-20260820T173800-before-durable-inbox`,包含可由`pg_restore --list`读取的PostgreSQL custom dump、运行源码、环境/systemd、发布包与`SHA256SUMS`tar和摘要均通过校验。第92条migration仅在测试数据库应用,API、Gateway、独立Worker和监控均健康;预生产未修改。
- 首轮50条/秒30秒测试写入1499条Inbox,但Worker因把`YYYY-MM-DD`字符串传给Prisma DateTime以及Asia/Shanghai会话中用`NOW()`比较UTC无时区租约而反复重领。发现后立即停止Worker,未清理Inbox、未重投客户提交。修复提交`53073461e9b991978a3063a691d454b68c20ced9`改为合法UTC Date对象并在领取/退避SQL显式使用`NOW() AT TIME ZONE 'UTC'`;修复前第二套恢复资产位于`/opt/cmpp-platform-backups/p1fix-20260820T175000-before-utc-fix`且全部校验通过。重启后原1499条Inbox无需客户重发即全部完成,日限/频控预留和短信主记录均1499条,双Stream最终0/0。
- UTC修复后的第二轮50条/秒生成1499帧,收到1492个SubmitResp,其中1483成功、9拒绝、7缺响应,P50/P95/P99=`519/3385/3909ms`,按零拒绝/零丢响应停止线仍失败。数据库时间窗内1487条新Inbox最终全部completed。Gateway累计阶段证明1489次API往返成功、10次恰好10秒超时;API自身1493个`POST /api/gateway/events/inbound/submit`全部在1秒内完成,说明未归因尾延迟位于Gateway到本机API的HTTP传输,而不是SubmitResp写Socket。
- 根因补充为Go默认Transport每主机只保留2条空闲连接,无法匹配64槽入站窗口;同时PrismaPg API/Worker仍使用默认连接池上限,无法为入口和重业务事务建立容量隔离。最小补丁新增Gateway专用API Transport,最大/空闲连接数均受`GATEWAY_CMPP_INBOUND_MAX_CONCURRENCY`约束并保留10秒总超时;Prisma按角色显式使用`API_DB_POOL_MAX=32`和`API_WORKER_DB_POOL_MAX=8`。该补丁不改变最小校验、Inbox幂等、风控、计费、路由或状态机,待提交、建立新恢复资产、部署并从50条/秒重新阶梯验证。
- 容量补丁`6708f1f7c540401d1c92083407c3750693bcbb4b`发布前恢复资产位于`/opt/cmpp-platform-backups/p1pool-20260820T101000-before-capacity-isolation`PostgreSQL 55MB、运行源码187MB、环境/systemd和发布包均经`pg_restore --list`、tar读取及SHA-256校验。测试环境配置API/Worker池32/8,部署后服务、9464/9465回环指标和数据库连接正常。
- 补丁后50条/秒30秒生成1499帧,1499/1499成功、零拒绝、零连接错误,P50/P95/P99=`1391/3460/4205ms`1499条Inbox全部completed,双Stream在注入结束约62秒后归零,入口停止线通过。100条/秒档只生成2719帧(实际90.6条/秒),虽2719/2719成功且P95=4277ms,但客户端窗口被压满1346次,未达到100条/秒目标并停止升档;此时API受理2719个请求全部小于250ms,而Gateway API往返平均3.305秒。
- 100档同时存在大量供应商Submit、回执和通讯日志;`inbound.Server`此前让Submit、协议日志、回执恢复和连接事件共享同一64连接Transport,后台流量仍能占满Submit传输槽。第二个最小补丁将Submit池按入站窗口独立,后台池固定16连接;保留10秒超时和全部日志/回执功能,不靠删除遥测通过压测。该补丁待专项验证、提交和再次建立恢复资产后发布复测。
- 第二个容量补丁`229a0b28fd8b84d910c359ff9ac442fc3e843cb4`经Gateway全量测试/vet、R6 104声明契约和部署门禁通过。发布前恢复资产`/opt/cmpp-platform-backups/p1submitpool-20260820T102400-before-dedicated-submit`包含PostgreSQL、运行源码、环境/systemd和发布包,均经列表、tar和SHA-256校验;测试环境标记为`229a0b28...+workspace.p1submitpool.f50505ad9ee9`,服务与启动日志正常,预生产未修改。
- 专用Submit池后100条/秒30秒发满2999条,2999/2999成功、零拒绝/节流/连接错误,P50/P95/P99=`42/147/173ms`API平均约37ms、Gateway API往返平均约54ms2999条Inbox全部completed,完整供应商链从开始到双Stream排空约132秒,折算约22.7条/秒。200条/秒20秒发满3998条,3998/3998成功、零拒绝/节流/连接错误,分位=`134/370/837ms`Inbox在开始后约75秒全部完成,双Stream在开始后约166秒排空,完整链折算约24.1条/秒。
- 默认API池32、Submit池64下首次500条/秒10秒只生成1716条,1716/1716成功但节流615次,P95=5217ms,实际171.6条/秒,失败停止。基于PostgreSQL`max_connections=100`和进程连接证据,仅在测试环境把`API_DB_POOL_MAX`调为48、`GATEWAY_CMPP_INBOUND_MAX_CONCURRENCY`调为128Worker仍为8;复测生成2979条,2979/2979成功、零拒绝/连接错误,P50/P95/P99=`942/1162/3221ms`,但仍节流611次,实际297.9条/秒,500入口仍失败。10个测试连接各窗口32形成320总在途,Gateway平均往返约965ms,实测上限与窗口理论值一致;API平均约322ms,继续只加连接会放大PostgreSQL竞争。
- 最终数据库按四个新号码前缀对账:`1390005/6/7/8`的Inbox completed分别为`2999/3998/1716/2979`,对应`SmsMessageRecord`及唯一MessageId数量完全相同,非completed Inbox为0,命令Stream和结果Outbox均`pending=0/lag=0`,相关服务日志无panic/fatal/Prisma错误或Inbox retry。第一阶段结论为200条/秒入口可靠受理通过、500条/秒入口未通过、完整异步链约24条/秒;不得宣称已完整处理500条/秒。下一阶段必须合并每Submit应用查询与Inbox写入、提高测试连接/窗口总量,并把Worker业务事务、供应商六通道总TPS及结果/回执写入水平扩容,不能再靠单机连接池参数解决。
## 2026-08-20 完整处理500条/秒第二阶段:合并入口SQL与全链有界扩容(实施中)
- 本轮重新核对本地`HEAD=633e7a705539cc706aa0a6dbabfd47cc61265e7f`、`origin/main=c4f36fc50d7906dfb2f97c881e9ea43c6a64c370`;测试环境运行标识为`229a0b28fd8b84d910c359ff9ac442fc3e843cb4+workspace.p1submitpool.f50505ad9ee9`,预生产仍为`433b2ee56f6016ad8afff1bac73f510b8fd53083+gateway-v2.cd7bb8d05e7b`。受保护的构建产物、`outputs/`、`pnpm-lock.yaml`和空文件`=`保持原状,不归因本轮。
- Worker累计真实指标4695条显示:预检、模板、消息持久化、风控频次、计费和入队平均约`83.9/74.5/28.3/92.2/25.2/64.7ms`,与上一阶段完整链约24条/秒一致。该证据确认不能把入口吞吐冒充完整处理能力。
- 普通短短信快路径已改为单个PostgreSQL CTE:使用账号唯一索引读取应用和企业当前状态,在同一快照校验接口、IP白名单及Src_Id,并以请求键`ON CONFLICT DO NOTHING`幂等写Inbox和稳定响应。正常路径不再先执行Prisma应用查询;仅并发唯一键竞争且当前快照看不到胜者时执行一次只读恢复,避免用自更新制造表膨胀。长短信分片状态机保持不变。
- Inbox Worker领取后改为按本批唯一`applicationId`一次查询应用、企业和白名单,再逐条处理;不做跨批应用状态缓存,领取事务仍不包住风控、计费、Redis或供应商调用。专项SendChain 121项、API全量42套493项、API与前端TypeScript、Vite生产构建、Prisma validate、Gateway全量测试/vet、5份Stream契约、R0/R6/R7/R10、安全/部署门禁和`git diff --check`均通过;R9仍只被HEAD既有`dispatchDueScheduledTasks`哈希漂移阻断,未改写该方法。提交、恢复资产、测试环境发布和100→200→500阶梯结果待后续补记。
- 主提交`99fb346c125b0f620641562c50ad517a7682a10f`发布到测试环境后,100条/秒首轮2998个请求全部收到业务拒绝且API返回500,立即按停止线终止升档。日志给出PostgreSQL `42P18 could not determine data type of parameter $11`;参数定位为`jsonb_build_object`的多态value位置没有为MessageId/phoneCount声明类型。该轮没有新增Inbox或业务短信,不计容量结果;修复为显式`text/integer`类型后须重新走门禁、提交和发布验证。
- 类型修复提交为`f4560479d3bcb9f1b1a6fc9b1b2664a997cdf851`,测试环境最终标识为`f4560479...+workspace.p2fix.51553e0d5555`,未推送。首次发布恢复资产`/opt/cmpp-platform-backups/p2-20260820T105600Z`和修复发布恢复资产`/opt/cmpp-platform-backups/p2fix-20260820T110500Z`均包含PostgreSQL custom dump、完整运行源码、环境和systemd,分别通过`pg_restore --list`、tar读取与SHA-256校验。最终修复包大小2431905字节,本地/测试机SHA-256均为`51553e0d5555ee6a6f3317cc1a4b99410d2c0cd717ad37eac0fc839e91baa2fd`92条migration无待执行项,API/Gateway/Worker/PostgreSQL/Redis/Nginx/Prometheus均active。预生产只读标识仍为`433b2ee56f6016ad8afff1bac73f510b8fd53083+gateway-v2.cd7bb8d05e7b`,未发布、未回退、未压测。
- 仅在测试环境连接总预算内设置API/Worker池48/32、Inbox业务槽96、BullMQ发送槽96、Gateway Submit槽128、结果Outbox槽32和客户入站上限128;代码默认值未改变,PostgreSQL`max_connections=100`仍保留至少20条非业务池余量。修复后1条/秒低负载9/9受理、P95=41msInbox与短信主记录均9条且MessageId唯一,双Stream归零。
- 正式100条/秒30秒档生成2998条,2998/2998成功,零拒绝、零节流、零连接错误,P50/P95/P99=`34/79/128ms`;相较第一阶段100条/秒P95=147ms,合并SQL在更高Worker竞争下仍降低入口尾延迟。数据库2998条Inbox全部completed、2998条短信主记录及唯一MessageId完全对账,Inbox从首条创建至末条完成约52.1秒,折算约57.5条/秒。
- 该档未通过“完整处理100条/秒”停止线:全部为移动号码并只走`LGST-M-P`主通道,最终产生3863次供应商尝试,其中accepted3118、rejected78、timeout667;回退通道接受846次。命令Stream和结果Outbox从首条接收至最终0/0约136秒,按2998条业务短信折算约22.0条/秒;最终消息delivered2797、failed70、submitted131。高峰期间API后台协议日志、连接状态和待投递查询出现超时,说明提高Worker/Outbox槽后共享API/数据库回调仍受争用。因100档完整链已经失败,按阶梯停止线没有继续200/500档,不能宣称完整500条/秒达标。
## 2026-08-21 完整处理500条/秒第三阶段:业务Worker批处理与数据库竞争治理(实施中)
- 接管复核:本地`HEAD=57192b7586b1e2c14f2edf0633d2d35936352879`、`origin/main=c4f36fc50d7906dfb2f97c881e9ea43c6a64c370`ahead 15;测试环境标记`f4560479...+workspace.p2fix.51553e0d5555`,预生产标记`433b2ee5...+gateway-v2.cd7bb8d05e7b`。测试机API/Worker/Gateway/PostgreSQL/Redis/Nginx/Prometheus均active92条migration、数据库6连接/无idle in transaction/无未授予锁,Inbox和双Stream均排空;预生产仅只读核验,未修改。
- 当前实现把Worker按默认64条组成有界业务批次:批次共享应用、模板、签名、黑名单、风控规则和敏感词只读快照;日限额按applicationId固定顺序锁定并为每条请求写独立预留;唯一号码频控按应用在短事务批量更新并逐条持久化决定;正常零计费单号码的任务、API请求和消息三表在一个短事务批量创建,再以MessageId作为BullMQ Job ID批量入队和逐条结算Inbox。
- 正单价、同号重复、业务拒绝、人工审核、歧义匹配、既有消息和其他异常保留原逐条状态机。批量路径任一步失败会使用稳定日限/频控键、确定性任务号/请求号、MessageId和队列Job ID逐条恢复;Redis发布不包在数据库事务中。新增固定阶段`worker_claim/reference_preload/daily_quota`并保留`risk_frequency/message_persist/queue_publish`。
- 当前本地API正式TypeScript编译通过;RiskReview、PhoneFrequency、SendChain专项3套145项通过。尚未提交、建立本次恢复资产、部署或压测;后续结果必须按smoke→100→200→300→500停止线补记,且零计费批量结果不得外推为付费链路吞吐。
- 第三阶段代码提交`52028b9bbdea20f0cd02efe792e91b558ba50be9`,未推送。API全量42套495项、Prisma validate/generate、API与前端正式构建、Gateway全量test/vet、5份Stream契约、安全/部署门禁、R0/R6/R7/R10、Bash语法和`git diff --check`通过;R8/R9分别被HEAD既有且本轮未修改的`GatewayInboundSubmitDto`与`dispatchDueScheduledTasks`契约漂移阻断,没有为通过门禁吸收无关历史。
- 本次测试环境恢复资产位于`/opt/cmpp-platform-backups/p3-20260821T014531Z-before-batch-worker`PostgreSQL custom dump 96897546字节、运行源码189193980字节、环境/systemd/Nginx/Prometheus配置包23127字节,全部0600`pg_restore --list`、两份tar读取和`SHA256SUMS`全部通过,恢复说明明确Gateway→API→Worker启动顺序。精确发布包2441194字节,本地/服务器SHA-256均为`7c14cd5f197a0fa049748bea44b9a99b28f2ca1b5a23c4d6bce4ec8f22f1f9eb`。
- 首次发布在Prisma输出Unicode勾号时,本地Windows GBK日志转发进程异常关闭SSH通道,远端失败保护自动恢复原运行目录、环境和服务;恢复后标记仍为`f456047...p2fix`且三服务/健康检查正常,失败目录保留为`/opt/cmpp-platform.failed-p3-20260821T014701Z`。改用UTF-8二进制日志后复用同一已校验包成功发布;当前标记`52028b9b...+workspace.p3.7c14cd5f197a`,上一运行目录`/opt/cmpp-platform.previous-p3-20260821T014803Z`92条migration无待应用项。
- 发布后API/Worker/Gateway/PostgreSQL/Redis/Nginx/Prometheus全部active,批处理显式启用、批次64、Worker槽96、API/Worker池48/32;数据库7连接、无未授予锁/idle in transactionInbox和双Stream初始排空。隔离供应商模拟器健康且6条连接在线,未连接或修改预生产。
- smoke使用新前缀`1380010`1条/秒10秒生成9条,9/9受理、零拒绝/节流/连接错误,P50/P95/P99=`30/71/71ms`;数据库9条消息、9个唯一MessageId,最终9条deliveredBullMQ与双Stream排空,Worker无warning,数据库无锁等待或idle in transaction。
- 100条/秒30秒使用新前缀`1380011`:生成2998条,2998/2998受理,零拒绝、零节流、零连接错误,P50/P95/P99=`28/71/181ms`。2998条Inbox全部completed,消息/唯一MessageId/任务/API请求/日限预留/频控预留均2998且任务号、请求号无重复;创建窗口29.954秒,最后一条创建后1.418秒完成,完成分布32个秒桶、平均93.69条/秒、P50/P95=`96.5/121`、最大124条/秒。批量阶段累计180次reference preload/日限批次、216次三表持久化/批量入队,证明不是逐条伪装。
- 100档注入结束时命令Stream`pending=128/lag=922`、结果Stream`pending=32/lag=31`,数据库瞬时`idle in transaction=3/waiting active=12/not-granted locks=7`;约25秒后数据库恢复0/0/0、双Stream恢复0/0。自开始至最终排空约87秒,按2998条折算完整下游约34.5条/秒,低于100条/秒;最终消息delivered2770、failed64、submitted164,隔离供应商本档累计提交尝试3281、accepted3226、rejected55、无回执69,错误0。
- 因100档下游队列在负载期持续增长且完整链不足100条/秒,严格按停止线没有执行200/300/500档。第三阶段结论:入口100条/秒和业务Inbox接近实时排空通过、相较第二阶段约57.5条/秒显著改善,但业务Worker500条/秒与完整链500条/秒均未证明;第四阶段仍需供应商六通道真实并行、发送链/回调独立工作池后再升档。测试应用单价为0,本结果不得外推正单价批量计费吞吐;正单价继续走已回归的逐条原子账务路径。
- 全程仅使用`100.93.204.60`测试环境和`100.91.249.119:17900`隔离供应商模拟器,没有发送、补发或重投真实短信,没有修改通道账号、密码、启停状态、企业余额或客户连接。预生产只读标记保持`433b2ee5...+gateway-v2.cd7bb8d05e7b`,未发布、未回退、未压测;受保护的`tsbuildinfo`、`outputs/`、`pnpm-lock.yaml`和空文件`=`继续排除提交、不删除、不归因。
## 2026-08-21 完整处理500条/秒第四阶段(实施中)
- 接管复核:本地`HEAD=0176aa6952f1e71a50a8f49eeaa64e307da02370`、`origin/main=c4f36fc50d7906dfb2f97c881e9ea43c6a64c370`;测试环境仍为`52028b9b...+workspace.p3.7c14cd5f197a`,预生产只读标记仍为`433b2ee5...+gateway-v2.cd7bb8d05e7b`。测试机六连接在线、双Stream 0/0、数据库无等待锁和idle in transaction。
- 10个隔离应用仍为单价0、同企业余额1/授信0;移动主备各200条/秒,联通/电信主备各150条/秒,窗口32。组项目为主10/备用20,默认只能三主主动承载,六连接在线不等于六通道并行。
- 已实现正价Worker批次、覆盖本次金额的余额判断、单事务释放/扣费、零价免账户流水,以及同最低优先级非备用通道的稳定weighted分流;默认主备语义不变。API正式编译和Billing/纯策略/SendChain三套143项通过。
- 部署、恢复资产、测试充值、临时六通道主动双活、smoke及阶梯结果待补记;所有临时配置只允许在测试环境先快照后变更并在测试后恢复。
- 首轮正价三运营商100条/秒生成2999条,2999/2999 SubmitResp成功、P50/P95/P99=`32/68/130ms`Inbox与唯一MessageId均2999;移动/联通/电信分别998/996/1005,六通道最终各承载488至514条,证明主动双活与跨运营商分流有效。注入结束时仅388条完成扣费,命令Stream`128/2131`、结果Outbox`32/192`、等待锁/idle in transaction各5,按停止线不升200档。
- 该轮最终双Stream归零,冻结/释放各2999、正式扣费2987、退款30、12条供应商最终拒绝只释放不扣费;SmsBillingRecord为charged2957/refunded30,余额恒等式精确成立,六通道与数据库最终无等待锁/idle in transaction。证据确认瓶颈是每个正价Submit结果在企业账户锁上串行,而不是单价0时可见的通道容量。
- 后续最小修复将正常“释放冻结+正式扣费”改为单个幂等SQL:冻结已在入口扣减,流水对净余额为零,因此正常结算不再取得账户锁或更新账户;历史已释放未扣费状态仍用原带锁路径补扣,并保留并发`ON CONFLICT`后一次MVCC恢复读。专项134项和TypeScript已通过,完整门禁、修复提交、新恢复资产与复测待补记。
- 无账户锁修复后100条/秒复测仍在注入结束出现命令Stream`128/1687`、结果Outbox`32/452`;相同观测点完成扣费从388提高至637、等待锁降为0,但单分片短信同时发布分片与聚合两个结果事件,仍造成约双倍API回调和分片审计写入。新增最小Gateway修复:单分片只发布已携带完整segments的聚合事件,多分片仍逐片先持久化,待新恢复资产和同口径复测。
- 单分片回调收敛后第三轮100条/秒生成2999条,2999/2999受理,P50/P95/P99=`31/71/191ms`,三运营商`998/996/1005`、六通道`480至518`。注入期命令/结果Stream已排空但一度有2227条`submit_queued`,最终BullMQ wait/active/failed/delayed均0,消息2910 delivered、34 failed、55 submitted;冻结/释放各2999、charged 2987、refunded 21SmsBillingRecord charged 2966/refunded 21,余额恒等式准确,数据库0等待锁/0 idle in transaction。该证据把剩余瓶颈定位到BullMQ发送Worker的逐消息数据库热路径,仍未达到全链100条/秒,因此没有升200档。
- 热路径确认每条提交结果和回执都会并发执行整批`SmsMessageRecord GROUP BY status`并更新任务。最小修复对同进程同批次刷新做单飞合并,并在运行中查询后出现新状态时保留一次尾随刷新,不缓存业务结果。新增`TC-CMPP-500-P4-010`SendChain专项122项与API正式TypeScript编译通过,部署和同口径100档复测待补记。
- 单飞修复提交`90345fba22e3ae183e1edb4fdae718fb7cb2d963`;部署前新恢复资产`/opt/cmpp-platform-backups/p4-20260821T030748Z-before-paid-six-channel`包含121MB PostgreSQL dump、181MB运行源码、24KB系统配置,`pg_restore --list`、两个tar目录及SHA256全部通过。首次发布因本地SSH输出端GBK无法编码Prisma成功符号而中断,远端部署脚本自动回滚至`3c6f1be...`且所有服务健康;修正本地UTF-8输出后使用同一哈希校验包重新发布成功,测试标记为`90345fba...+workspace.p4progress.d82933c344ec`92个migration无待执行项。
- 发布后正价smoke使用`1380027/1300027/1890027`9/9受理并deliveredP50/P95/P99=`35/250/250ms`,冻结/释放/扣费各9笔且金额均2925,余额精确减少2925,双Stream排空、数据库0锁等待/0 idle in transaction。
- 最终100条/秒30秒使用`1380028/1300028/1890028`2999/2999受理、零拒绝/节流/连接错误,P50/P95/P99=`30/63/96ms`;移动/联通/电信`998/996/1005`,六通道各承载479至517。中间审计完成扣费1391笔,较修复前同口径805笔显著改善,但仍有1651条`submit_queued`及命令Stream`128/1322`;最终消息2815 delivered、43 failed、141 submitted,冻结/释放各2999、charged 2988、refunded 32SmsBillingRecord charged 2956/refunded 32,双Stream和数据库最终0/0。首条入队到最后供应商提交167.991秒,完整提交约17.85条/秒,100档仍失败,故未执行200/300/500。
- 第四阶段全部隔离正价样本共12040条,金额单价均325;冻结/释放各12040笔、总额3913000charged 11992笔/3897400refunded 125笔/40625。SmsBillingRecord最终charged 11867/refunded 125;测试账户从初始1经审计充值20000000、扣费与退款后余额16143226,恒等式`1+20000000-3897400+40625=16143226`成立。
- 测试结束已恢复配置:同企业11个应用单价均0;三主通道priority10/非备用、三备priority20/备用,weight均1003条临时运营商规则已删除并重启Worker。真实充值、扣费、退款和操作日志保留作为审计事实;六连接在线,双Stream 0/0,数据库0等待锁/0 idle in transaction。预生产未发布、未压测、未写入;本地未push,受保护工作区文件未纳入提交或删除。
## 2026-08-21 第四阶段停止优化后的主流程回归
- 按用户决定停止继续性能优化,新增`docs/phase-4-send-worker-optimization-plan.md`只记录后续诊断、P0至P3实施顺序、正确性约束和验收停止线。本轮不再修改或部署性能代码,不再执行阶梯压测。
- 测试环境标记保持`90345fba...+workspace.p4progress.d82933c344ec`。回归前六个隔离供应商连接在线,API、Worker、Gateway、Nginx、PostgreSQL、Redis均active且健康,数据库无等待锁。仅将测试应用`920001`单价从0临时改为325金额单位,保留前后快照和操作日志。
- 客户CMPP最小真实样本生成2条:2/2 SubmitResp成功,P50/P95/P99=`18/20/20ms`。按本轮开始时间和专用号段`1380031`直接核对真实数据库,Inbox completed 2、SmsSubmitRecord accepted 2、SmsReceiptRecord delivered 2、消息delivered 2,客户侧状态回执下游投递delivered 2。
- 正价计费闭环通过:两条消息单价325、总金额650;冻结/释放/正式扣费各2笔且金额分别为`-650/+650/-650`SmsBillingRecord charged 2,无重复、无退款;测试账户余额从16143226精确降至16142576。
- 在客户CMPP连接保持在线期间,经测试机内部Gateway事件入口注入一条携带实际`messageId/channelId/phoneNumber`的上行事件。`SmsUplinkMessage`按messageId精确匹配原应用和下发记录,内容“主流程回归上行短信”;客户端捕获`registered=0`普通Deliver并返回ACK`CmppDownstreamDelivery`最终uplink delivered 1。该步骤验证Gateway事件入口至API入库、匹配和客户下行Deliver/ACK;供应商到Gateway的原始CMPP Deliver解包由随后Gateway全量`go test ./... -count=1`和`go vet ./...`覆盖,本轮未伪称为真实供应商上行报文注入。
- 客户连接上线时还收到历史pending回执补投,因此客户端汇总`receipts=283`不能作为本轮回执数量;本轮严格使用开始时间、专用号段、MessageId和数据库外键隔离,新增回执事实为2条、上行为1条。该现象是既有待投递恢复行为,不归因到本次新增短信。
- 回归结束已把`920001`单价恢复为0并保存after快照;双Stream pending/lag均0,数据库0等待锁/0 idle in transactionAPI/Worker/Gateway均active。真实消息、计费、回执、上行和操作日志保留审计,预生产未变更。
## 2026-08-21 CMPP发送准入、频控、通道禁用与通道组补发专项复测
- 本轮只在`100.93.204.60`测试环境、`qa-bell-alerts-tenant`隔离企业及`910001`至`920007`压测应用执行;供应商为`100.91.249.119:17900`本地模拟器,没有触达预生产或真实短信。每个用例仅发送1条,号码频控用例发送同号2条;判定采用本次MessageId对应的PostgreSQL消息、提交、频控和回执事实,不采用客户端重连时收到的历史积压回执数。
- 签名审核拦截通过:`920002`签名临时从`approved`改为`pending`后,消息`MSG-eedf1831-7c2c-425c-98be-8a4befcc8446`最终为`failed/SIGNATURE`,错误为“短信内容未识别到已审核通过的签名”,供应商提交0条。签名状态已恢复。
- 模板强校验通过:压测应用默认没有模板且`templateMismatchMode=direct_send`,因此先将`920003`临时切为`reject`模拟必须报备模板;消息`MSG-3d3bea6a-3de8-4052-8aae-3ed613736b2f`最终为`failed/TEMPLATE`,错误为“短信内容未匹配到已报备模板”,供应商提交0条。应用模式已恢复`direct_send`。
- 余额不足通过:`920004`临时单价325、企业可用余额临时置0后,消息`MSG-aaeb23b1-b18b-4f6b-8b41-0e610d244e9b`按325计算并最终为`failed/BALANCE`,供应商提交0条。应用单价已恢复0,账户余额/授信已恢复`16142576/0`。
- 企业应用禁用/删除通过:分别关闭`interfaceEnabled`、把应用状态改为`inactive`和`deleted`时,客户CMPP登录均返回状态码3并断开,未进入提交阶段;恢复后`920005`为`active/interfaceEnabled=true`。企业禁用/删除通过:企业状态分别为`inactive`和`deleted`时,`920006`登录均返回状态码3;企业已恢复`active`。
- 号码频次通过:为`920007`临时建立5分钟1条的应用级规则,同号`13800310000`第1条真实提交并`delivered`,第2条`MSG-40004fe5-21e0-41f2-8bc4-388d00ec6b2d`最终为`failed/RISK`、供应商提交0条;命中记录为阈值1、实际2。临时规则已删除,命中历史作为测试审计保留。
- 通道签名报备拦截通过:将`910001`签名在移动主备两通道的报备任务临时改为`pending`后,消息`MSG-2c52fdc8-bc42-4287-a325-6780781ee2a3`最终为`failed/ROUTE`,错误为“无已报备通过且在线的可用通道”,供应商提交0条;2条报备任务均已恢复`approved`。
- 通道禁用行为通过:仅禁用`LGST-M-P`时,消息`MSG-fc4a6384-3dfd-4252-bc5b-855e4e881a1a`自动选择`LGST-M-B`并`delivered`;主备同时禁用时,消息`MSG-5bf5960f-cfc1-4409-a6bc-80e6969ad827`最终为`failed/ROUTE`且供应商提交0条。两通道均已恢复`active`。
- 通道组补发通过:模拟`LGST-M-P/SUP001`对消息`MSG-3c2ad6ea-9b45-435c-8833-7dbf7bf28ebd`返回Submit结果码8,首条提交记录为`rejected`;平台随后在`LGST-M-B`创建带`retryOfSubmitRecordId`的第二条提交,状态`accepted`,消息最终`delivered`。模拟器已恢复普通配置,6条通道连接均为`connected`。
- 最终恢复审计:API及API/Worker/Gateway/PostgreSQL/Redis/MinIO服务健康;10个隔离应用全部`active`、接口全部开启、单价均0、模板模式均`direct_send`;10个签名审核/汇总报备均通过,60条签名通道报备任务全部`approved`6个LGST通道全部`active/connected`;临时风险规则0条;Inbox仅有`completed`状态;专项窗口Worker严重错误筛查0条。
## 2026-08-24 第四阶段后续优化第1步:现状复核与恢复准备
- 本地`HEAD`与`origin/main`均为`c6f11014d61a8627ae311098ef81d89dd099ffaa`。既有`api/tsconfig.build.tsbuildinfo`、`api/tsconfig.tsbuildinfo`、`tsconfig.tsbuildinfo`、`outputs/`、`pnpm-lock.yaml`、空文件`=`以及本轮接管时已存在的`tmp_generate_ui_drafts.py`、`tools/local/seed-screenshot-materials.mjs`均未修改、删除或纳入本轮范围。
- 测试环境运行标记仍为`90345fba22e3ae183e1edb4fdae718fb7cb2d963+workspace.p4progress.d82933c344ec`API、Worker、Gateway、安全代理、PostgreSQL、Redis、MinIO和Nginx均activeAPI健康、Redis PONG。数据库约1348MB、92条已完成migration、11/100连接、0等待锁、0 idle in transactionInbox只有36968条completed。10个隔离应用均active/接口开启/单价0,测试企业余额/授信为`16142576/0`。
- 两条Gateway Stream的消费者均为1、`pending=0/lag=0`。BullMQ `sms.send.queue`为wait/active/failed/delayed均0`gateway.submit.queue`保留76984条wait,而同口径命令Stream已经完整消费,作为后续双发布职责梳理的当前证据,本步未清理或改写任何队列。
- 当前`pg_stat_statements`未安装且未加入`shared_preload_libraries`,记录为第2步可观测性准备项,本步未修改PostgreSQL扩展或配置。隔离供应商模拟器`100.91.249.119:17900`当前不可达,六个LGST连接状态均为failed且最后心跳停在2026-08-21;平台和数据库服务正常,但后续真实发送/压测前必须先恢复模拟器并确认6/6重连。
- 已创建root专属恢复目录`/opt/cmpp-platform-backups/phase4-step1-20260824T020501Z`,权限700。包含129MB `database.dump`、183MB `runtime-source.tar.gz`、48KB `system-config.tar.gz`、运行标记、服务状态、PostgreSQL版本、92条迁移清单及内容目录;`pg_restore --list`识别818项,源码归档内运行标记一致,全部SHA-256复核通过。数据库/源码/系统配置SHA-256分别为`5b6aec796314947b44d7d6323665036927f326994e0f598f32559a06802b03c9`、`7be9da3a51a11048bfdc43b4923285bd7e34a07b8a95f7b983bf92735d525d6a`、`1de39e5dbf4a699123c9f2dab9ffae85092c8bd194c0e7f00e630d51257132be`。备份后磁盘仍剩62GB,服务、API、Redis和两条Stream复核正常。
- 本步没有修改业务代码、数据库业务数据、通道配置、余额、客户连接或预生产环境,没有发送短信、部署或压测。第1步完成;进入第2步前的显式前置条件为恢复隔离供应商模拟器并确认6/6连接。
## 2026-08-24 第四阶段后续优化第2步:P0可观测、测试环境发布与正价诊断
- 恢复本地隔离供应商模拟器并通过Tailscale Serve将测试机到`100.91.249.119:17900`的访问转发到本机回环仿真器;重启测试Gateway后平台和模拟器均确认6/6连接。测试结束模拟器继续运行且6连接在线;未触达预生产或真实供应商。
- 测试机已有`postgresql-contrib`和`pg_stat_statements.so`,无需联网安装新包。新增`/etc/postgresql/16/main/conf.d/20-pg-stat-statements.conf`,设置`shared_preload_libraries='pg_stat_statements'`、max10000、track=all、track_utility=off并创建扩展;PostgreSQL重启后扩展、预加载、视图读取均通过,未调整`max_connections`或`work_mem`。
- 发送Worker增加固定低基数分段直方图、BullMQ六状态、Worker槽位、处理结果和数据库客户端池`max/total/idle/waiting`Prisma继续使用原API/Worker池上限,仅改为显式持有同一个pg Pool以读取原生计数。指标不含手机号、企业、应用、通道、消息或任务ID。API全量42套498项、SendChain 122项、相关专项124项、TypeScript正式构建和`git diff --check`通过。
- 发布前恢复资产`/opt/cmpp-platform-backups/phase4-step2-20260824T023615Z`包含128MB PostgreSQL custom dump、181MB运行目录、56KB系统配置、恢复说明、迁移/服务清单及测试配置快照;`pg_restore --list`、两份tar目录和全部SHA-256通过。基础包/工作区补丁SHA-256分别为`d0f3311830932e3ebb4e3aea3a7bb6a9136f5acce73c9e7dd6e327953e35a24a`和`045215c9a9ac3c2a09a8a2402cdb7a1f3d998deb74ff9fdee6e7e266b03af0da`;排除`outputs/`、`pnpm-lock.yaml`、空文件`=`和`*.tsbuildinfo`。
- 仅发布到`100.93.204.60`测试环境,运行标记为`c6f11014d61a8627ae311098ef81d89dd099ffaa+workspace.phase4step2.045215c9a9ac`92条migration无待执行项,部署安全门禁、API/Worker/Gateway/PostgreSQL/Redis/MinIO/Nginx及回环metrics均健康。预生产未发布、未回退、未压测。
- 正价smoke生成9条,9/9受理、P50/P95/P99=`34/54/54ms`,计费charged 9笔共2925金额单位;Worker 11个阶段count均为9,数据库池waiting为0。客户连接同时ACK了2483条历史pending回执,因此该回执数不作为本轮新增回执证据,随后重置`pg_stat_statements`和Worker指标再进入压力档。
- 首次100档因测试库没有`PhoneCarrierRule`,仿真联通/电信号默认归为移动,只压到移动主备;2999条生成、2997个SubmitResp、2个缺失,257次客户端节流,P99=1773ms,按停止线不升档。该轮仍给出关键对照:两个会话热点下`submit_transaction`累计669.331秒、Worker池waiting峰值38、开放会话UPSERT累计557.234秒。
- 快照后临时增加只匹配`1380028/1300028/1890028`的三条运营商规则并重启Worker,修正后的六通道100档为2999/2999受理、零拒绝/节流/连接错误,P50/P95/P99=`31/68/233ms`;移动/联通/电信=`998/996/1005`。六供应商账号各收到588至612次提交尝试;2999个唯一号码的首次供应商提交从`02:55:20.074Z`到`02:56:53.068Z`,覆盖`92.994秒`、约`32.25条/秒`,完整100条/秒目标仍失败,未执行200/300/500。
- 六通道诊断阶段均值:message_load约22.7ms、phone_routing约18.5ms、route_lookup约33.5ms、signature_candidates约7.0ms、signature_final_check约6.8ms、rate_limit约6.8ms、submit_transaction约47.4ms、BullMQ发布约7.1ms、Stream发布约6.9ms、task_progress约18.2ms、total约175.1ms。180秒采样峰值为Worker in_flight24、数据库池total32/waiting3、PostgreSQL未授予锁20;结束均归零。
- `pg_stat_statements`进一步确认正价入口企业账户`pg_advisory_xact_lock`累计390.932秒/587次、均值665.983ms;开放会话`CmppSubmitSession` UPSERT累计32.293秒/3616次、均值8.931ms。P1应先治理企业账户批次锁竞争和六个开放会话热点行,再处理路由、号码回写、任务进度与重复Gateway入口;本步不执行P1代码优化。
- 日志复核发现两个非本次指标代码引入但需后续处理的相邻问题:部署后定时报表刷新有1次5秒交互事务过期;压力客户端连接关闭/重建竞争触发`CmppDownstreamConnection`的P2025/P2002。发送Worker无uncaught/fatal,当前窗口6006个Inbox全部`completed/attempts=1`,服务、连接和Stream最终恢复正常;本步只记录证据,不扩展为业务修复。
- 本轮精确6006条正价消息(smoke 9、单运营商误测2998、六通道2999)冻结/释放各6006笔、金额1951950;正式charged 5991笔/1947075,退款73笔/23725SmsBillingRecord最终charged5918/refunded73,当前样本净扣1923350,账务链一致。测试窗口还处理了103条历史消息退款,因此账户从16159476到14269601的总变化以窗口全量账务净额核对,不能只用本轮MessageId计算。
- 最终已恢复10个隔离应用为active/接口开启/单价0,三主通道priority10/非备用、三备priority20/备用、weight100,删除3条临时运营商规则并重启Worker6通道active/connected,两条Stream pending/lag均0,数据库0 idle-in-transaction、0锁等待、0未授予锁,8项服务active。真实消息、账务、回执和操作日志保留审计;受保护工作区文件未纳入发布或删除。
## 2026-08-24 第四阶段后续优化下一步:P1低风险数据库往返收敛
- 实施四项低风险收敛:CMPP单号码任务提交按已知状态直写,结果/回执/超时用单条`UPDATE ... FROM`读取唯一消息状态并直写;路由、在线连接与签名运营商报备合并为一次候选查询并删除最终二次报备查询;Worker首次读取后复用开放会话ID,事务不再逐短信更新`submitTotal`;确认Go Gateway只消费Redis Stream且具备PEL自动认领、逐条ACK、结果Outbox和死信,发送Worker停止向无人消费的`gateway.submit.queue`同步写副本。Redis Stream发布前的跨介质崩溃窗口尚无独立PostgreSQL Outbox扫描器,明确留作P2残余风险。
- 本地API全量42套500项、SendChain 124项、TypeScript正式构建和`git diff --check`通过。两次部署前分别建立`/opt/cmpp-platform-backups/phase4-p1-20260824T033000Z`和最终恢复点`/opt/cmpp-platform-backups/phase4-p1-final-20260824T034900Z`;最终恢复点包含154MB PostgreSQL custom dump、2.4MB精简运行源码和56KB系统配置,`pg_restore --list`、两份tar及SHA-256全部通过。最终发布包SHA-256=`eb07c9fb5dfff3152fed52574895cd4308b69818e78685d6aad5649507ec4521`,仅部署测试机,运行标记=`c6f11014d61a8627ae311098ef81d89dd099ffaa+workspace.phase4p1.eb07c9fb5dff`92条migration无待执行项。预生产未修改。
- 最终正价smoke 9/9受理,P50/P95/P99=`29/33/33ms`。最终六通道100档2999/2999受理,零拒绝、零节流、零连接错误,P50/P95/P99=`33/77/179ms`;三运营商=`998/996/1005`,六通道提交尝试分别为主`998/996/1005`、备`182/178/166`。2999个唯一号码首次供应商提交从`03:51:44.049Z`到`03:53:23.989Z`,覆盖99.940秒、约30.00条/秒,低于P0对照32.25条/秒,完整100条/秒仍失败,按停止线未升200/300/500。
- 最终Worker阶段3008个样本(smoke+100档)平均:message_load约18.5ms、phone_routing约16.4ms、route_lookup约32.4ms、signature_candidates约0.004ms、rate_limit约5.4ms、submit_transaction约26.8ms、Stream发布约5.5ms、task_progress约17.9ms、total约123.1ms;相比P0总耗时175.1ms下降约29.7%,提交事务和重复签名/路由往返明显下降。应用产生的单任务状态`GROUP BY`为0,开放会话`submitTotal`更新为0Bull遗留wait从测试前到结束始终84119。
- 剩余决定性瓶颈为正价同企业计费`pg_advisory_xact_lock`,累计373.373秒/841次、均值443.963ms,远高于其余SQL;因此P1只降低Worker单条耗时,未提升完整供应商吞吐。最终样本消息2999/MessageId2999/号码2999均唯一;当前消息delivered2895、failed42、submitted62,提交accepted3142/rejected73/timeout310。冻结/释放各2999笔974675,扣费2990笔971750,退款25笔8125SmsBillingRecord当前charged2965笔963625/refunded25笔8125,账务一致。
- 测试后10个隔离应用全部恢复active/接口开启/单价0,3条临时运营商规则删除,6个供应商通道保持connected;命令/结果Stream均pending0/lag0Bull遗留wait84119未增长,数据库idle-in-transaction0、未授予锁0API/Worker/Gateway/PostgreSQL/Redis/Nginx均active且发布窗口无error级journal。真实测试消息、账务和回执保留审计;未提交、未push,受保护的`*.tsbuildinfo`、`outputs/`、`pnpm-lock.yaml`、空文件`=`及其他并发产物未删除或纳入发布。
## 2026-08-24 第四阶段P2:正价计费并发锁治理与Worker微批取舍
- 发布前恢复资产位于`/opt/cmpp-platform-backups/phase4-p2-20260824T101000Z`PostgreSQL custom dump 161MB、`pg_restore --list` 835行、精简源码1.4MB、系统配置2KB,两个tar可解包且SHA-256完整。最终测试环境标记为`c6f11014d61a8627ae311098ef81d89dd099ffaa+workspace.phase4p2final.879a234fbc86`,仅发布`100.93.204.60`,预生产未操作。
- 正价入站批量持久化仍保持全部账务与业务行同事务;仅将同企业`tenant-account` advisory lock移到事务末尾账务段。最终正价六通道50档该锁598次累计3.241秒/均值5.420ms,相比P1的373.373秒/841次、均值443.963ms,累计下降约99.1%、均值下降约98.8%。
- Worker 5ms/最多20条的消息加载微批曾部署实测,去除最慢项栅栏后仍只有约22.20条/秒,低于P1对照,因此已回退且最终发布不包含该负优化。最终代码只保留计费锁缩短,PostgreSQL Submit Outbox、批量路由与批量提交不再执行。
- 最终六通道正价50条1499/1499受理,零拒绝/节流/连接错误,入口P50/P95/P99=`31/77/227ms`。1499个唯一号码首次到达供应商从`10:37:44.510Z`到`10:38:53.564Z`,覆盖69.054秒、约21.69条/秒,50档失败,按停止线未执100或更高档。
- 最终样本MessageId/号码均1499个且唯一,客户单价min/max均325;冻结/释放各1499笔487175charged1496笔486200,最终失败退费21笔6825`SmsBillingRecord` charged1475笔479375/refunded21笔6825,净扣一致。所有压力运行均为325正价,没有0计费压测。
- 结束后根据发布前CSV快照恢复10个隔离应用单价为0,删除3条临时号段规则;这是环境还原,还原后未再压测。API/Worker/Gateway/PostgreSQL/Redis/Nginx均active,六供应商连接在线,BullMQ wait/active和两条Stream pending均0。代码未提交、未push,受保护产物未纳入发布。
## 2026-08-24 第四阶段发布前收尾回归
- 仅在`100.93.204.60`测试环境和本地隔离供应商模拟器执行,运行标记仍为`c6f11014d61a8627ae311098ef81d89dd099ffaa+workspace.phase4p2final.879a234fbc86`;预生产未操作。恢复点继续使用`/opt/cmpp-platform-backups/phase4-p2-20260824T101000Z`。
- 正价主流程使用`920001`、新号码`13877780000`和单价325SubmitResp为0、延迟15ms;消息`MSG-6b537761-9a1c-47eb-88d3-fe5e1d7d33f9`最终`delivered`,主通道Submit accepted、真实`DELIVRD`回执闭合,消息/计费记录单价和金额均325,账户生成`charged -325`流水。结束后单价回读为0。首次因远程SQL引号导致单价未生效的0价消息明确作废,不作为计费证据。
- 上行使用同一真实MessageId从测试机内部Gateway事件入口注入,`SmsUplinkMessage cmt75bszh0qjy6vletv06f4pc`以`messageId 精确匹配`关联应用和原消息;客户连接上线后普通Deliver得到ACK`CmppDownstreamDelivery`最终`delivered`。Gateway原始CMPP Deliver解析继续由全量Go测试覆盖。
- 当前版本拦截复测通过:签名未审核`MSG-c52b65a8-2451-465f-ac80-83779d78e341`为`failed/SIGNATURE`;模板未报备`MSG-137ae451-18e2-401f-b908-a4e4db0175ad`为`failed/TEMPLATE`;余额不足`MSG-1287c06b-3ecb-4fde-be1c-401636a2505c`按325计算并为`failed/BALANCE`;号码频次同号第一条delivered、第二条`MSG-6bec92fd-8eab-4450-afbf-555c292a2150`为`failed/RISK`且命中阈值1/实际2。四种失败均供应商提交0,客户失败回执已生成,临时状态和规则均恢复。
- 应用接口关闭、应用`inactive/deleted`、企业`inactive/deleted`五次CMPP bind均返回状态3且未进入提交;应用、企业和接口均已恢复。
- 通道报备和禁用复测通过:移动主备报备临时pending时`MSG-44c2b749-62fc-47f7-a200-9ed74d2f1ff7`为`failed/ROUTE`且供应商提交0;仅主通道inactive时`MSG-d256c8fc-e74f-4260-9fa6-595a37b16e17`自动选`LGST-M-B`并delivered;主备都inactive时`MSG-598ea5de-da7f-4c24-ac4d-728e12629489`为`failed/ROUTE`且供应商提交0。
- 通道组补发在模拟器6/6且数据库六通道均`connected/currentConnections=1`后执行:`MSG-0a91d27a-0d39-4377-a57d-fa98e869d2d9`在`LGST-M-P`结果码8/rejected,随后`LGST-M-B`产生带`retryOfSubmitRecordId`的accepted提交并最终delivered。切换模拟器后未等待数据库连接状态的第一次试验只有主通道拒绝,明确判为夹具无效轮,不作为产品失败。
- 最终恢复回读:10个隔离应用全部active、接口开启、单价0、模板模式direct_send;隔离企业active16个签名审核均approved10个签名汇总报备approved60条通道报备任务approved6通道active且connected;临时规则0Inbox pending0;两条Stream pending/lag均0BullMQ wait/active均0;数据库锁等待和idle transaction均0;六个核心服务active,普通模拟器6/6连接。
- 新增`docs/phase-4-send-pipeline-redesign.md`,说明原BullMQ Worker微批边界、跨介质一致性和回调资源争用问题,并提出PostgreSQL Submit Outbox、批量路由持久化及回调池隔离方案。当前不实施该重构。
- 发布门禁复跑:API全量42套500项通过,TypeScript正式构建通过。pnpm包装器首次在测试启动前因既有`msgpackr-extract`未批准构建脚本退出;未修改依赖或锁文件,随后直接使用已安装的Jest/TypeScript入口完成验证。`git diff --check`与最终Git范围检查另行执行。
## 2026-08-25 PostgreSQL Submit Outbox发布与正价压测
- 仅部署测试机`100.93.204.60`,标记`c6f11014d61a8627ae311098ef81d89dd099ffaa+workspace.phase4outbox-live.20260825`;恢复资产`/opt/cmpp-platform-backups/phase4-outbox-20260825T094000Z`已验证,预生产未操作。
- API 42套502项、Gateway全包测试、TypeScript构建和`git diff --check`通过;迁移已应用,API/Worker/Outbox/Gateway/PostgreSQL/Redis/Nginx active。
- 正价阶梯:20 TPS=20.46/s、计费6467530 TPS=29.97/s、计费97175;三运营商50 TPS=33.07/s、计费162175。所有档MessageId/submitId唯一,补发均关联retryOf,队列和锁干净。
- 50 TPS停止线未通过,未执行100/200/300/500。临时号段规则已删除,10个测试应用单价恢复0;最终Outbox published=2172、payload差异0、重复submitId=0、Inbox非completed=0、双Stream pending/lag=0。
## 2026-08-25 批量路由持久化、独立回调进程与正价复压
- 发送Worker新增最大32条、等待3ms的有界聚合批次:批量读取消息、号段、路由/连接/签名报备,按消息完成实时约束和通道限速;首次提交以一个短事务批量创建`SmsSubmitRecord`、集合式更新消息、批量创建`GatewaySubmitOutbox`。重试、拒绝和异常仍走原逐消息幂等状态机。
- 新增回环`cmpp-gateway-callback`进程,独立12槽数据库池,专门处理Submit结果、分片结果、回执、上行、受限协议日志和死信;客户HTTP Webhook仍在主API异步Worker。Gateway连接状态控制继续写主API,供应商事件写回调进程。回调管理Controller未加载,端口仅监听`127.0.0.1:3001/9468`。
- 初次smoke因连接状态控制误发到回调端点而全部`failed/ROUTE`,供应商提交0、计费0;已拆分控制面和事件面URL并复测,六连接数据库状态均为connected。该轮作为发布缺陷审计保留,不纳入容量统计。
- 修复后正价结果:smoke 9/9、账单292520 TPS 199/199、P50/P95/P99=`19/51/94ms`、账单6467530 TPS 299/299、`20/48/69ms`、账单9717550 TPS 499/499、`35/76/135ms`、账单162175。四个成功窗口合计1006条、1006笔账单、单价全部325、金额326950。
- 50档499条唯一首次供应商Submit跨度9.930秒,完整提交速率`50.25条/秒`,相对上一版同档33.07条/秒提高约52%。全部尝试/Outbox均542条且ID唯一;状态检查时delivered485、failed4、submitted10,关联补发43次。Inbox、Outbox、双Stream最终排空,数据库无等待锁、无idle in transaction,回调池`max=12,total=1,idle=1,waiting=0`。
- 测试环境最终标记`c6f11014d61a8627ae311098ef81d89dd099ffaa+workspace.phase4batchcallback.callback-surface.599393bb6233`;恢复资产为`/opt/cmpp-platform-backups/phase4-batch-callback-20260825T025611Z`。10个隔离应用单价恢复0,三条临时号段规则删除,真实计费事实保留;预生产未操作,未执行100/200/300/500档。
## 2026-08-25 第五阶段单 Gateway 容量扩展与正价压测
- 完成协议日志 Redis Stream 降载及独立日志 Worker、单 Gateway 每通道 18 连接/每连接 1~64 窗口、RTT/在途择优、失败冷却、平滑扩缩容、Gateway 结果 Outbox 批量 HTTP 回调、逐事件确认和上行 eventId 幂等;明确未实施多 Gateway P2。
- API单测、Gateway控制入口和测试机实际运行三层覆盖 `1x1/2x16/4x32/8x64/4x64/2x32`。`LGST-M-P` 1→4→1 在20 TPS在途发送期间平滑缩容,399/399 SubmitResp、399条首次Submit、重复ID为0P95/P99=`49/142ms`。
- 协议日志首次冒烟发现空`REDIS_URL`未回退,按停止线中止。修复、回归并重发后发布16、采样47、错误0,独立Worker排空。批量回调累计事件数大于HTTP请求数,重试/死信为0;同一上行eventId重放两次只落一条。
- 正价325阶梯:20档199条约20 TPS、P95/P99=`21/29ms`、6467530档299条30.39 TPS、`33/61ms`、9717550档499条49.47 TPS、`62/89ms`、16217570档699个SubmitResp690条有效首提在10.351秒完成66.66 TPS`4099/5323ms`690笔224250。另9条为频控`RISK`且供应商/计费均0。
- 70档尾延迟突增且未达到目标,立即停止,未执行100/150/200。稳定TPS上限定为50 TPS。
- 当前部署回归:签名、模板、余额分别9/9在供应商前拦截;应用/企业停用均无法鉴权;主通道停用9条全部走备通道,主备全停9/9`ROUTE`且提交0;随机主拒绝补发均有retryOf;Submit、回执、上行和计费对账通过。
- 发布只到`100.93.204.60`,恢复点`/opt/cmpp-platform-backups/phase5-capacity-20260825T041622Z`;预生产未操作。结束时应用单价0、临时号段规则0、业务配置恢复、六连接在线,队列排空且数据库无锁等待/idle事务。
## 2026-08-25 第五阶段回执回放热修复与正价复压
- 重新验证确认旧70 TPS尾延迟是回执恢复风暴:每条SubmitResp都启动pending扫描,多个扫描在sent回调前取到同一批。实施Gateway账号级单飞与25ms/250ms有界合并、API FOR UPDATE SKIP LOCKED pending到dispatching原子领取、claimId/30秒租约、未发送无损释放及过期恢复。
- 首轮复压还发现6191条中29条有2次下游尝试,进一步定位为API新建回执直推与Gateway恢复拉取之间没有共享所有权。直推改为先取得dispatching + claimId,未抢到则退出。Linux race门禁另发现并修复ACK超时timer指针赋值竞态。
- 门禁:API 44套520项、TypeScript构建、Gateway全包测试、go vet、Linux go test -race ./internal/inbound和git diff --check通过。只发布测试机,预生产未操作;恢复点/opt/cmpp-platform-backups/phase5-replay-hotfix-20260825T070815Z,最终标记761c123b65f09093bc379096188f3ee9ccb2e618+workspace.phase5.replayhotfix2.directclaim。
- 正价325阶梯入口SubmitResp20=199/199、P95/P99 10/16ms30=299/299、10/18ms50=499/499、35/47ms70=699/699、44/60ms100=999/999、51/72ms150=1498/1498、87/114ms200=1998/1998、84/110ms;全部零拒绝、零节流、零连接错误。完整供应商首提速率依次为19.84/30.34/49.47/65.54/74.86/94.86/92.24 TPS,端到端天花板约95 TPS。
- 最终100 TPS正价复验:999/999P50/P95/P99 54/102/179ms999个唯一MessageId1087个含主备补发的submitId全部唯一;999次999个唯一首提在12.488秒完成(80.00 TPS)。972条终态回执全部客户ACK,下游尝试972、重复0、最大1。计费998条中995 charged、3 refunded1条RISK供应商前失败不计费;27条no-receipt保持submitted。Inbox/Outbox/下游pending队列、未授权锁和idle transaction最终均0。
- 最终建议分口径:客户入口可受理200 TPS冲击,不等于端到端供应商200 TPS;供应商首提峰值约95 TPS,建议稳定限速70 TPS保留余量。按用户要求,7个应用单价保持325,三条临时号段规则、Tailscale白名单及VM回环白名单均保留,未做删除或归零。压测原始证据已复制到相邻测试项目lg-cmpp-stress-lab/results下的phase5-replayfix目录。
## 2026-08-25 95 TPS天花板定向诊断
- 先将第五阶段容量扩展和回执防重修复提交为`9292352`,排除`*.tsbuildinfo`、`outputs/`、`pnpm-lock.yaml`、空文件`=`及无关临时脚本;未push。随后仅在`100.93.204.60`测试环境和本地隔离供应商模拟器执行正价诊断,预生产未操作。
- 100 TPS档998/998受理,P50/P95/P99=`57/117/257ms`,首次供应商Submit跨度13.172秒、约75.76 TPS150 TPS档1498/1498受理,P50/P95/P99=`71/136/185ms`,首次供应商Submit跨度15.547秒、约96.35 TPS。两档均零拒绝、零节流、零连接错误,单价均325。
- Gateway不是当前天花板:6/6供应商连接、总窗口192;150档连接等待均值0.006ms、供应商RTT均值13.761ms、窗口采样峰值10、命令Stream lag峰值27。150档供应商模拟器新增1603次尝试、1574次接受、29次拒绝、错误0;105次主备补发解释了尝试数高于业务消息数。
- 天花板位于独立CMPP入站工作流。7个压测应用全部属于同一企业`qa-bell-alerts-tenant`,因此日限、号码频控、消息持久化和正价账户冻结集中在同一企业边界。100档Inbox 998条形成171个完成批次,平均5.84条、最大16条,注入9.991秒但排空13.245秒,完成延迟P50/P95=`3053/3810ms`150档1498条形成153个完成批次,平均9.79条、最大22条,注入9.974秒但排空15.555秒,完成延迟P50/P95=`3779/5620ms`。配置虽为工作流并发96、批次64,但泵在每批完成后立即领取当时已有记录,没有有界聚合等待,稳态产生大量小批次。
- 150档阶段指标均值显示`risk_frequency≈202.05ms`、`message_persist≈183.57ms`、`daily_quota≈152.86ms``pg_advisory_xact_lock`164次累计6.897秒、均值42.057ms。BullMQ waiting峰值0、发送Worker槽峰值76/96、数据库池waiting峰值0Gateway命令和结果Stream、Inbox及Submit Outbox最终全部排空,数据库无等待锁和idle transaction。主机CPU一分钟窗口峰值约65.47%、内存约40.74%,不是CPU或内存打满。
- 结论应限定为“单企业正价完整首提约95 TPS”,不能外推为多企业平台总吞吐。下一步优先为入站工作流增加按企业分组的有界微批(目标批次32~64、最大等待20~50ms)并对不同企业并行、同企业账户冻结串行;同时把配额/频控/消息持久化合并为更少的集合事务。之后用同企业100/150和至少2个独立企业的总200 TPS正价场景分别验收。多Gateway仍不是当前优先项。
- 诊断另发现`GatewaySubmitOutbox.createdAt`由Prisma按UTC写入,而原生SQL以`CURRENT_TIMESTAMP`写`publishedAt/updatedAt`,测试机数据库会话时区为Asia/Shanghai时产生8小时显示偏差。该问题不影响本次Stream排空和首提TPS,但会污染Outbox发布时延审计,需单独将原生SQL时间统一为`NOW() AT TIME ZONE 'UTC'`并回归租约/重试时间语义。
- 收尾回读:9个核心服务均active,六连接在线;命令/结果Stream pending和lag均0,协议日志Stream长度0;7个应用继续active、接口开启、单价325`^1380028/^1300028/^1890028`三条priority10规则继续active,每个应用的`100.91.249.119/32`及`127.0.0.1/32`白名单均保留。发布窗口API/Gateway/Worker/回调error级journal为0。
## 2026-08-25 单企业微批、连接竞态修复与双企业正价容量验证
- 提交`76e7c8c`:入站工作流领取前最多40ms聚合到目标32/上限64,按企业分组,不同企业并行、同企业分批串行并从后续领取排除;Submit Outbox及关联消息原生SQL统一为UTC。API完整45套525项(后续连接修复后526项)、TypeScript构建、Gateway全包测试/go vet、R0、发布契约和真实PostgreSQL SQL门禁通过。
- 100 TPS首轮998条出现2个Result 9,日志证明为Gateway复用API loopback连接时被Node默认keep-alive关闭;`394949f`设置API keep-alive/headers timeout为120/125秒并由部署脚本校验。复验不再出现loopback reset,但`920004`连接只返回9条后断开;日志定位同一connectionId的connected/submit状态回调竞态被误判超过1条连接。`b5005f2`改为同connectionId不重复计数、首次状态幂等upsert,保留不同连接超限403。
- 三次发布均只到`100.93.204.60`,预生产和多Gateway P2未操作;最终标记`b5005f21d5092b7e2759efdce0ebd02798e4552f+test.phase6.tenant-microbatch.utc.keepalive.connection-race`。最终恢复点`/opt/cmpp-platform-backups/phase6-connection-race-20260825T095448Z`,另保留实施前和keep-alive修复前两份可读恢复集;每份均含custom dump、运行源码、环境/systemd和SHA-256pg_restore/tar校验通过。
- 有效正价结果:单企业100档999/999、P50/P95/P99=`72/243/466ms`、23个批次平均43.43/最大64、Inbox 10.721秒排空、首次供应商Submit `95.85 TPS`;单企业150冲击1498/1498、`53/83/117ms`、33批平均45.39/最大64、12.453秒排空、首次Submit `122.87 TPS`;双企业合计200冲击1999/1999、`80/148/287ms`、两企业各22批、首次Submit `129.39 TPS`,两企业分别64.69/65.96。全部零拒绝、零节流、零连接错误。
- 双企业200档单价全部325:1999条账务记录,其中1988 charged/646100、11 refunded/35752145个含主备补发的SubmitId及Outbox全部唯一/publishedOutbox最大发布0.111秒。最终1936 delivered、49模拟器no-receipt为submitted、11最终失败已退款、3条首次接受后补发结果码8保留charged。1950条终态回执投递1950次、重复0、最大尝试1;客户端离线产生的973 pending由14账号零发送排空。
- 收尾状态:Inbox全83194条completedSubmit Outbox全27107条published,命令/结果/协议日志Stream pending和lag均0,下游pending=0,数据库锁等待/idle transaction=09服务active、API/Gateway健康、Redis PONG14个测试应用active且单价325,28条指定白名单保留,原phase5三条和新增phase6三条临时号段规则均active。未执行长期稳态,当前建议单企业限速90 TPS、单Gateway平台总限速100 TPS;入口150/200冲击不等于完整供应商TPS。
## 2026-08-25 测试环境主要发送流程与 P0 拦截回归
- 按用户最新要求停止性能压测,本轮仅在测试机`100.93.204.60`和本地供应商模拟器执行低流量功能回归,未访问或修改预生产/生产,未实施多 Gateway P2。代码级门禁限定`api/`根目录后,SendChain、号码频次和Gateway事件3套141项全部通过;首次从仓库根目录执行时被用户保留的`outputs/`旧快照误匹配,未作为产品失败且未修改该目录。
- 正常正价链路通过:`MSG-a33198db-c3ba-4002-9358-97a128aca87f`、`MSG-b2b329ad-b088-4b41-a19a-c94d2e7a525c`均为`delivered`,走`LGST-M-P`并各产生1笔`charged=325`。本轮测试窗口共落库26条,12条delivered、14条failed12笔charged合计3900,账户从1827951变为1824051,冻结16笔/5200与释放16笔/5200相抵,补发没有重复计费。
- 发送前拦截重新验证通过:签名未审核2条为`failed/SIGNATURE`,模板强校验2条为`failed/TEMPLATE`,余额不足2条为`failed/BALANCE`;三类均供应商Submit=0、账单=0,并生成客户失败投递。移动主备签名通道报备改为pending后,`MSG-05db68dd-9185-4c1d-8e4b-5bf114390c41`和`MSG-b4bf86a6-271e-45eb-9c73-8a2930d54894`均为`failed/ROUTE`、供应商Submit=0、账单=0。签名审核、模板模式、余额和6条报备任务均已恢复。
- 号码频次通过:专用应用级5分钟1条规则下,固定上海时区同一窗口的第2条`MSG-7f8df0db-7a03-4965-ab93-021c0504abb6`和`MSG-90429628-c566-40c3-824c-73cc3600075a`均为`failed/RISK`,命中阈值1/实际2,供应商Submit=0、账单=0。一次初测恰好跨越19:05固定窗口边界,按设计重新计数,不作为失败;本轮临时规则已删除,两测试号码活动命中已解除,既有全局规则和平台白名单未修改。
- 企业应用`inactive/deleted`、企业`inactive/deleted`四次新连接均返回CMPP Bind状态3并断开,未创建短信记录。bind后再停用的严格复验同样拦截发送;此前两次跨机器时间未校准的尝试虽送达并计费,但无法证明配置变更早于Submit,明确作废且不用于判断。严格复验暴露`P0-SEND-AUDIT-001`:应用或企业停用后,参数合法Submit返回非零SubmitResp,且测试号码`13800389700/13800389800`均没有`SmsMessageRecord`、失败回执或下游投递;这与`TC-SEND-037`要求“已鉴权合法Submit先返回成功并留痕,再以REJECTD业务失败”冲突。当前单元测试反而断言同步拒绝且不落库,说明需求、测试和实现口径已漂移,需先确认权威语义再修复,不能把“拦截生效”冒充完整失败审计闭环。
- 通道行为通过:仅`LGST-M-P`停用时,`MSG-94d30de8-78cb-48a4-bdbf-e6ef6dd2fb93`、`MSG-22f26498-0289-4b79-aa0c-a1fa54bb0b99`自动改走`LGST-M-B`并delivered;移动主备同时停用时两条均`failed/ROUTE`、供应商Submit=0、账单=0。确定性故障模拟下,`MSG-c28b231f-2489-41fc-9d0f-6223bc8307bd`和`MSG-a65283b6-9349-4838-a12d-fee2e5ee07ff`先在主通道结果码8/rejected,再创建带`retryOfSubmitRecordId`的备用accepted提交并最终delivered,每条只计费325。
- 最终恢复回读:企业/应用active、接口开启、模板模式direct_send、应用单价325、余额1824051;`【LG压测】`审核和汇总报备approved6/6通道报备approved;六通道active、端口17900、连接6/6,普通模拟器已恢复;每应用两条指定白名单及phase5/phase6六条临时运营商号段规则全部保留,临时频控规则0。Inbox仅completed、Submit Outbox仅published,命令/结果/协议日志Stream均pending0/lag0,业务BullMQ wait/active/delayed/failed/prioritized均0,遗留`gateway.submit.queue` wait仍为84119且未增长;数据库未授予锁0、idle transaction09项服务active,本轮窗口核心服务error级journal为0。
## 2026-08-25 P0-SEND-AUDIT-001 本地修复与提交前验证
- 根因确认有两段:普通路径在应用查询后、快速路径在Inbox合并SQL内,都把应用/企业/接口状态作为SubmitResp同步拒绝条件,导致已鉴权合法Submit在短信记录前退出;即使后续业务状态机生成`ACCOUNT/INTERFACE`失败回执,下游队列仍会因当前`interfaceEnabled=false`直接返回。两处行为共同造成测试号码没有`SmsMessageRecord`、`SmsReceiptRecord`和`CmppDownstreamDelivery`。
- 最小修复保留新bind的应用/企业/接口拒绝、账号存在性、IP白名单、`Src_Id`和协议参数校验;已鉴权合法Submit先进入原有持久化流程,普通路径立即、快速路径由Worker按最新状态生成`failed/ACCOUNT`或`failed/INTERFACE`、`undelivered/REJECTD`。仅这两类平台业务失败回执携带窄范围许可,即使资源随后停用/删除或接口关闭,也可创建下游投递并尝试送到原CMPP会话;普通HTTP消息、上行和其他停用资源投递语义未放宽。
- 单元回归覆盖接口bind后关闭、应用处于disabling且回执入队时已deleted/interface关闭、快速路径Inbox SQL不再提前检查业务状态,同时确认IP白名单与`Src_Id`校验仍保留;既有“接口关闭时新bind拒绝”和“HTTP-only应用不产生CMPP投递”用例继续通过。
- 提交前门禁:API全量45套526项通过;非增量TypeScript正式构建通过且未要求改写用户保留的`tsbuildinfo`Gateway `go test ./... -count=1`和`go vet ./...`通过;`git diff --check`通过。无数据库迁移、无新增环境变量,部署脚本和环境变量校验无需修改;回滚只需revert本轮代码/文档提交并重新构建。
- 本轮按用户授权仅在本地修复和验证,没有部署到测试环境,也没有执行新的短信发送或压力测试;测试环境仍运行旧部署标记`b5005f21d5092b7e2759efdce0ebd02798e4552f+test.phase6.tenant-microbatch.utc.keepalive.connection-race`,恢复资产仍为`/opt/cmpp-platform-backups/phase6-connection-race-20260825T095448Z`。因此P0已由代码和自动化测试验证,但尚未在测试环境重新做真实CMPP闭环验收;预生产/生产未访问,多Gateway P2未实施,未push远端。
## 2026-08-26 预生产 Prometheus 监控基础设施修复
- 只读诊断确认预生产`8.160.169.106`为 Alibaba Cloud Linux 4 ARM64,服务器没有 Prometheus、Node Exporter 或三个服务 Exporter;既有安装脚本仅接受`apt-get`,发布脚本也不会自动调用监控安装,因此页面按设计显示 Prometheus 不可用。API/Worker 自身回环指标端点在修复前仍为 HTTP 200,最近两份发布备份也均不含`/etc/prometheus`,排除近期业务发布误删。
- 最小修复保留 Debian/Ubuntu apt 路径,并为 Linux aarch64 增加官方 release 二进制安装、固定版本与 SHA-256 校验、systemd 基础单元、root 专属离线缓存及 API 托管告警规则目录的精确`ReadWritePaths`。部署中发现 Node Exporter systemd 正则发生二次转义告警,已追加修复并由`systemd-analyze verify`及新日志窗口确认告警消失。
- 发布前恢复点为`/opt/cmpp-platform-backups/releases/20260826T062955Z-before-b0bdb60-monitoring`,包含183415098字节 PostgreSQL custom dump、14647063字节运行目录、30849字节环境/systemd/Nginx配置、Gateway二进制、原部署标记和 SHA-256 清单;`pg_restore --list`、两份 tar 目录及全部清单均通过。校验过的5个官方 ARM64 release 包也移入该恢复点的`monitoring-release-cache/`并再次通过 SHA-256。
- 预生产最终监控标记和部署标记均为`523481299028d9ded470d7738add145ee2070bd1`。安装版本:Prometheus 3.14.0、Node Exporter 1.12.1、PostgreSQL Exporter 0.20.1、Redis Exporter 1.89.0、Nginx Exporter 1.5.3Prometheus加载9个规则组共83条规则。
- 发布后 Prometheus 9个 target 全部`up``pg_up=1`、`redis_up=1`、`nginx_up=1`9090/9100/9187/9121/9113及API/Worker metrics均只监听回环。Prometheus、5个 Exporter、MinIO、Nginx、API、Worker、Gateway、PostgreSQL和Redis均activeAPI/Gateway健康;供应商连接`desired=9/connected=9`,命令/结果 Stream 最终均`pending=0/lag=0`。
- 浏览器只读验收已到达预生产运营端登录页,因当前浏览器没有运营端登录会话,没有输入凭据或验证码,故本轮未把登录后的页面截图作为验收证据;监控可用性以 Prometheus targets、PromQL和API进程实际环境变量为当前证据。未发送短信、未压测、未修改余额/应用/企业/白名单/临时号段/通道配置,未操作正式生产,多 Gateway P2 未实施。
## 2026-08-26 上行匹配展示与应用黑名单入口本地修复及提交前验证
- 只读回查预生产数据库时共有84条上行记录,其中61条已匹配、23条为多候选;82条没有平台`messageId`,但59条已通过接入号或手机号72小时窗口写入`messageRecordId`。因此“全部匹配不到”的直接原因是客户端和运营端详情在`messageId`为空时提前返回,忽略API已返回的`messageRecord`;这不代表后端未匹配。
- CMPP普通MO的Deliver `Msg_Id`是供应商为该上行分配的独立标识,不是历史MT Submit的消息ID。Gateway此前仅尝试用它查询本地Submit跟踪器,正常MO通常得不到平台`messageId`,且原始MO `Msg_Id`只写日志未持久化。本轮新增独立可空字段`SmsUplinkMessage.gatewayMessageId`及迁移,Gateway将MO `Msg_Id`原样随事件上送,API持久化并在两端详情与关联平台消息ID分栏展示;平台`messageId`继续只表示真实关联,不伪造关联。
- 客户端和运营端详情优先使用上行列表响应内嵌的真实`messageRecord`;只有历史兼容记录在缺少内嵌记录且存在平台`messageId`时才回查消息接口。多候选记录给出认领提示。运营端对已匹配或已认领到企业应用的上行恢复“加入应用黑名单”按钮,确认后调用现有真实企业应用黑名单API;客户端保持只读。
- 自动化门禁:Gateway/API队列5份契约样例通过;SendChain与Operations专项2套159项通过;API正式TypeScript构建、前端TypeScript检查、Vite生产构建、Prisma schema校验、Gateway全包`go test ./... -count=1`和`go vet ./...`均通过。Gateway首次全包测试仅既有限速时序用例偶发一次`delay=0`,该包连续5轮及随后全包复跑均通过,本轮未修改限速实现。
- 本轮功能改造仅发生在本地工作区,没有在远端环境执行数据库迁移,没有发送短信、压测、push或部署。新增迁移必须随未来授权发布执行后,新上行才会保存`gatewayMessageId`;历史记录不会反填供应商MO ID。预生产和正式生产均未改动,多Gateway P2未实施。
## 2026-08-27 运营端短信记录高密度列表本地调整
- 搜索区保留原有9项条件:企业、应用、提交日期、手机号码、运营商、短信内容、通道、发送状态、是否含引流信息;未新增、删除或合并条件,仅改为12列响应式布局并压缩控件宽度。
- 短信记录由大卡片改为按提交日期分组的紧凑行式列表;提交时间和回执时间均按日期、时分秒两行展示,无回执时明确显示“暂无回执”。计费列集中展示金额、分片数和字数,不展示“已补发”标签;最右侧箭头继续调用原有`SendDetailModal`,弹窗实现未修改。
- 本地真实API和PostgreSQL数据渲染验证通过:9项搜索条件全部存在,列表可见1/2分片计费记录,点击右箭头可打开原有发送详情、通道发送与回执、状态信息和分片补偿审计;另开干净页面控制台日志为空。
- 门禁通过:R11页面契约、前端TypeScript检查与Vite生产构建、API正式构建与Prisma校验、队列契约、SendChain/Operations 2套159项、Gateway全包`go test ./... -count=1`和`go vet ./...`。pnpm包装器因既有`msgpackr-extract`构建脚本未批准而中止,未放宽依赖策略,改用已安装的TypeScript/Vite入口完成等价构建。
- 本轮仅使用本地隔离环境,没有访问或修改预生产/生产,没有发送短信或压测。为渲染验证启动的PostgreSQL、API、前端预览和临时Redis均已停止;多Gateway P2未实施。
## 2026-08-27 LG第46/47步确认缺陷本地修复
- 对测试机`100.93.204.60`做只读复核:`gateway.submit.results` consumer group 为`lag=1974/pending=0`Gateway日志明确记录`2026-08-26 05:48:18 ... worker stopped: ... i/o timeout`。批量回调消费在一次Redis短暂读超时后永久退出,解释了随后SubmitResult、回执和上行事件均入流但不回写的两个P0。
- Gateway批量结果消费增加持续重试外层,每次重试重新确保consumer group存在;一次Redis I/O错误不再结束唯一结果消费协程。Outbox校验同时改为仅Submit结果必须具有平台`messageId`,普通MO上行可在没有历史MT关联时继续回调并落库。
- 客户端发送页按应用真实`templateMismatchMode`放行`direct_send`,保留签名和正文必填,并在提交区显示禁用原因;导入在读文件前校验CSV/TSV/TXT扩展名及MIMEXLSX不再当文本解析。
- 移动端日期选择器使用视口内固定弹层和内部滚动,操作区置底;批量任务提交/定时时间统一为Asia/Shanghai格式。
- 门禁通过:API 45套528项,Gateway全包(含新增Outbox重试与无messageId上行用例),API正式构建,前端TypeScript检查和Vite生产构建。390×844 Chromium回归的直发、XLSX拦截、定时弹层和批次时间均通过,控制台错误/警告0。
- 本轮没有部署、重启服务、发送短信或处理测试机1974条积压;没有访问或修改预生产/生产。因此当前是本地代码与自动化/渲染回归通过,测试机真实CMPP闭环需在后续部署授权后再验收。
## 2026-08-27 客户端展示、三网报备与人工审核状态优化(本地门禁)
- 完成用户明确的10项页面优化,并按`batch-task-manual-review-status-optimization-20260827.md`第一阶段实现人工审核状态修复;第二阶段孤立审核任务事务/补偿不在本提交范围。
- 客户端签名接口按运营端同一应用路由、通道运营商范围和报备任务计算三网汇总,只输出汇总,不暴露通道或报备任务明细。
- 人工审核状态改用共享前端映射;未知状态不再默认“发送中”。客户端仅`scheduled`可取消,运营审核列表返回并展示关联批量任务号。
- 本地前端TypeScript、API TypeScript正式构建和Vite生产构建通过;API全量45套529项通过。Gateway全包测试仅既有限速时序用例偶发一次`delay=38.136ms`,该包随后连续3轮通过,`go vet ./...`通过。客户端登录页真实渲染确认“返回官网”存在。
- 首次发布提交`01cffa4758af4908a8d4110fb5b039c0151226c4`前建立并完整校验恢复点`/opt/cmpp-platform-backups/ui-review-20260827T101712Z`95项迁移均已应用,发布后8项核心服务active,API/Gateway健康,命令和结果Stream均`pending=0/lag=0`,发布窗口核心服务error级日志为空。此前一次在`pg_dump`参数校验阶段中止,未覆盖代码、配置或数据库;目录`ui-review-20260827T101624Z`不作为有效恢复点。
- 测试环境真实服务核验定位到客户端接口对接页原500的根因:测试机使用HTTP源地址,而后端强制要求HTTPS。追加提交`070a951e7cffb467734a4486ac46a83605a7f218`,默认仍拒绝不安全源地址,仅允许隔离测试环境通过`HTTP_API_ALLOW_INSECURE_ORIGIN=true`显式放行HTTP;新增OpenAPI单测11/11和API正式构建通过。
- 第二次发布前重新建立并校验恢复点`/opt/cmpp-platform-backups/ui-http-origin-20260827T104430Z`。最终部署标记为`070a951e7cffb467734a4486ac46a83605a7f218`;以`screenshot_client`所属企业的真实应用直接调用配置、凭据、Webhook、请求日志、投递日志五个服务方法全部成功,配置接口不再抛出Internal server error。8项核心服务active、API/Gateway健康、结果Stream`pending=0/lag=0`、发布后error级日志为空,运营端/客户端登录页及API健康地址从工作站访问均HTTP 200。
- 两次发布均仅操作测试环境`100.93.204.60`;未访问、回退、覆盖或部署预生产`8.160.169.106`,未发送短信或执行压力测试。第二阶段孤立审核任务事务/补偿仍未实施。
## 2026-08-27 客户端金额样式复核与系统日志日期区间(本地门禁)
- 用户在另一台电脑复核后指出首页金额视觉没有变化。重新比对最终CSS确认首次改动仅把原有约30px深色粗体重复声明为30px深色粗体,视觉差异不足;同时`MoneyText`组件不生成`.money-text`类,首次样式中的后代选择器不会命中。现改为明确的Arial/微软雅黑普通系统字体、38px、500字重、纯黑`#111111`,并显式清除背景、文字填充、阴影及特殊裁剪效果;最近充值使用28px紧凑规格。
- 运营端系统与操作日志、运营端通讯交互日志、客户端系统日志均改为可选起止日期的真实日期区间,初始及重置默认北京时间近7天。查询、分页和导出统一向后端传递`createdAtFrom/createdAtTo`,后端按开始日00:00:00.000至结束日23:59:59.999Asia/Shanghai)过滤。
- Chrome视觉夹具计算样式确认三个关键金额均为`rgb(17,17,17)`、38px、500字重、Arial/微软雅黑且控制台无error/warn;前端TypeScript与Vite生产构建通过。API正式TypeScript构建、操作日志/通讯日志专项34项、API全量45套532项通过。
- 本轮代码提交`33fa3709d9ba8238f4ae8fb6087d49a70363c0ed`。发布前新建并完整校验恢复点`/opt/cmpp-platform-backups/amount-log-date-20260827T120716Z`,随后仅部署测试环境`100.93.204.60`;最终部署标记与提交一致,95项迁移均已应用且无待执行迁移。
- 测试环境前端已切换为新资源`index-CbwHlDzn.css`与`index-BftfsVsS.js`;远端CSS明确包含38px纯黑金额规则,JavaScript包含日志日期区间。Chrome无缓存参数重新打开测试环境客户端登录页后加载同一新资源且控制台无error/warn。
- 真实测试数据库按`2026-08-21`至`2026-08-27`核验:操作日志服务返回总量44714,与数据库同一北京时间边界直接计数44714一致;通讯日志服务返回425843,与数据库直接计数425843一致。8项核心服务active、API/Gateway健康、Gateway结果Stream`pending=0/lag=0`,发布后核心服务error级日志为空。
- 预生产未访问或修改,未发送短信、未压测。登录后金额与日志控件最终人工视觉复核仍需使用现有客户端/运营端账号完成验证码登录;验证码未被自动绕过。
## 2026-08-28 客户端账户余额字体与标题复核发布
- 重新核对确认账户余额页此前复用了首页`.client-amount-value`,该类强制使用Arial/微软雅黑、38px和500字重,不符合账户余额页“继承系统字体、普通字重”的要求。余额页现改用独立`.client-billing-amount`:继承平台字体、32px、400字重和`--color-text-strong`纯深色,并移除摘要金额内的`MoneyText`拆分包装;首页金额类仍被首页4处金额使用,予以保留且不再影响余额页。
- 账户余额页顶部删除“账户”眉题,改为与其他客户端页面一致的左侧`WalletCards`图标加“账户余额”标题;`TC-UI-REVIEW-001`同步补充字体、标题结构验收口径。
- 本地前端TypeScript检查和Vite生产构建通过,代码提交为`5bd347e0105b6344b0cdf64592cf8f25c1496668`。首次远端续部署在恢复资产校验完成后因入口脚本无可执行位而停止,服务尚未重启;随后以`bash`显式调用同一脚本完成部署,没有跳过或重建恢复基线。
- 发布前恢复点`/opt/cmpp-platform-backups/billing-presentation-20260828T014051Z`包含PostgreSQL custom dump、原运行目录、环境/systemd/Nginx配置、原部署标记和SHA-256清单;`pg_restore --list`、两份tar目录及全部摘要校验通过。测试环境最终部署标记与代码提交一致,95项migration无待执行项。
- 发布后前端资源为`index-X8XfFWLh.css`和`index-DTiS-tkY.js`;服务器产物包含余额页专用类和标题文本,工作站全新浏览器标签加载同一资源且控制台无error/warn。客户端未登录访问按预期重定向登录页,因图形验证码未自动绕过,本轮没有把登录后的余额页渲染冒充浏览器验收证据。
- API、Send Worker、Submit Outbox、Gateway Callback、Protocol Log Worker、Gateway、Security Agent、MinIO、Nginx、PostgreSQL和Redis均activeAPI/Gateway健康,Gateway结果Stream为`pending=0/lag=0`,发布窗口核心服务error级日志为空。仅部署测试环境`100.93.204.60`;预生产未访问或修改,未发送短信、未压测、未改余额或通道配置。
## 2026-08-28 客户端工作台金额统一与余额水位移除
- 工作台“可用发送额度”“今日消费金额”“今日返还金额”移除旧`.client-amount-value`覆盖,和“今日发送”共同使用`.metric-card strong`;“最近充值”恢复账户状态列表的普通强调文字。旧金额类及紧凑变体已无引用并从全局CSS删除。
- 账户状态中的“余额水位”标题、百分比、进度条及其专用派生计算全部删除;余额、消费和返还的真实API数据及金额格式化逻辑没有改变。`TC-UI-REVIEW-001`同步更新验收口径。
- 本地TypeScript检查、Vite生产构建和浏览器渲染验证通过。四张指标卡计算样式均为同一平台字体栈、30px、700字重、`rgb(17,24,39)`,页面中“余额水位”计数为0,控制台无error/warn。代码提交为`a70e9e2c078a6109dd87cf8e45aeff956faf24e8`。
- 发布前建立并校验恢复点`/opt/cmpp-platform-backups/dashboard-metrics-20260828T021652Z`,包含PostgreSQL custom dump、原运行目录、环境/systemd/Nginx配置、原部署标记和SHA-256清单;`pg_restore --list`、两份tar目录和全部摘要校验通过。95项migration无待执行项。
- 测试环境最终部署标记与代码提交一致,新资源为`index-DObeLiN5.css`和`index-BrcWR_qc.js`。服务器与工作站HTTP回读确认CSS包含统一30px指标规则且不含旧金额类,JavaScript不含“余额水位”。应用内浏览器的测试机导航被本机客户端拦截,未冒充登录后真实页面验收;本地同产物渲染截图作为视觉证据。
- 11项相关服务均activeAPI/Gateway健康,Gateway结果Stream为`pending=0/lag=0`,发布窗口核心服务error级日志为空。仅部署测试环境`100.93.204.60`;预生产未访问或修改,未发送短信、未压测、未改账户、应用或通道配置。
## 2026-08-28 客户端工作台金额旧资源现场复核与直接文本发布
- Chrome真实已登录工作台现场确认用户看到的异常来自旧资源:页面仍加载`index-CbwHlDzn.css`和`index-BftfsVsS.js`,三个金额的真实DOM仍带`.client-amount-value`,计算样式为Arial/微软雅黑、38px、500;同时仍显示“余额水位”。这证明截图所见是旧标签页状态,不是上一轮新产物的计算结果。
- 为彻底消除首页金额专用路径,工作台移除全部`MoneyText`包装及其导入,四张指标卡金额/数量均改为无class、无子元素的`strong`直接文本;删除冗余`.metric-card--featured strong`规则。账户状态“最近充值”同样改为直接文本。全局`MoneyText`组件因其他业务页面仍使用而保留,但首页不再引用。
- 本地TypeScript检查和Vite生产构建通过;同正式CSS的浏览器渲染验证显示四个`strong`均无class、子元素数0,并全部为同一平台字体栈、30px、700字重、`rgb(17,24,39)`,控制台无error/warn。代码提交为`0b84370270c681dff3b15363f91b73566c6954b5`。
- Chrome真实标签尝试刷新时被本机客户端策略以`ERR_BLOCKED_BY_CLIENT`拦截私网地址,因此无法把刷新后的登录态页面冒充验收证据;服务器HTTP回读和远端产物门禁用于确认新发布资源。用户侧原标签需关闭后重新打开或强制刷新以脱离旧内存资源。
- 发布前新建并校验恢复点`/opt/cmpp-platform-backups/dashboard-direct-text-20260828T023121Z`,包含PostgreSQL custom dump、原运行目录、环境/systemd/Nginx配置、原部署标记和SHA-256清单;`pg_restore --list`、两份tar目录及全部摘要校验通过。95项migration无待执行项。
- 测试环境最终部署标记与代码提交一致,新资源为`index-9yfCJZo4.css`和`index-piRXc72V.js`;远端门禁确认CSS不含旧金额类和首卡专属strong规则,JavaScript不含“余额水位”。11项相关服务activeAPI/Gateway健康,Gateway结果Stream`pending=0/lag=0`,发布窗口核心服务error级日志为空。仅部署测试环境`100.93.204.60`,预生产未访问或修改。
## 2026-08-28 代码质量 P0 整改与测试环境发布
- 按`docs/code-quality-remediation-plan-20260828.md`执行发布阻断整改,代码提交依次为`2744690`(可信租户、强哈希、Redis登录状态、DTO/依赖/分包/门禁)、`d85ff85`(最长2小时的回退兼容窗口)、`fc4a6a7`(管理员和smoke维护工具只写强哈希)。最终测试环境部署标记为`fc4a6a7afcfc3c1c11d1e353f46d5b724f48a39e`。
- 真实双租户 API 矩阵通过:当前租户无header和一致header均成功;伪造其他租户header返回`403 CLIENT_TENANT_MISMATCH`;请求体tenantId被服务端覆盖为会话租户;跨租户应用资源ID返回404。一次性测试账号均清理,活跃`@integration.invalid`用户最终为0。
- 密码使用版本化scrypt格式,旧SHA-256只读兼容并在成功登录后条件更新。测试环境一次性旧哈希账号通过真实验证码和客户端登录接口迁移为scrypt后删除;4个未登录历史旧账号保持原值等待自然迁移。兼容环境变量已从配置和API进程移除,维护脚本真实创建的临时管理员也验证为scrypt后清理。
- API 47套542项、覆盖率69.77/53.47/71.08/73.05、前后端TypeScript/Vite构建、bundle budget、Gateway全包测试/go vet、Prisma、5份队列契约、代码质量和安全部署门禁全部通过。初始JS gzip约107.38 KiB;图表异步块约181.64 KiB,校准预算190 KiB。根生产依赖审计为0API子项目仍有2 moderate/7 high公告,既有兼容缓解门禁通过,需后续按兼容矩阵升级。
- 采用两阶段密码安全发布并在每次覆盖前重新建恢复资产:`code-quality-before-d85ff859-20260828T035007Z`、`code-quality-compatible-d85ff859-20260828T035426Z`、`code-quality-before-fc4a6a7-20260828T040150Z`。三份均含PostgreSQL custom dump、运行目录、配置、Redis RDB、MinIO数据、状态快照、回退说明和SHA-256;恢复清单、pg_restore、tar和Redis校验通过。
- 最终收尾为95/95迁移、11项服务active、入口HTTP 200、API/Gateway健康、Redis PONG、`gateway.submit.results pending=0/lag=0`,发布后7项核心服务error级日志均0。浏览器真实登录页完整且控制台error/warning为0;未自动输入账号密码/验证码,登录后深层页面仍保留为人工浏览器验收边界。
- 本轮没有发送短信、压测、修改余额/应用/通道或写入MinIO业务对象,也没有执行新的CMPP模拟器全链;两个SendChain超大Service未在安全发布中做高风险重构。完整证据和保留项见`docs/code-quality-remediation-result-20260828.md`。只操作测试环境`100.93.204.60`,预生产未访问或修改。
## 2026-08-28 代码质量 V2 复评与测试环境健康探测校正
- 固定`3af145abe5eb8cae567bb18e29116b4940889258`基线重新复评,原两个P0在代码、单测和结构门禁层面均已关闭;API 47套543项、全源覆盖率59.84/51.29/60.15/62.60、前后端构建、bundle budget、Gateway全包测试/go vet、Prisma及队列契约通过。正式报告为`docs/code-quality-reassessment-20260828-v2.md`。
- 首次外部健康探测时本机开启Clash虚拟网卡/代理,`100.93.204.60:12026/api/health`曾连续返回HTTP 502。关闭Clash后使用`curl --noproxy '*'`明确绕过代理,连续3次均返回HTTP 200、`status=ok`,总响应约1928msTCP 12026可连接;因此撤销“测试环境502”P0判定,确认为本地代理干扰,不是服务端故障。
- 本轮SSH只读认证未成功,未独立读取部署标记、内部服务、Redis Stream、migration和服务器日志;这些运行态项目继续保留为预生产前复核边界。未部署、未重启服务、未写库、未发送短信、未压测,预生产未访问或修改。
## 2026-08-28 代码质量持续优化执行
- 按`docs/code-quality-continuous-optimization-plan-20260828.md`实施非“暂不建议投入”项:补齐客户端凭据、Webhook、导出、文件、用户等运行时DTO与负向校验;浏览器端不再为客户端请求发送或回退租户ID,服务端继续只从认证会话取得客户端租户。
- 登录保护扩展为账号、来源IP和账号+IP三维失败计数,并增加IP维度验证码频率限制;Redis键只保存规范化值的SHA-256摘要。账号锁定仍为24小时,IP阈值为15分钟窗口30次,组合阈值为24小时5次;Prometheus新增有界事件/范围指标。
- 建立Vitest、Testing Library、jsdom、MSW前端测试基座,覆盖登录错误中文化、异步路由异常、客户端租户头禁止、401/403/500、文件/表单请求、用户列表loading/empty/error及删除确认。33项前端测试通过,纳入覆盖范围的核心模块为statements 88.19%、branches 84.51%、functions 84%、lines 87.94%,门禁为80/70/80/80。
- API增量覆盖门禁覆盖本轮新增DTO、动态JSON校验及登录安全逻辑,28项定向测试通过,覆盖率为86.78/78.29/95.83/89.84。API全量51套563项通过,全源覆盖率为70.44/53.77/71.76/73.61,较V2复评继续形成缓冲。
- 引入ESLint flat config、Prettier和实际增量文件门禁;`packageManager`固定为与测试环境一致的npm 10.9.4,正式提交仍只维护根目录/API两份`package-lock.json`。历史受保护的未跟踪`pnpm-lock.yaml`和空文件`=`保持原状且不纳入提交。
- 重新审计API依赖并将9项公告降至5项:Swagger、`js-yaml`、`fast-uri`和`brace-expansion`安全升级完成;剩余5项属于Prisma CLI同一开发/迁移链,唯一自动方案为破坏性降级Prisma 7至6,未执行`audit fix --force`。逐项路径和运行时判断见`docs/api-dependency-advisory-matrix-20260828.md`。
- 本地前后端TypeScript、Vite生产构建、bundle budget、Gateway全包测试与`go vet`、95项Prisma schema、代码质量、安全部署及依赖缓解门禁均通过。按方案明确排除全局ValidationPipe一次性切换、强制audit修复、ECharts替换和SendChain高风险重构;发布与真实环境证据在后续条目补齐。
- 实施提交为`ad27acad7e02b787185c972c710c73c867429c36`,随后以`226527f1cef122e4dbd163da782485e8c0254dc5`将jsdom降至兼容测试机Node 22.21.1的29.1.1,并用测试机同版npm 10.9.4重新生成两份lock。两项目`npm ci --dry-run --include=dev`、前端34项覆盖测试和API正式编译再次通过。向`origin/main`推送时远端Git服务拒绝当前凭据,故本地提交完成但远端未推送,未以部署成功冒充push成功。
- 第一次发布前恢复点`/opt/cmpp-platform-backups/code-quality-continuous-20260828T063123Z`约651MB且全部校验通过。首次覆盖在根依赖安装后、迁移/构建/重启前被npm 10发现API lock缺少可选依赖并安全停止;旧部署标记保持`fc4a6a7...`11项服务、API和Gateway健康,没有进入迁移或重启阶段。
- 修正后重新建立第二套恢复点`/opt/cmpp-platform-backups/code-quality-continuous-20260828T064405Z`约671MB,重新包含并校验PostgreSQL custom dump、当时运行目录、环境/systemd/Nginx、Redis RDB、三条Stream状态、MinIO对象清单、原部署标记和95项迁移。两套恢复点的SHA-256、`pg_restore --list`、tar目录与Redis RDB均通过,未复用第一次资产冒充第二次发布前基线。
- 最终发布包`outputs/cmpp-quality-226527f-20260828T0646Z.tar.gz`为2596543字节,本地/服务器SHA-256均为`e05f81798e4bbffc0b07ce6f30d10102f650bd50e23f26bb331fcb1708984de3`。测试环境部署标记为`226527f1cef122e4dbd163da782485e8c0254dc5`95项迁移无待执行项。
- 发布后API、Send Worker、Submit Outbox、Gateway Callback、Protocol Log Worker、Gateway、Security Agent、MinIO、Nginx、PostgreSQL和Redis全部activeAPI/Gateway健康、Redis PONG`gateway.submit.commands`、`gateway.submit.results`和`gateway.protocol.logs`均`pending=0/lag=0`,发布窗口error级日志0。Prometheus已暴露新的认证保护指标,临时发布/校验脚本已清理。
- 工作站显式`curl --noproxy '*'`验证首页、客户端登录、运营端登录、API健康和客户端验证码接口均HTTP 200。Chrome真实加载客户端和运营端登录页,客户端显示“返回官网”,页面资源为`index-BvZGIM6l.js/index-DyAqoJbu.css`,两页控制台error/warning均0;未输入密码或代解验证码,登录后页面继续作为人工验收边界。
- 全程只操作测试环境`100.93.204.60`,未访问、回退、覆盖或部署预生产`8.160.169.106`;未发送、补发或重投短信,未修改余额、应用、通道或客户连接。
## 2026-08-28 代码质量持续优化补充关闭
- C2沿用同一运行代码的真实双租户API矩阵证据:客户端无租户header和一致header成功、伪造其他租户header返回`403 CLIENT_TENANT_MISMATCH`、请求体tenantId不能覆盖会话租户、跨租户资源返回404;本轮前端34项测试继续验证`/api/client/**`不发送`x-tenant-id`,管理端显式租户选择不受影响。登录后可见页面由用户按`docs/code-quality-browser-acceptance-checklist-20260828.md`人工验收,结果回填前不把浏览器验收标记为关闭。
- C5新增`tools/testing/verify-auth-redis-multi-instance.mjs`真实Redis契约。两个独立`SessionService`实例共用隔离Redis,验证跨实例会话、验证码一次性消费、验证码第31次拒绝、账号/组合第5次锁定、随机账号扫描同IP第30次锁定、15分钟/24小时TTL及SHA-256键;测试完成后隔离库`dbsize=0`。另补Redis不可用时验证码、锁查询和失败记录均返回服务不可用的fail-closed单测。
- C9不执行任何npm、Node、Prisma或依赖降级;继续使用上一轮已部署验证的npm 10.9.4和根/API两份`package-lock.json`,经文件所有者授权移除旧的未跟踪`pnpm-lock.yaml`。质量门禁由“只检查已跟踪替代锁”收紧为仓库根目录只要出现`pnpm-lock.yaml`或`yarn.lock`即失败;空文件`=`及其他会话产生的评估报告修改继续保留、不纳入本次提交。
- C8只新增`docs/sendchain-service-decomposition-plan-20260828.md`,按认证、长短信、Inbox Repository/Worker、消息准备/持久化、Worker生命周期、路由、限速、Submit命令、Outbox和任务进度刷新分S0~S8实施;本轮没有修改发送链运行代码。
- 回归通过:认证相关3套26项、API全量Jest、前端34项、API/前端TypeScript、Vite生产构建、真实Redis多实例契约、ESLint、Prettier、结构质量和依赖缓解门禁。首次从仓库根目录启动Jest时误扫描`outputs/`历史副本且未加载API转换配置,随后使用`api/jest.config.cjs`明确项目范围通过;未修改受保护历史资产。
- 本轮运行代码没有变化,测试环境仍运行已验证的`226527f1cef122e4dbd163da782485e8c0254dc5`,因此没有重复建立恢复资产或形式化重新部署。未访问预生产,未写入测试环境业务数据,未发送、补发或重投短信。
## 2026-08-28 签名与引流三网状态及引流字段统一发布
- 重新验证本地基线为`main`,实施前`HEAD=origin/main=9ac41e9`;既有`docs/code-quality-reassessment-20260828-v2.md`修改、未跟踪`docs/code-quality-reassessment-20260828-v3.md`和空文件`=`均保留且未纳入提交。本轮功能提交为`c68ac7a3db82d1bdb867260378df18f93cca0fd2`,未推送远端。
- 客户端签名与引流列表将移动、联通、电信改为同一组三网状态卡片,签名和引流行统一显示真实汇总得到的“报备通过/暂不可用”。新增/修改弹窗移除“名称”,将“访问地址”统一为“引流 URL 或号码”;URL 保持安全外链,手机和固定电话按普通文本展示。
- 客户端和运营端不再提交独立`siteName`。后端 DTO 与领域服务真实接受`http/https` URL、手机号码和固定电话号码,拒绝空值及任意文字;既有非空兼容列由服务端同步写入同一规范化目标。单条审核、审核详情、导入审核、报备任务、报备记录、导入映射和官方模板同步移除独立站点名称口径,没有使用 mock、静态数据或 localStorage 代替产品功能。
- 本地门禁通过:前端 Vitest 5个文件36项、TypeScript、Vite生产构建和bundle预算通过;API Jest 51套571项、TypeScript正式构建和Prisma schema校验通过;Gateway`go test ./... -count=1`与`go vet ./...`、增量Lint/Prettier、结构质量及`git diff --check`通过。专项用例覆盖URL、手机、带格式手机、固定电话、分机号、非法文字拒绝、兼容列同步和官方模板无站点名称。
- 应用内Browser访问测试机在导航阶段连续两次超时并重置,未据此声称登录后线上页面已验收。随后用与正式发布一致的生产构建做本地API拦截视觉夹具:桌面展开态和新增弹窗、390px窄屏均渲染正常,页面级横向溢出为false,URL为`A`、固定电话为`SPAN`,弹窗不存在“名称/访问地址”,控制台事件0。夹具只用于布局回归,不作为线上业务数据证据。
- 部署前测试机真实基线为`226527f1cef122e4dbd163da782485e8c0254dc5`,源码与数据库均95项migration11项相关服务activeAPI/Gateway/Redis健康。新恢复点`/opt/cmpp-platform-backups/drainage-carrier-ui-20260828T092840Z`包含238MB PostgreSQL custom dump、211MB完整运行目录、24KB环境/systemd/Nginx配置、原部署标记、服务/Stream状态和恢复说明;`pg_restore --list`842行、运行tar 52592项、配置tar 309项,`sha256sum -c`全部成功后才开始覆盖。
- 精确Git归档`outputs/cmpp-drainage-carrier-ui-c68ac7a-20260828T092917Z.tar.gz`为2612752字节,本地和服务器SHA-256均为`ef39ebdef18efc5937b2e4001398d4cb4667f739c1fe6b4a2206208ff280054f`且tar可读。标准部署脚本完成两套依赖安装、安全门禁、Prisma、前端/API/Gateway构建、Nginx校验和服务重启;95项migration无待执行项,旧运行目录保留为`/opt/cmpp-platform.previous-drainage-20260828T093754Z`。
- 测试环境最终`.deployed-commit=c68ac7a3db82d1bdb867260378df18f93cca0fd2`。11项相关服务均activeAPI、Gateway、Gateway Callback健康,Redis PONG`gateway.submit.commands`、`gateway.submit.results`、`gateway.protocol.logs`全部`pending=0/lag=0`,发布窗口7项核心服务error级journal均为0。
- 线上前端资源为`index-BLUa_d1S.js`、`index-BB9q6lcg.css`、`ClientSignaturesPage-COD8bZjo.js`和`AdminDrainageAuditPage-Dg8qCDBw.js`;服务器与工作站HTTP回读SHA-256一致。首页、客户端登录、运营端登录和API健康均HTTP 200。真实测试库当前未删除引流信息为0,因此未创建业务记录模拟页面数据,也未执行审核写操作;未发送、补发或重投短信,未修改余额、通道或客户配置。
- 仅部署测试环境`100.93.204.60`;预生产`8.160.169.106`未访问、未部署、未覆盖、未回退或修改。
### 追加:不带协议的 URL 校验放宽
- 用户追加要求引流 URL 不一定以`http`开头。增量提交`5328bb09bf89170b4368407e896dbce9527a7b5c`将 DTO 和领域服务统一改用同一校验器:接受`https://example.com/path`、`example.com/path`、`www.example.com`、IPv4地址、手机和固定电话,继续拒绝无域名结构的普通文字;客户端和运营端提示同步改为“支持带或不带协议的 URL”。
- 增量专项 API 2套79项及前端2项通过;完整回归为前端5个文件36项、API 51套575项,两端TypeScript和Vite生产构建、bundle预算、增量Lint/Prettier及`git diff --check`通过。视觉夹具重新加载新产物,弹窗提示包含“不带协议”,名称/访问地址仍不存在,390px窄屏正常且控制台事件0。
- 第二次部署没有复用首轮恢复点。新恢复点`/opt/cmpp-platform-backups/drainage-schemeless-url-20260828T095954Z`以`c68ac7a3db82d1bdb867260378df18f93cca0fd2`为原标记,包含238MB PostgreSQL custom dump、211MB完整运行目录、24KB环境/systemd/Nginx配置及状态/恢复说明;`pg_restore --list`842行、运行tar 52597项、配置tar 309项,`sha256sum -c`全部成功。
- 第二次精确包`outputs/cmpp-drainage-schemeless-5328bb0-20260828T100028Z.tar.gz`为2614570字节,本地和服务器SHA-256均为`20665da0321eeb8a82ba9ca3cc3c595c3b38db439d530b34b1f03f1578f6fe64`且tar可读。标准脚本完成无待执行的95项migration及全部构建/重启;旧运行目录保留为`/opt/cmpp-platform.previous-schemeless-20260828T100204Z`。
- 测试环境最终`.deployed-commit=5328bb09bf89170b4368407e896dbce9527a7b5c`。11项服务activeAPI/Gateway/Callback健康,Redis PONG,三条Stream均`pending=0/lag=0`,发布窗口7项核心服务error级journal均为0。线上新资源为`index-C_Eutz1B.js`、`index-BB9q6lcg.css`、`ClientSignaturesPage-CFLWpVlL.js`和`AdminEnterpriseSignaturesPage-9HtQnQ7y.js`;服务器与工作站HTTP回读哈希一致,四个入口均HTTP 200。
- 本次追加仍未写入业务引流记录、未执行审核操作、未发送短信,未修改余额、通道或客户配置;预生产未访问或修改。
## 2026-08-30 签名与引流改造推送及预生产发布
- 重新验证本地分支为`main`,功能/校验/测试环境证据提交依次为`c68ac7a`、`5328bb0`、`4d526b8`。Chrome 中已登录的 Gitea 会话使 Git Credential Manager 完成认证,`main`已成功推送到`origin/main`;推送前后均保留既有`docs/code-quality-reassessment-20260828-v2.md`修改、未跟踪`docs/code-quality-reassessment-20260828-v3.md`和空文件`=`,未将其暂存或提交。
- 预生产发布前重新只读核验`8.160.169.106`:原`.deployed-commit=523481299028d9ded470d7738add145ee2070bd1`,源码/数据库均94项migrationAPI、Send Worker、Gateway、Security Agent、MinIO、Nginx、PostgreSQL和Redis均activeAPI/Gateway健康、Redis PONG。独立Outbox、Callback和Protocol Log Worker环境开关未启用,因此对应服务保持inactive,不在本轮变更中擅自开启。
- 覆盖前建立新恢复点`/opt/cmpp-platform-backups/preprod-drainage-ui-20260830T130719Z`,包含184MB PostgreSQL custom dump、180MB当前运行目录、32KB环境/systemd/Nginx配置、原部署标记、服务/migration/Stream状态和恢复说明。`pg_restore --list`为840行,运行tar为40970项、配置tar为158项;部署前验证通过,发布后再次执行`pg_restore --list`、两份tar可读性和`sha256sum -c`,全部成功。
- 精确发布包`outputs/cmpp-preprod-drainage-ui-4d526b8-20260830T130904Z.tar.gz`为2615300字节,本地与服务器SHA-256均为`1e98a102aa6cacfb6068ec0a8f34d28d9adfa59eef45f704fc9100abd9d8afcc`且tar可读。标准发布脚本完成依赖安装、安全门禁、Prisma迁移、前端/API/Gateway构建、Nginx检查、服务重启和健康检查;旧运行目录保留为`/opt/cmpp-platform.previous-preprod-drainage-20260830T131034Z`。
- 预生产最终`.deployed-commit=4d526b83abe73a495945137e88fd7b679565d0bf``20260826170000_add_uplink_gateway_message_id`已应用,源码与数据库均95项migration`SmsUplinkMessage.gatewayMessageId`列存在。API、Send Worker、Gateway、Security Agent、MinIO、Nginx、PostgreSQL和Redis均activeAPI`/api/health`与Gateway`:8090/health`返回okRedis PONG。按既有开关,Submit Outbox、Gateway Callback和Protocol Log Worker继续inactive。
- Redis Stream只读回读:`gateway.submit.commands`的`cmpp-gateway`组`pending=0/lag=0``gateway.submit.results`的`cmpp-api-callback`组`pending=0/lag=0``gateway.protocol.logs`长度9670且当前没有consumer group,和Protocol Log Worker未启用一致,不虚构pending/lag数值。发布窗口API、Send Worker、Gateway、Security Agent和Nginx的error级journal均无记录。
- 预生产资源为`index-C_Eutz1B.js`、`index-BB9q6lcg.css`、`ClientSignaturesPage-CFLWpVlL.js`、`AdminEnterpriseSignaturesPage-9HtQnQ7y.js`和`AdminDrainageAuditPage-C7jiPhpY.js`。工作站实际下载的主JS/CSS SHA-256分别为`341d5132909b0f3b06aafc7784c6fd0d33da7d00ebbdd298a7b401c074f98469`、`0c91342b01fdb798ccd15f1607301a4a0034802e4c3a8f6fb961c1e9ad18ac1a`,与服务器产物一致;客户端页面块含“不带协议”,不含旧“支持 http/https URL”提示和“访问地址”。首页、客户端登录、运营端登录和API健康均HTTP 200。
- Chrome可连接且其登录态已用于Git推送,但预生产HTTP页面自动化读取连续超时,因此本轮不声称完成浏览器DOM/控制台验收;外网HTTP、真实静态资源哈希、服务健康、Stream和发布日志证据均已独立通过。发布过程中未发送、补发或重投短信,未修改余额、通道、客户或引流业务记录,也未执行审核写操作。
## 2026-08-30 预生产完整拆分架构升级与协议日志ACK竞态修复
- 重新验证`main=origin/main=6777450`,预生产运行代码为`4d526b8`且95/95项migration一致;差距不是代码版本,而是`cmpp-submit-outbox`、`cmpp-gateway-callback`和`cmpp-protocol-log-worker`三项独立进程的环境开关未设置。升级前Submit Outbox为0PostgreSQL活动连接约12/100Gateway供应商连接9/9,三池采用测试环境已验证的6/12/4槽后总连接池预算为62/100。
- 完整架构参数启用Submit Outbox影子/正式发布及独立进程,Outbox池6、指标9467Gateway Callback独立进程回环`127.0.0.1:3001`、池12、指标9468、Gateway事件面指向`http://127.0.0.1:3001/api`并按50条批量回调;协议日志Stream Worker池4、组`cmpp-protocol-log-writer`、读取批次250Callback重复协议跟踪保持关闭。主API继续承担控制面,Send Worker、Outbox、Callback和Protocol Log职责不重复。
- 第一次恢复点创建曾因目录只允许root、PostgreSQL子进程不能写dump而在任何配置修改或服务重启前安全停止,目录保留为`/opt/cmpp-platform-backups/preprod-full-split-architecture-20260830T133411Z.incomplete`,未当作恢复资产。重新创建的有效恢复点`/opt/cmpp-platform-backups/preprod-full-split-architecture-20260830T133555Z`包含192442604字节custom dump、217862064字节运行目录、33114字节环境/systemd/Nginx/Prometheus配置、184207194字节Redis RDB、原标记及服务/migration/Stream状态;`pg_restore --list`840行、运行tar 52617项、配置tar 63项,全部文件均通过SHA-256。
- 首次配置切换和标准发布成功后,三项进程均active,但真实历史积压暴露协议日志Worker竞态:9670条Stream事件已写入数据库却仍全部pending。根因是`recordMany`触发首批异步flush后,紧接的`flushNow`看到flushing便返回false;即使没有竞态,旧实现也可能只写首个100条数据库批次就返回成功,和一次读取250条的ACK边界不一致。立即停止Protocol Log Worker,保留9670条pending,不手工ACK/XDELOutbox、Callback及发送链其他服务继续运行。
- 修复提交`1a5063a7c635280b912021c42c33a07c99f4c5dd`让并发flush共享同一个完成Promise,并循环写完缓冲区全部数据库批次后才返回成功;写库失败会把当前批次放回缓冲区并返回false。新增`TC-PROTOCOL-LOG-017`锁定“大于数据库批次、首批未完成时再次flush、全部持久化后才ACK”的行为。专项5/5、API全量51套576项、API正式TypeScript构建、ESLint及`git diff --check`通过,提交已推送`origin/main`。
- 第二次发布没有复用第一份恢复资产。新恢复点`/opt/cmpp-platform-backups/preprod-protocol-flush-fix-20260830T135502Z`保存193258264字节custom dump、217856577字节当前运行目录、33271字节配置、184604385字节Redis RDB及当时Worker停机/pending/重复日志现场;同样完成840行`pg_restore --list`、52617项运行tar、63项配置tar和全部SHA-256验证。修复包`outputs/cmpp-preprod-protocol-flush-1a5063a-20260830T1357Z.tar.gz`为2617814字节,本地/服务器SHA-256均为`4131ffa5f1f26ef01ffa5146165b6c0865c743003befc839ec4a0ee2b59e88d0`且tar可读;旧运行目录为`/opt/cmpp-platform.previous-protocol-flush-20260830T135712Z`。
- 修复发布后9670条Stream积压一次性完成持久化和ACK/XDEL`gateway.protocol.logs`最终`长度=0/pending=0/lag=0`。失败窗口数据库中24340行对应9670个唯一eventId,精确识别14670条重复行;在第二份数据库/Redis恢复点保护下,只删除`2026-08-30 13:37:00`后同一eventId的第2条及以后记录,保留最早一条,最终为9670行/9670个唯一eventId,未触及短信、账务及其他日志。
- 最终`.deployed-commit=1a5063a7c635280b912021c42c33a07c99f4c5dd`95/95项migrationAPI、Send Worker、Submit Outbox、Gateway Callback、Protocol Log Worker、Gateway、Security Agent、MinIO、Nginx、PostgreSQL和Redis共11项均active,三项拆分服务均enabled。API、Callback、Gateway健康,9464/9465/9467/9468指标端点可用,Callback池`max=12,total=1,idle=1,waiting=0`,供应商连接9/9,数据库活动连接15/100Submit Outbox为0;命令、结果、协议日志三条Stream均`pending=0/lag=0`,修复发布窗口8项服务error级journal均为空。
- 首页、客户端登录、运营端登录及API健康从工作站直连均HTTP 200;实际资源仍为`index-C_Eutz1B.js`和`index-BB9q6lcg.css`,工作站与服务器SHA-256一致。Chrome只读导航该私网HTTP页面再次超时,因此不声称完成浏览器DOM/控制台验收。全程未发送、补发或重投短信,未修改余额、通道、客户或签名/引流业务配置。
## 2026-08-31 预生产磁盘清理与数据盘第一阶段
- 用户授权只保留上一个版本后,核验`4d526b8`的上一运行目录和完整恢复点,删除52项旧发布/失败/回滚目录及旧部署备份,释放约31.2GiB,系统盘占用80%降至25%;保留业务操作记录,未修改数据库或重启服务。历史章节所列更早恢复点是历史证据,不代表清理后仍可用。
- 用户随后明确授权仅执行数据盘第一阶段,第二阶段等待今晚指令。100GiB数据盘已建GPT/ext4分区并按UUID挂载`/data``/etc/fstab`验证通过,完成挂载单元启停验证,未重启整机。
- 固定备份入口`/opt/cmpp-platform-backups`原子切换为指向`/data/cmpp-platform-backups`的符号链接;约573MiB备份以10MiB/s限速迁移,21个文件/目录条目的内容、属主、权限、mtime和扩展属性一致,SHA256SUMS、数据库备份目录及两份tar可读性全部通过,再删除系统盘副本。
- `/usr/local/sbin/cmpp-backup-storage-check`核验挂载及UUID;底层空`/data`设置immutable。已实测缺盘时检查拒绝执行且root不能写回系统盘,挂载后原备份入口实际写入数据盘。未创建自动备份或自动迁移计划。
- 09:35复核系统盘24%(可用44G),数据盘1%(可用97G);11项服务active且PID与操作前一致,API/Callback/Gateway健康、PostgreSQL接受连接、Redis PONG,所检查服务error级journal计数0。代码版本仍为`1a5063a`PostgreSQL/Redis/MinIO和运行目录均未迁移,未执行第二阶段。
- 配置、保护机制、验证范围及证据路径见`docs/preprod-data-disk-stage1-20260831.md`。本轮只修改服务器存储配置/备份入口和本地运维文档,未提交、推送或发布代码。
## 2026-08-31 预生产存储规范文档补齐(仅本地文档)
- `docs/production-deployment.md`新增“预生产磁盘与目录规划”,统一系统盘/数据盘分工、目标目录、挂载和权限保护、版本保留、容量管理及第二阶段验收要求;区分09:35已记录的第一阶段状态和待实施规划。
- 第一阶段记录增加到正式规范的链接;早期Linux部署方案标记为历史示例,统一固定备份入口、区分SQL/custom备份恢复,并纠正“删除未消费Redis队列”的旧回滚指引。
- 本次仅修改本地Markdown文档,没有访问或修改服务器、调整脚本、启用告警/清理任务、迁移业务数据、提交或推送。第二阶段仍未执行,须等待用户明确指令。
## 2026-08-31 六项运营/客户端修复(测试环境发布准备)
- 本轮仅授权测试环境 `100.93.204.60`,不访问、不部署预生产。开始时核验 main/HEAD `119d577` 与测试部署标记 `5328bb09bf89170b4368407e896dbce9527a7b5c`;原有4份已修改文档及3项未跟踪文件完整保留,不纳入本轮提交。
- 通用字段增加原位修改入口和 PUT API,可修改引用字段、资料用途和必填要求;服务端检查有效字段/重复组合,事务保存配置与操作日志,不改历史资料快照。两端签名表单使用同一后端字段合并结果,切换应用丢弃旧请求,加载失败禁止提交;修复同字段多资料用途快照覆盖及已删除通道残留资料要求。
- 客户端签名列表与统计的删除排除条件不再被 status 参数覆盖;签名/模板已删除对象禁止再次提交。模板列表原有后台删除过滤核验并补回归;两页刷新拒绝旧请求覆盖,防止删除后被旧响应重新显示。测试机基线真实 PostgreSQL:2租户、26签名、11模板,当前无 deleted 样本;18应用加通用配置共19组签名字段与运营端投影完全一致,未用此基线冒充有删除样本的实测。
- 发送记录列表只在发送状态下显示正向“含引流”标签,去掉回执时间列;详情显示含/不含引流(未检测历史记录明确标识),按真实检测位置高亮内容,新增“最终回执时间”,保留各通道路由回执信息。
- 客户端批量任务、发送详情、上行短信复用运营端查询/重置组件;输入条件与已应用条件分离,输入不发请求,查询/重置回第一页,分页仅使用上次确认条件,修复上行从第二页返回第一页不加载的问题。
- 监控磁盘查询从根目录限制改为全部实际块设备文件系统,按 instance/device/mountpoint/fstype 对齐容量和趋势;系统盘、数据盘及其他挂载点独立卡片/趋势,缺点不填假值。容量和inode规则覆盖所有磁盘并注明设备/挂载点,保留原告警名及阈值兼容性。
- 验证:API全量51套/581项、前端8文件/45项通过;前后端 TypeScript、Vite构建、依赖安全、部署契约与包体积检查通过。新增独立页面/接口/监控文件定向 ESLint 通过;修改范围整体 ESLint 仍有既存领域拆分未用导入及页面Hook规则问题,不宣称全仓lint通过。自动化测试中的隔离stub仅用于回归,产品仍调用真实API。
- 发布前观察:三条 Redis Stream pending/lag 均0;测试机仅有 `/dev/sda2` 挂载 `/`Prometheus采集容量105086115840字节;Security Agent既有 `/run/cmpp-security-agent` 缺失导致226/NAMESPACE重启,已记录。Tailscale链路曾短暂中断,恢复后HTTP健康200。浏览器自动化多次读取/导航超时,尚未完成真实页面和控制台验收,不以DOM单测或构建替代。
- 此节为发布准备记录:独立恢复资产正在建立;未通过 pg_restore --list、tar可读性及SHA-256前不部署。最终发布标记、恢复点、服务/健康/资源哈希与验收边界在后续发布记录补充。
## 2026-08-31 六项修复测试环境发布完成
- 已提交代码 `b0deef5e6ebe6adbfe85591c53dedf11866880a0``fix: align reporting fields queries and disk monitoring`),2026-08-31 12:22(北京时间)部署至测试环境 `100.93.204.60:12026`;发布后读取 `.deployed-commit` 与代码提交完全一致。本轮未推送远端,未访问或修改预生产。
- 本次独立恢复点:`/opt/cmpp-platform-backups/six-fixes-20260831T041541Z`。含 PostgreSQL custom dump249150883字节)、当前运行目录归档(排除另存的历史备份及易变日志)、环境/systemd/Nginx/Prometheus等配置归档、Redis RDB、原部署标记及服务/Stream基线;`pg_restore --list`、两份tar可读性、全部11项SHA-256清单校验通过,部署前再次复核通过。
- 发布包仅由已提交代码生成,SHA-256为 `c87ecb6f341ccb6cc3275594223f57a573bfa98220521c1eb4c42aca6279b6a2`;依赖锁、Prisma结构/迁移及Gateway源码与旧运行版本一致,复用Linux依赖并重新构建前后端;没有迁移业务数据库、修改账户/余额/通道/客户配置或发送、补发、重投短信。旧运行目录保留于 `/opt/cmpp-platform.previous-sixfix-20260831T042224Z`。
- 发布后8项CMPP服务及Nginx/PostgreSQL/Redis/Prometheus共12项服务activeAPI/Callback/Gateway健康通过,外部入口 `/api/health` HTTP 200;三条Streamsubmit.commands、submit.results、protocol.logspending/lag均0。发布窗口相关服务error级journal无记录,各应用文件日志相对发布前偏移的新增内容未见ERROR/FATAL/panic/Unhandled/Exception。
- 已恢复测试机Security Agent既有运行目录缺失问题,服务自12:22:49持续active,复核累计重启计数17197未再增加。此处仅恢复 `/run/cmpp-security-agent`,未修改安全策略;现有unit没有RuntimeDirectory声明,整机重启后的目录持久保障仍是既存运维风险,不在本次六项业务修复中宣称解决。
- 真实PostgreSQL/已部署服务复核:2租户、26签名、11模板保持一致;18应用及通用配置共19组客户端/运营签名报备字段一致,删除过滤检查通过。另在隔离真实数据库事务内验证通用字段更新、客户端字段变化及1条审计日志,随后完整回滚全部验证数据;不是已完成登录浏览器或鉴权HTTP全流程验收的替代。
- Prometheus已实际加载覆盖全部块设备挂载点的容量告警,警告80%/严重90%保持原配置;全部规则health=ok、无重复规则名、无仅根挂载点的查询限制。真实监控服务返回系统盘 `/dev/sda2 /`、容量105086115840字节及61个趋势点;测试机只有这一块已采集磁盘,多盘对齐以三磁盘回归测试覆盖,不虚报真实多盘验收。
- 外部HTTP实际下载的主JS/CSS与服务器文件SHA-256一致:`index-BaM_U9uq.js`=`b14c2ee21f80d718e6f78289cc6e676f215c2e16bd24712202df731aeadb3d6f``index-D8PbKTXI.css`=`86b17c3845da62022861df97536db00df9d241ceac9677434d7028286e0ac0ca`;本次涉及的8个页面JS(通用字段、发送记录、系统监控、客户端签名/模板/批量任务/发送详情/上行短信)逐个下载与本地构建哈希一致。
- 回归结果维持API 581项、前端45项通过,测试用例见 `TC-PORTAL-001..010`。浏览器插件在网络恢复后仍多次导航、截图及DOM读取超时,真实页面视觉效果、浏览器控制台及登录后交互验收尚未完成,留待用户在测试环境验收,不标记为已通过。
- 证据:服务器 `/tmp/cmpp-sixfix-deploy.log`、`/tmp/cmpp-sixfix-before.json`、`/tmp/cmpp-sixfix-after.json` 及恢复点清单。提交时仅纳入本轮代码/用例/进度追加,原有4份修改文档及3项未跟踪文件仍保留为未提交状态。
## 2026-08-31 预生产数据盘第二阶段完成
- 用户明确授权后重新核验预生产`8.160.169.106`,仅迁移PostgreSQL、Redis、MinIO。停写窗口22:31:57至22:33:1477秒);API短时不可用、CMPP连接断开后重连,未宣称零中断。
- 当前版本恢复点`/data/cmpp-platform-backups/preprod-storage-stage2-20260831T142327Z`包含在线PostgreSQL custom dump、全局角色、运行目录、系统配置、冻结前后表/Stream/对象清单、冷文件校验清单及三服务一致性冷备`cold-storage.tar.gz`。配置备份首次因不存在的`/etc/sysconfig/pgsql`中止,重新生成并校验后才进入停写窗口;不是带着不完整备份切换。
- 停入口/Worker并核对Gateway在途和Outbox为0,停Gateway/Callback/Protocol Log Worker,执行Redis SAVE后停止三项存储。PostgreSQL状态`shut down`,以40MiB/s复制:PG 2225条目/2373269966字节、Redis 2条目/184085437字节、MinIO 249条目/40914208字节;全部文件内容SHA-256、属主、权限、mtime及扩展属性一致。
- `/data/postgresql`、`/data/redis`、`/data/minio`分别绑定挂载至原`/var/lib/pgsql`、`/var/lib/redis`、`/var/lib/minio`fstab和三个`50-cmpp-data-disk.conf`建立启动/存续依赖,ExecStartPre检查UUID、绑定源、只读状态和既有存储标记。底层空挂载点immutable;隔离mount namespace中缺盘、缺绑定、错绑定和只读负向检查通过,宿主挂载及存储服务PID未受负向测试影响。
- 恢复业务前110张public表精确行数一致,三条Stream的长度及组状态一致,62个对象清单一致;PostgreSQL临时表事务、Redis随机key和MinIO随机对象的真实读写/回滚或删除通过。未发送或重投短信,不以探针冒充端到端短信验收。
- 最终11项服务active,上游9/9、下游4个,命令/结果/协议Stream pending/lag均0API/Callback/Gateway/MinIO健康、PostgreSQL接受连接、Redis PONG、外网API健康通过。重连初期下游短暂为2个,随后已恢复4个;恢复后所查服务error级journal为0。
- 数据盘承载业务数据,系统盘仍保留约2.4GiB三项原数据冷副本作本次迁移保护;禁止新位置接受写入后直接切回旧副本。上一代码版本`4d526b8`恢复点继续保留;日志、监控数据未迁移,整机重启与异机恢复未测试。
- 本地及线上两份部署/安装脚本加入存储前置检查,新增`tools/deploy/check-data-storage.sh`bash语法和缺挂载拒绝执行验证通过。业务产物标记仍为`1a5063a`,仅运维脚本及存储配置改动;未Git提交、推送或发布新业务产物。详见`docs/preprod-data-disk-stage2-20260831.md`及`outputs/data-disk-stage2-*.txt`。
## 2026-08-31 迁移后预生产六项修复发布准备
- 用户明确授权推送最新代码并发布预生产,提醒数据迁移已完成。重新读取迁移记录及线上事实:预生产业务标记仍为 `1a5063a`,三项存储分别绑定到 `/data/postgresql`、`/data/redis`、`/data/minio`,数据盘UUID为 `ef4ee3bb-a19b-4aeb-b00c-aa2b995611c2`,备份入口解析到 `/data/cmpp-platform-backups`12项服务active,三条Stream pending/lag为0。
- 三份尚未提交的迁移保护脚本与线上LF归一化SHA逐项一致,本轮仅接续提交 `production-bootstrap.sh`、`production-deploy.sh`、`check-data-storage.sh`,其余原有修改及未跟踪文档保持不动。补充部署契约及 `TC-STORAGE-DEPLOY-001/002`,隔离mount namespace中隐藏Redis绑定后两入口前置部分均拒绝继续,宿主挂载与存储PID不变。
- 本次发布只切换应用代码和相关监控规则,不重新迁移/恢复数据库,不重启PostgreSQL、Redis或MinIO,不改fstab、存储保护、环境及业务配置。首份新恢复资产因Redis配置路径错误在tar阶段中止,未部署;核实 `/etc/redis/redis.conf` 后重新建立完整资产,最终证据另记。
## 2026-08-31 迁移后预生产六项修复发布完成
- 已将六项修复及迁移保护提交推送到 `origin/main`,发布版本 `9a15d28da56af62225856b361ce2946466cc7210`。首次HTTP推送认证失败,经Git Credential Manager交互重试成功,随后远端ref独立回读一致;没有改远端地址或强制推送。
- 本轮重新建立的有效恢复点为 `/data/cmpp-platform-backups/preprod-six-fixes-20260831T145909Z`(原固定备份入口仍可访问)。PostgreSQL custom dump 195212320字节、运行归档221146521字节、配置归档230962字节,另含全局角色、Redis RDB、原标记、服务/PID/挂载/Stream基线及受保护配置清单;`pg_restore --list`、两份tar可读性及全部16项SHA均通过,准备和切换前重复校验通过。首次中止目录 `preprod-six-fixes-20260831T145538Z` 保留但不作为有效恢复点。
- 精确Git发布包SHA为 `d696da5a21257f86e7ce2ed82ff02b1943311663811601c01d6ff44611af7c1a`。先在独立目录核验依赖锁、Prisma结构/迁移、Gateway源码及三份存储保护脚本与运行环境一致,复用Linux依赖、重新构建前后端;未执行数据库迁移或账号初始化。数据库仍为95项已完成migration。
- 23:07:16(北京时间)进入应用切换,23:07:19 API/Callback/Gateway均健康;期间存在短暂API不可用及CMPP重连,不宣称零中断。最终 `.deployed-commit` 为 `9a15d28`,上一运行目录保留为 `/opt/cmpp-platform.previous-preprod-sixfix-9a15d28`;失败恢复仅针对应用/规则,不恢复系统盘旧数据。
- 发布前后PostgreSQL/Redis/MinIO PID分别保持2196113/2196112/2196114,未重启、未重新迁移。数据盘UUID、三个绑定源/目标及既有存储标记检查通过;fstab、环境文件、UUID文件、两份保护检查器和三个systemd存储drop-in的SHA逐项不变。系统盘旧冷副本、迁移冷备及其他既有恢复点均未删除。
- 12项相关服务active7项重启应用服务NRestarts均0API/Callback/Gateway/MinIO健康HTTP 200Redis PONG;三条Stream pending/lag均0且entries-read/last-delivered-id与本轮基线一致。上游连接先为6/9,23:12:20自动恢复9/9,后续指标与数据库状态再次确认9/9;下游恢复4个。未手工重连、发送、补发、重投或修改客户/余额/通道配置。
- 真实部署服务/PostgreSQL只读核验:149租户,49条deleted签名与38条deleted模板未出现在客户端列表中;客户端签名105条、含历史模板12条,6组签名报备字段与运营投影一致。本轮未在预生产创建测试字段或执行审核写操作,未把直接服务检查冒充鉴权HTTP/浏览器交互验收。
- 真实监控返回系统盘 `/dev/nvme0n1p2 /`、EFI分区、数据盘 `/dev/nvme1n1p1 /data` 及三个存储绑定挂载点;根/数据盘各61个趋势点,新迁移绑定点36个,均来自Prometheus而非补零或模拟数据。容量告警覆盖全部块设备挂载点,保留原有效80%/90%阈值;43条基础规则和20条托管规则校验通过,已加载规则全部health=ok、无同名重复、无仅根目录的查询限制。
- 发布窗口error级journal无记录,但文件日志不是零错误:Gateway重连阶段有连接数限制403及关闭连接日志;API 23:07:39出现一次日报刷新5秒事务超时。旧运行日志在08-30及迁盘后的22:33:33已有同类日报错误,报表产物与旧版本字节一致,本轮未扩大范围修复。23:10:28至23:13:50稳定性复核,所有应用新增日志未再检出ERROR/FATAL/panic/Unhandled/Exception;此观察不代表既存日报问题已解决。
- 外部首页、两端登录入口及API健康均HTTP 200;主JS/CSS和8个改动页面JS实际HTTP下载SHA全部与服务器产物一致。主资源 `index-BaM_U9uq.js` SHA为 `b14c2ee21f80d718e6f78289cc6e676f215c2e16bd24712202df731aeadb3d6f``index-D8PbKTXI.css` SHA为 `86b17c3845da62022861df97536db00df9d241ceac9677434d7028286e0ac0ca`。
- 本轮API51套581项通过;前端初次fork工作进程启动超时,改threads/单worker重跑8文件45项通过;前后端TypeScript、Vite、依赖安全、部署契约、包体积、bash语法及隔离缺挂载负向检查通过。browser技能路径中Chrome标签发现可用,但旧标签DOM读取及新标签导航均超时,真实页面身份/非空/错误遮罩/控制台/截图/交互六项均未完成;没有切换未授权的浏览器控制替代方式。
- 线上证据:`/tmp/cmpp-preprod-sixfix-activate.log`、`/tmp/cmpp-preprod-sixfix-backend-after.json`、`/tmp/cmpp-preprod-sixfix-postcheck.json`(保留首次日志失败)和 `/tmp/cmpp-preprod-sixfix-stability.json`。除明确接续的三份迁移保护脚本外,原有4份修改文档及4项未跟踪文件仍未提交;发布记录采用独立追加暂存,没有夹带另一会话的迁移文档。
## 2026-08-31 磁盘绑定挂载去重修复(仅本地提交,待授权发布)
- 用户要求修复并提交,下个版本发布须另等指令。本轮基于`main / 12668cee87400fdacf2d5609e2f18a75caa71cbf`,重新核验Git和最近进度;保留另一会话4份修改文档及4项未跟踪文件,不推送、不部署、不重载规则、不重启服务。
- 根因:前次“全部磁盘”按`instance/device/mountpoint/fstype`区分,把同一数据盘的`/data`及三个存储绑定路径当成四块盘。现改为`instance/device/fstype`独立文件系统标识,卡片、瞬时使用率、趋势和容量/inode规则一致去重;总容量取最大值、可用容量取最小值,不累加别名容量,不按容量相同误合并不同设备/主机/文件系统。
- API新增`mountpoints`保留所有路径,主路径按层级、长度及字典序稳定选择;前端一张卡片展示主路径,原生可展开区域展示其他挂载点,趋势计数改为文件系统。保留系统盘及EFI等独立分区、根盘兼容字段,采集缺失不补零。未变更业务数据、数据库结构、迁盘绑定和存储保护配置。
- 23:35(北京时间)对预生产Prometheus执行只读即时/范围查询:原始容量6条,聚合后3个文件系统(根、EFI、数据盘),每个趋势61点;数据盘容量`105087164416`字节,四个路径只产生一条使用率/可用容量及趋势。此证据验证新查询,不代表线上API或页面已升级。
- 候选基础规则63条、托管规则20条通过线上现有`promtool check rules /dev/stdin`只读语法校验;未写入线上规则文件。补充生成规则与基础容量/inode规则表达式一致性测试;发布时仍须按当前有效阈值生成托管规则、移除实际加载的同名基础规则并核验health。聚合会改变告警标签、指纹及for计时,不能承诺保留原告警已读状态或连续计时。
- 本地全量API 51套584项、前端9文件48项通过;前后端TypeScript检查、Vite构建、依赖安全、部署契约、包体积门禁及`git diff --check`通过。Vite仍提示既有Chart分块超过500kB,但入口gzip约107.39KiB,符合250KiB预算。新增回归覆盖绑定路径、乱序、主路径缺失、不同主机/设备/类型、缺失样本及展开交互;更新`TC-PORTAL-008/009`,新增`TC-DISK-DEDUP-001..004`。
- 本轮仅本地单元/组件回归及真实采集查询核验,没有部署新API/页面;登录浏览器视觉、控制台、真实页面展开及告警加载验收留待下一次明确授权发布,不以测试替身或构建通过冒充真实页面验收。既存日报5秒事务超时不在本轮修复范围。
- 提交仅包含本轮监控源码、规则、测试用例和本节进度追加;其他会话的迁盘文档及进度追加不纳入。本轮没有发送、补发、重投短信,也没有修改余额、通道或客户配置;待下一版本指令后再决定推送和目标环境发布。
## 2026-09-02 运营端企业签名管理高密度改版(仅本地提交)
- 按用户确认的第1稿落实现有企业签名管理,不新增顶部统计接口或Tab数量;保留既有4项查询及查询/重置语义。签名列表改为紧凑表头/行布局,签名统一以中文黑括号展示且不重复包裹,不展示用途;引流信息仅显示条数,不计算或显示异常数。
- 签名及引流两级表头统一为“审核状态”。移动、联通、电信列从文字状态/日期组合收敛为真实`approved/total`通道数字,零适用通道显示“—”,完整含义保留在title及无障碍标签中;数据继续来自现有真实报备目标汇总,不使用静态业务数据替代产品实现。
- 签名列新增升/降序双按钮,前端传递`signatureSort=asc|desc`,后端按`name`再按`id`稳定排序后分页;无排序参数的既有调用继续按创建时间倒序。切换排序回第一页,已在第一页时仅发送一次请求。签名与引流操作列均只保留“报备状态、编辑、删除”,移除两个报备详情入口及对应未使用展示组件。
- 更新R4页面契约:移除已废弃的两个详情组件/状态,纳入排序状态和新表格JSX;同时将前次签名/引流字段变更后已过期但未同步的两个表单函数哈希对齐当前源码。门禁通过,仍确认8个真实API调用和24项页面状态。
- 定向回归:企业签名组件2项、SMS配置服务68项通过;全量API 51套584项、前端10文件50项通过,前后端TypeScript、定向ESLint、Vite构建、依赖安全、部署契约、R4契约及包体积门禁通过。Vite仍仅有既有Chart分块超过500kB提示,入口gzip 107.41KiB符合250KiB预算。
- Browser插件本轮不可用,常规Chrome/Edge自动化进程因本机策略启动即退出;改用工作区自带Playwright Chromium复核本地构建。1600×1000页面身份、非空、无框架错误层、控制台、截图和交互通过:展开首条后可见3条引流信息;两级各3个指定操作、0个报备详情;点击降序实际请求`/api/admin/enterprise-signatures?signatureSort=desc&page=1&pageSize=10`。视觉夹具仅用于渲染验证,不冒充真实API验收。
- 本轮不推送、不部署,不访问或修改测试/预生产业务数据;未发送、补发、重投短信,未修改余额、通道或客户配置。真实登录环境API、浏览器控制台及页面效果仍须在未来获授权发布后复核。
- 提交只暂存本轮源码、测试、R4契约、测试用例及本节进度追加;原有4份修改文档、3份未跟踪文档、未跟踪`=`文件和`docs/testing-progress.md`中另一会话26行追加继续保留,不覆盖、不夹带。
## 2026-09-02 企业签名三网状态恢复与放弃报备汇总
- 重新核验 `main / 9e34757`、最近提交及交接进度后定位回归:高密度列表将三网单元格收敛为纯 `approved/total` 数字,导致签名和引流信息的状态语义不可见;公共报备汇总函数此前也没有“全部目标均为 abandoned”的独立结果。
- 签名及展开的引流信息三网列现同时展示汇总状态和通过数/总通道数,覆盖全部通过、部分通过、报备中、资料待补充、报备失败、放弃报备和未报备;状态及数量继续来自真实列表API的汇总字段。只有同一运营商下全部当前目标通道均为 `abandoned` 才汇总为“放弃报备”,混合状态保持其可执行状态,不误判为全部放弃。
- 签名表头的升序/降序图标由箭头改为上下实心三角,保留按钮无障碍名称、当前排序态及服务端稳定分页排序语义。同步更新R4契约和 `TC-ENTERPRISE-SIGNATURE-DENSITY-002/004/007`。
- 定向公共汇总8项、企业签名组件2项通过;全量API 51套586项、前端10文件50项通过,前后端TypeScript、定向ESLint(仅保留既有Fast Refresh警告)、Vite构建、依赖安全、结构质量、R4契约、包体积及 `git diff --check` 通过。Vite仍仅有既有Chart分块超过500kB提示,入口gzip 107.39KiB符合250KiB预算。
- 测试环境 `100.93.204.60` 当前经Tailscale显示离线、最后在线约12小时前,ping及SSH均不可达;因此尚不能重新建立和验证本次独立恢复资产,也未部署、重启服务或变更测试数据。待主机恢复连通后,必须先完成PostgreSQL custom dump、运行目录、环境/systemd/Nginx/原标记/SHA清单及三项可恢复性校验,才能发布。
- 本轮未访问或修改预生产,未发送、补发或重投短信,未修改余额、通道或客户配置。原有4份修改文档、3份未跟踪文档、未跟踪`=`文件及本文件中其他会话追加保持不动。
## 2026-09-02 企业签名三网状态修复(测试环境发布完成)
- 测试机恢复在线后重新核验:发布前 `.deployed-commit=b0deef5e6ebe6adbfe85591c53dedf11866880a0`,本次目标 `cd824999f3b604155e09fbad1f5c6258cfe1d918` 是其后续提交;本轮仅发布测试环境 `100.93.204.60`,未访问预生产。
- 本轮独立恢复点为 `/opt/cmpp-platform-backups/enterprise-signature-status-20260902T035026Z`,约668MB,含PostgreSQL custom dump、原运行目录、环境/systemd/Nginx/Prometheus配置、Redis RDB、原部署标记、服务及Stream基线和SHA清单。`pg_restore --list`、运行与配置tar可读性、全量SHA校验首次和切换前复核均通过。
- 精确Git归档SHA-256为 `7ecb95c3c2534d76ef8eaf103c6094af44afb75ef2be25936f3f5e49e9b8db3c`。候选目录首次在未加载环境文件时于Prisma生成阶段停止,未切换服务;加载既有环境后完成前后端、Gateway和Security Agent构建,95项migration无待执行项。
- 11:56:18至11:56:25(北京时间)完成应用目录切换和服务重启,上一运行目录保留为 `/opt/cmpp-platform.previous-enterprise-signature-b0deef5`。最终 `.deployed-commit=cd824999f3b604155e09fbad1f5c6258cfe1d918`PostgreSQL、Redis、MinIO未重启,Nginx仅重载。
- 发布前Security Agent因 `/run/cmpp-security-agent` 缺失已累计反复启动失败;本次经版本内安全边界安装脚本建立受控运行目录后恢复active,发布后 `Result=success / ExecMainStatus=0`,未修改安全策略范围。
- API、Gateway Callback、Gateway健康通过,API/Callback连接池正常;12项相关服务均active。命令、结果、协议日志三条Redis Stream均 `pending=0 / lag=0`entries-read和last-delivered-id与发布前基线一致,未产生或消费新的短信事件。测试环境6条上游连接状态为failed、当前连接0/期望6,下游连接0条;本轮未手工重连或修改通道配置。
- 发布窗口及约11分钟稳定复核中,API、Worker、Outbox、Callback、Protocol Log Worker、Gateway、Security Agent均无error级journal,运行目录文件日志未检出ERROR/FATAL/panic/Unhandled/Exception。
- 工作站从测试环境实际下载主资源 `index-BNrNaR05.js`、`index-CMZPlsxo.css` 和企业签名页分块 `AdminEnterpriseSignaturesPage-D_Q97xUB.js`SHA-256分别为 `f93dd4a0732edd4cad1396dbc67b588b27ef1188912c67fc27f7c297498c160d`、`8c98d139dc3cc1846f1b114ed278f42118b0d65fa83c303d0f12086aa2ed9329`、`bfed281a0849e86edc2d1e7fb2d332b167643139df4effcf8a3d584849c2ca23`,与服务器产物一致。
- Browser插件不在本会话可用技能中,按前端调试流程使用工作区Playwright Chromium对本地最新构建做1600×1000视觉复核。页面身份、非空、无框架错误层、控制台和展开交互通过;可见签名及引流信息的状态+数量、“放弃报备”和上下三角排序。截图使用隔离视觉数据,仅用于设计展示,不冒充测试环境真实API/数据验收;测试环境真实鉴权页面截图未完成。
- 全程未发送、补发或重投短信,未修改余额、客户、通道或签名/引流业务配置。原有修改及未跟踪文件继续保留,未覆盖或夹带。
## 2026-09-02 报备工作台、补资料合并与单条签名资料导出
- 按已确认方案将原“报备任务”重组为“报备工作台”,拆分为报备资料池、报备批次、通道报备明细、状态记录四个菜单。资料池保持现有审核通过且`pendingReport=true`的进入规则,并展示真实路由展开后的通道明细状态汇总;批次页可打开批次内任务、批量修改状态并下载通道文件。
- 通道报备明细新增当前有效应用路由下的虚拟未报备签名明细,维度为企业应用×签名×通道×运营商;真实状态修改在后端事务内创建或更新任务并写状态记录。放弃报备只排除对应通道运营商组合,不阻断同一资料的其他组合。
- 导入命中已有签名时改为补资料合并:只覆盖本次提供的同名字段并保留未提供字段;用途列未映射或为空时不再写入空字符串。导入仍先进入审核批次,审核通过前不修改真实签名。
- 新增单条签名报备资料详情和XLSX导出接口,按通道报备字段顺序输出并支持真实MinIO图片嵌入;单条导出不创建批次、不修改任务状态、不触发短信链路,并写操作日志。短信通道报备详情改为后端分页、全量今日发送数降序、细化查询条件及按字段顺序查看资料。
- 企业签名保存结果新增资料变化标识;页面仅在真实报备资料变化后提示前往报备资料池。企业签名列表新增最新资料版本尚待生成的通道×运营商明细数及下钻入口。状态记录增加批次号、操作人、变更后状态和修改入口查询。
- 本轮未新增数据库迁移,未改变部署架构。定向报备材料12项、签名配置68项和企业签名组件2项通过;全量API 51套587项、前端10文件50项通过,前后端TypeScript、定向ESLint(仅既有Hook依赖警告)、Vite构建、依赖安全、部署契约、结构质量、包体积及`git diff --check`通过。Vite仍只有既有Chart分块超过500kB提示,入口gzip约107.51KiB,符合250KiB预算。
- 发布边界仅为测试环境`100.93.204.60`,不推送远端、不访问预生产、不发送/补发/重投短信、不修改余额、通道或客户配置。测试机健康接口和SSH端口已恢复可达;部署结果、恢复资产、运行标记、服务/Stream/日志及真实页面验收在完成测试机认证后补记。
## 2026-09-02 高频查询整改及企业签名按钮优化(仅本地代码)
- 重新核验`main / 9b8196e`、最近提交、工作区及本文件末段后实施;开始时源码干净,但4份既有修改文档、4项未跟踪文件继续保留。本轮没有reset、覆盖或暂存其他会话内容,依赖工具意外生成的pnpm锁文件已在确认位于工作区且为本轮产物后删除,`pnpm-workspace.yaml`恢复原内容。
- 企业签名批量导入弹窗将“保存为可复用映射方案”改为通用Button,增加加号/完成图标、阴影、选中描边及`aria-pressed`;选中态文案为“本次将保存/更新映射方案”。签名和引流操作区的报备状态、编辑、删除统一使用通用`sm`高度,`DeleteRiskAction`支持显式size/className。
- 按整改文档收敛高频请求:企业签名/模板、企业应用、充值、上行、Gateway异常、下游投递、企业黑名单、客户端签名/模板、签名/模板审核、利润/质量/对账、报备任务/记录/批次均改为列表与选项分离、draft/applied条件或单请求页码分支;输入及选择变化不再触发业务查询。
- 新增轻量企业选项接口`/api/admin/tenants/options`;企业签名分页剔除材料、原始任务、目标数组及编辑动态字段,编辑和两类报备状态按ID懒加载;短信记录分页不再预取提交/回执/下游投递数组,详情与分片审计按单条并行加载并防止迟到响应污染。
- 通道页移除逐行连接状态N+1,复用分页接口真实`connectionStates`;通道报备详情将基础配置与任务分页拆分,查询/重置/翻页只刷新1次任务分页。所有功能仍使用真实API和数据库契约,没有增加mock、静态数据或localStorage产品兜底。
- 自动化:前端11文件51项、API 51套590项通过;新增映射按钮选中态、通用按钮高度、轻量企业选项、短信摘要/详情拆分、签名摘要白名单契约回归。前端TypeScript、API TypeScript构建、Vite生产构建及`git diff --check`通过;Vite仅保留既有Chart分块超过500kB提示。
- 本轮没有部署授权,因此未建立恢复资产、未访问或部署测试/预生产,未执行真实浏览器Network的20次P50/P95、响应字节和PostgreSQL执行计划验收;这些明确留待后续授权发布,不能以单元测试或构建结果冒充线上性能完成。未发送、补发或重投短信,未修改余额、通道或客户配置。
## 2026-09-02 高频查询整改及企业签名按钮优化(测试环境发布完成)
- 用户随后明确授权发布测试环境。重新核验本地 `main / ad89e8fed793857daf18ea6cebb995edfe3b74d4`、工作区和测试进度;发布前测试机 `.deployed-commit=cd824999f3b604155e09fbad1f5c6258cfe1d918`,核心服务及 API/Gateway 健康。本轮未访问或修改预生产。
- 首份恢复目录因 `DATABASE_URL` 含 Prisma 专用 `schema` 查询参数,在 `pg_dump` 参数校验阶段停止并标记 `.incomplete`,未作为恢复资产。最终成功发布前重新独立建立恢复点 `/opt/cmpp-platform-backups/high-frequency-ui-final-20260902T084800Z`,约667MB,包含 PostgreSQL custom dump、当前运行目录、环境/systemd/Nginx/Prometheus配置、Redis RDB、原部署标记和服务/Stream基线;`pg_restore --list` 842项、运行tar 52591项、配置tar 92项可读,9项 SHA-256 首次及切换前复核均通过。
- 精确Git归档包 SHA-256 为 `c59bba2ec4231d77c3136f64cb8b3e7a58ba5abb00b799302cca9abe1953bfcc`。独立目录完成依赖安全、部署契约、Prisma生成、前后端生产构建;95项migration无待执行项。候选目录首次因缺少未跟踪的 `dist` 目标目录在复制既有Gateway二进制前停止,补建后完整构建通过,未修改Gateway源码。
- 前两次应用切换均因发布探针顺序问题触发自动回退:第一次未等待Gateway启动,第二次在Gateway重启期间启动API后3000端口未健康;两次均自动恢复旧目录、旧标记和全部服务。隔离3100端口探针确认目标API约3秒健康后,第三次保持未改动的Gateway/Security Agent在线,明确确认3000端口释放再切换成功。最终上一运行目录为 `/opt/cmpp-platform.previous-high-frequency-final-cd82499-20260902T0851Z`。
- 2026-09-02 16:50(北京时间)最终 `.deployed-commit=ad89e8fed793857daf18ea6cebb995edfe3b74d4`。API、Send Worker、Submit Outbox、Gateway Callback、Protocol Log Worker、Gateway、Security Agent、Nginx、PostgreSQL、Redis、MinIO、Prometheus均active7项应用服务 `NRestarts=0`API、Callback、Gateway健康,Redis PONG。
- 命令、结果和协议日志三条Redis Stream发布前后均 `pending=0 / lag=0`Submit Outbox发布前全部为published。最终发布窗口7项应用服务error级journal为0API/Worker/Outbox/Callback/Protocol Log/Gateway文件日志未检出新ERROR/FATAL/panic/Unhandled/Exception。测试机Gateway仍为既有上游期望6、已连接0、下游0状态,本轮未手工重连或修改通道。
- 实际线上主资源 `index-AXwrLCns.js`、`index-BbnYYqYM.css` 及企业签名分块 `AdminEnterpriseSignaturesPage-DfsTejUl.js` 的SHA-256分别为 `5327e20e224dcabd9bebf2c6e1296e164e40ba7380df089b49e7c21926378661`、`719da5355b1cbfb780438935f31935fa028f9468377a68b9192a9693951da3ab`、`fc3c26c4e6abc86d3c94e77b60e3866d26b82ad8462da5da406a6e1258344ec7`,工作站HTTP回读与服务器一致;外部API健康连续3次HTTP 200。
- Browser插件不可用,Chrome接管导航超时;显式绕过本机代理后,工作区Playwright Chrome确认测试环境运营登录页HTTP 200、页面非空、无框架错误层。测试机保存的管理员凭据已失效并返回“用户名或密码错误”,两端临时凭据随即删除;未重置密码、未创建账号,因此登录后的企业签名按钮和真实Network P50/P95尚未在本轮浏览器验收,不以自动化组件测试冒充线上交互通过。
- 全程未发送、补发或重投短信,未修改余额、客户、通道、签名或引流业务配置。原有未提交文档及未跟踪文件继续保留,不覆盖、不夹带。
## 2026-09-02 报备工作台批量操作与通道简报(测试环境发布准备)
- 企业签名管理移除签名排序入口和逐行“待生成明细”,恢复按创建时间倒序;搜索条件下方集中展示当前筛选范围内、最新资料版本尚待生成批次的“企业应用 × 签名 × 通道 × 运营商”明细总数,并可进入通道报备明细。
- 通道报备明细增加“全选当前页/取消全选”,翻页、查询或重新加载后清空选择,不跨页隐式选中。报备批次详情按通道展示可复制简报;日期取批次创建时间的北京时间,签名和引流资料使用各自格式,短信内容取通道字段库排序后的第一个“短信内容”字段,没有时留空。
- 简报短信内容在批次生成时写入既有批次明细JSON快照,历史批次不会随当前字段库或资料变化;没有新增数据库字段或migration。引流资料优先展示快照中的引流URL,无URL时回退站点名称。
- 定向API 2套83项、前端2文件4项通过;全量API 51套592项通过。全量前端首次11文件50项通过且另1个工作进程启动超时,超时文件单独重跑3项通过,合计12文件53项业务测试通过;前后端TypeScript、Vite生产构建、依赖安全、部署契约、结构质量、R4页面契约、包体积及`git diff --check`通过。Vite仅保留既有Chart分块超过500kB提示,入口gzip约107.61KiB,低于250KiB预算。
- Browser插件不可用,按前端调试技能回退到本机Playwright Chrome,对本地生产构建完成1600×1000和390×844核验:企业签名页无排序和逐行待生成字段、汇总条可见;当前页全选后批量数正确;批次内签名/引流简报及复制入口可见;页面无新增控制台错误。隔离页面数据只用于布局和交互核验,不冒充真实API/PostgreSQL验收。
- 发布范围仅限测试环境`100.93.204.60`,不推送远端、不访问预生产。发布前已只读确认测试机当前标记`ad89e8fed793857daf18ea6cebb995edfe3b74d4`、核心服务健康、三条Redis Stream均`pending=0 / lag=0`。后续只从既有可报备资料生成少量测试批次,不创建通道、客户或签名资料,不发送、补发、重投或重新入队短信;部署恢复资产、最终标记、测试批次及真实接口结果待完成后追加。
- 本轮代码及用户指定的全部既有未提交文档已提交为`7cb5dd376e23ff0c8a1e3785ab376e432f2ebf6a`,未跟踪异常文件`=`未纳入;未推送远端。精确Git归档SHA-256为`b338b244aef72127c08a9896f924b862c2499b562c8bba5997e9f98dece1decf`。
- 测试环境最终恢复点为`/opt/cmpp-platform-backups/report-briefs-20260902T103034Z`,约657MB,含PostgreSQL custom dump、运行目录、环境/systemd/Nginx/Prometheus配置、Redis RDB、原部署标记、服务及三条Stream基线。首次因沿用旧`.env`路径而停止,随后使用当前`/etc/cmpp-platform/cmpp-platform.env`在同一目录完整重建;移除`.incomplete`前再次通过`pg_restore --list`、两份tar可读性和全部SHA校验,误建的空目录已删除。
- 候选版本通过安全、部署契约、Prisma生成和前后端生产构建,95项migration无待执行项。旧运行目录的Gateway/Security Agent磁盘二进制已被上次前端构建清除但进程仍在,本次从同一源码为候选目录重新编译;前两次隔离探针因错误覆盖`PORT`而仍尝试3000端口,均未切换服务,改用`API_PORT=3100`和独立指标端口后探针HTTP 200。
- 正式切换成功,上一运行目录保留为`/opt/cmpp-platform.previous-report-briefs-ad89e8f-20260902T1040Z`,最终`.deployed-commit=7cb5dd376e23ff0c8a1e3785ab376e432f2ebf6a`。12项相关服务全部active7项应用服务`NRestarts=0 / Result=success`API健康,发布窗口error级journal和运行日志关键错误均为空。命令、结果、协议日志三条Redis Stream均`pending=0 / lag=0`,未产生短信发送、补发、重投或重新入队操作。
- 工作站从测试环境`12026`端口实际下载`index-Bf_CFnM7.js`和`index-CHC8RH63.css`SHA-256分别为`453b65d6abed7336868f93e25cad11826ea906b321b1a64eb41740ea56f3b2ca`、`747fc3fb521ec8aed64d8a589ba0f3a80b691f3a26973bb98cdc4ebde2abe142`,与服务器产物一致。本机Playwright Chrome确认运营登录页HTTP 200、标题正确、主体非空、无框架错误层和控制台错误;因测试机保存的管理员凭据失效,未把登录后页面标记为真实浏览器验收通过。
- 测试数据生成未执行:真实业务服务查到24条待生成资料,但测试库`ChannelReportField`为0条,逐条正式预检均被“通道未配置当前资料类型的报备字段”阻断,历史批次也为0。继续生成真实批次必须先修改通道报备字段配置,超出本轮“不得修改通道配置”的边界;没有裸插数据库、伪造批次或使用mock绕过。一次旧凭据验证使原管理员失败次数由4升到5并触发锁定,已依据登录代码的单次递增事实精确恢复为4且清除本次产生的锁定,同时回退本次Redis匿名失败计数;未重置密码或创建账号。
## 2026-09-03 报备字段组合与通道简报真实数据验收
- 用户明确授权在测试环境配置十余个多类型字段并一起验证。本轮仅修改测试环境`100.93.204.60`中的报备字段库、6个`LGST-*`测试通道映射和报备批次数据;未访问预生产,未修改客户、余额、短信通道连接参数或签名业务资料,未发送、补发、重投或重新入队短信。
- 真实服务创建20个`qa`前缀测试字段,覆盖系统当前支持的`string / image / file`三种类型;包含两个同名“短信内容”字段及签名、企业、应用、行业、场景、联系人、网站、图片、附件等字段。6个测试通道各配置16个签名字段和15个引流字段,共186条映射,覆盖必填/可选、默认值、`trim / digits / uppercase / lowercase`转换、不同列宽和图片尺寸。
- 配置后两条`LG压测`签名的正式预检均为`eligibleTargetCount=6 / skipped=0`。通过部署版本的`ReportMaterialsService`和真实PostgreSQL、MinIO生成两个批次:`RB20260903014950CF8E`、`RB20260903015137EF86`;每批次选中1条资料,按6个通道产生6个报备任务、6份XLSX及6份通道简报,批次状态均为`completed`。
- 逐份通过`FilesService`从MinIO读回并用ExcelJS解析12份真实XLSX:工作表均为“签名报备”,16列、2行,文本默认值及`trim / digits / uppercase`转换结果与映射一致;现有两条资料没有图片或附件,因此对应单元格和工作簿图片数为0,未伪造附件。测试库当前没有待生成引流资料,故未伪造引流批次;已完成引流字段映射,为后续真实引流资料验证保留入口。
- 发现首版简报会把通道字段默认值误当成资料中的“短信内容”。修复后仅取批次生成时资料快照内、按映射顺序第一个同名“短信内容”字段的真实值;字段未提供时保持空,不读取默认值,也不回退第二个同名字段。定向报备材料13项、API全量51套592项和API TypeScript构建均通过,修复提交为`068b8047ddbfbacf32b233b7b8cfb4e52fd04a6f`。
- 发布前恢复点为`/opt/cmpp-platform-backups/report-brief-testdata-20260903T013807Z`,约668MBPostgreSQL custom dump、Redis RDB、运行与配置tar、标记及服务基线均通过SHA、`pg_restore --list`和tar可读性校验;精确Git归档SHA-256为`d17dcc5befbb9c0e7fb5439652fd375130ab3968a6ef95adb72d139bc1b251c3`。最终测试环境`.deployed-commit=068b8047ddbfbacf32b233b7b8cfb4e52fd04a6f`95项migration无待执行项。
- 两个批次的简报均按批次创建时间显示“2026年9月3日”,包含签名`【LG压测】`和各自批次号;由于资料快照没有“短信内容”值,短信内容正确为空,证明默认值没有冒充资料。配置、批次、XLSX及简报核验JSON均保存在上述恢复点。
- 生成前后三条Redis Stream的完整基线文本逐字一致,未产生短信链路事件。发布后12项相关服务均active,API健康,发布窗口无error级journal。Chrome中现有测试标签停留在登录页且没有有效登录态,因此本轮没有把登录后页面视觉/复制交互标记为真实浏览器通过;该项由真实服务、数据库和MinIO数据验证覆盖,但仍与浏览器交互验收明确区分。
## 2026-09-03 报备工作台全选控件统一(本地修改)
- 通道报备明细右上角操作区改用现有统一`page-heading__actions`样式,修复“全选当页”和“批量修改状态”之间无间隔的问题;仅调整样式类名,不改变选择、翻页清空或批量状态接口。
- 报备资料池移除表格上方“选择本页全部可生成资料”复选框标签,替换为右上角统一幽灵按钮“全选当页/取消全选”,与“预检并生成”保持统一间距;仍只选择当前页资格预检通过的数据,后端预检及生成接口、参数和业务逻辑不变。
- 定向报备工作台组件3项、前端全量12文件54项、TypeScript及Vite生产构建通过;Vite仅保留既有Chart分块超过500kB提示。Browser插件不在本会话技能列表,按前端调试流程使用工作区Playwright Chrome运行本地生产预览;1600×1000下两个页面身份、非空、错误层、控制台及点击全选交互通过,两个按钮组间距实测均为8px,截图保存在工作区外,不纳入提交。页面数据仅用于本地布局和交互验证,不作为真实API验收结论。
## 2026-09-03 报备批次明细与文件导出重构(测试环境发布准备)
- 报备批次列表移除逐个文件入口,原进度比改为报备总明细、报备中、成功、失败四项真实任务计数;状态归类为`reporting/exporting`、`approved`、`failed/rejected`,历史状态不伪造归类。
- 批次明细改为右侧滑窗,展示四项汇总及通道明细;表头可全选当前加载的批次明细,支持单条或多选后批量修改状态。所有状态选择和原因输入仅在确认弹窗中出现,不再提供“导出本条”。状态写入继续复用现有真实批量接口、权限和事务记录。
- 新增“报备文件导出”弹窗,每个通道集中展示不可变批次简报和对应XLSX下载;“全部下载”由服务端从真实MinIO读取每个通道文件,生成包含每通道一份XLSX及一份TXT简报的ZIP。文件统一命名为`日期_通道名_批次号`,缺少任一真实通道文件时明确失败,不静默生成不完整压缩包;限制100个通道和200MB工作簿总量。
- 未新增数据库字段或migration,未改变部署架构和短信链路。API新增两个只读下载接口,仍通过批次查询校验对象存在并使用既有后台权限;下载不修改任务、余额、通道或客户配置。
- 验证:API全量52套595项、前端全量12文件55项、前后端TypeScript、Vite生产构建、依赖安全、部署契约、结构质量、包体积和`git diff --check`通过;新增ZIP内容/命名/缺文件失败及明细抽屉/状态弹窗/导出弹窗回归。定向ESLint为0错误,仅保留该页面既有Hook依赖警告。Vite仅有既有Chart分块超过500kB提示,入口gzip约107.63KiB。
- 使用本机Playwright Chrome对本地生产构建完成1600×1000与390×844视觉和交互核验:列表无直接文件名,四项计数可见;右侧滑窗紧贴右边且全高,表头全选3条、单条及批量状态弹窗正常;导出弹窗显示通道简报、单通道下载和全部下载,窄屏无横向溢出;浏览器控制台无错误。隔离页面数据仅用于布局验证,不冒充真实API、PostgreSQL或MinIO验收。
- 发布授权仅限测试环境`100.93.204.60`,不推送远端、不访问预生产。部署、真实下载和“同一通道多个签名且包含短信内容”测试批次结果在完成恢复资产、发布及数据库/MinIO核验后追加;全程禁止发送、补发、重投或重新入队短信。
## 2026-09-03 报备批次明细与文件导出重构(测试环境发布完成)
- 代码提交`dc201bf92ef039dd5beb3c16950e622c600f0026`已部署至测试环境,未推送远端、未访问预生产。测试机原标记为`068b8047ddbfbacf32b233b7b8cfb4e52fd04a6f`,最终`.deployed-commit`与本轮代码提交完全一致;95项migration均已完成且无待执行项,本轮没有数据库迁移。
- 发布前恢复点为`/opt/cmpp-platform-backups/report-batch-redesign-20260903T030900Z`,约664MB,包含PostgreSQL custom dump、Redis RDB、运行目录、环境/systemd/Nginx/Prometheus配置、原标记及服务/Stream基线。`pg_restore --list`为842项,两份tar可读,首次和切换前SHA-256均通过;精确Git归档SHA-256为`ebc8a49c81bc97cf8731ccf820d8d9031fe76d8bd96bae589604fae9992fd06a`。
- 隔离候选首次因未先载入受保护环境变量而在Prisma生成前停止,第二次因`npm --prefix api exec`工作目录不符合Prisma schema解析要求停止;两次均未切换服务。改为载入现有环境文件并在`api`目录执行后,Prisma状态、依赖安全、部署契约和前后端构建通过;3100端口隔离API健康后才正式切换。上一运行目录保留为`/opt/cmpp-platform.previous-reportbatch-068b804-20260903T031400Z`。
- 发布后API、Send Worker、Submit Outbox、Gateway Callback、Protocol Log Worker、Gateway、Security Agent、Nginx、PostgreSQL、Redis、MinIO、Prometheus共12项服务均active且`NRestarts=0`;内外API健康HTTP 200。发布窗口及测试数据生成后相关服务无error级journal,当前运行日志未检出新增`ERROR/FATAL/panic/Unhandled/Exception`。
- 真实测试数据批次为`RB20260903031835C997`:在同一应用下创建3条专用已审核签名,每条均填写字段库中排序第一的“短信内容”,按6个既有`LGST-*`测试通道生成6份XLSX、6份通道简报和18条通道报备明细。四项计数为总明细18、报备中18、成功0、失败0,符合新批次任务初始`exporting`状态归入报备中的规则。
- 通过已部署服务、真实PostgreSQL和MinIO逐份读回验证:每个通道XLSX均4行(表头1行、签名3行),每份简报均包含3条签名及各自短信内容;批量ZIP名称为`2026-09-03_RB20260903031835C997_报备文件.zip`,内部严格为每通道一份`日期_通道名_批次号.xlsx`和同名`.txt`,共12项。验证JSON及发布后Stream快照已写入恢复点并附独立SHA-256。
- 测试数据生成前后三条Redis Stream的组信息、最后投递ID、entries-read、pending和lag快照逐字一致,均为`pending=0 / lag=0`,没有发送、补发、重投或重新入队短信;没有修改余额或短信通道连接参数。登录后测试环境真实浏览器验收因没有有效平台管理员登录态未执行,未以本地隔离页面视觉验证冒充线上登录交互。
## 2026-09-03 待生成明细数量状态联动与企业签名按钮间距(本地修改)
- 重新核对两处状态入口:通道报备明细使用`sourceEntry=report_task`,企业签名报备状态弹窗使用`sourceEntry=enterprise_signature`,均调用统一真实批量状态接口并持久化`ChannelSignatureReportTask/ChannelSignatureReportRecord`;企业签名弹窗保存成功后会重新请求分页接口刷新汇总数。
- 待生成明细总数继续严格遵循已确认口径:仅统计审核通过、仍在资料池、当前材料版本尚未成功生成批次且未放弃的“企业应用×签名×通道×运营商”组合。尚未生成批次时,改为`abandoned`会减少、恢复为其他状态会增加;已成功生成当前版本的组合不会因人工状态变化重新进入,避免同版本重复生成。本轮未扩大或改写批次资格规则。
- 企业签名管理右上角按钮容器修正为统一`page-heading__actions`,使“批量导入签名及引流资料”和“添加签名”获得标准间距并保留窄屏换行。
- 增加两个状态入口共用事务逻辑、各状态下待生成数量和页面按钮间距的回归用例。定向API 2套122项、API全量52套601项、前端全量12文件55项、前后端TypeScript及Vite生产构建均通过;Vite仅保留既有Chart分块超过500kB提示。
- Browser插件不在本会话技能列表,按前端调试流程使用本机Playwright Chrome检查本地生产构建:1600×1000与390×844下均显示两个目标按钮,计算样式间距为8px、无重叠和页面横向溢出,控制台及页面错误均为0。接口响应使用隔离布局数据,仅验证样式和响应式交互,不冒充真实API/PostgreSQL验收。
- 本轮不提交、不推送、不部署,不访问预生产,不修改测试环境业务数据,不触发短信发送、补发、重投或重新入队。
## 2026-09-03 运营修改自动通过、资料池状态颜色与待生成资料数(测试环境发布准备)
- 运营端新增签名沿用既有自动通过规则;运营端修改签名或资料后也直接保持/变为审核通过,并写入`admin_update_approved`审核记录及操作人。客户端修改和导入审核流程不变,仍按原规则进入待审核;没有新增数据库字段或migration。
- 报备资料池按真实预检结果展示明确状态颜色:待生成、部分可生成为黄色,资料不完整及阻断原因为红色,已生成为绿色,全部放弃、无有效通道和资格检查中为灰色。状态只作用于现有资料池查询范围,不扩大为全部签名或历史资料查询。
- 企业签名管理搜索区下方汇总改为“待生成报备资料”份数,按一条企业应用下的签名资料计数;只有至少一个当前通道×运营商组合可生成时才计入。同一接口继续返回原“待生成明细数”兼容字段。入口文案改为“查看详情”,点击跳转报备资料池。
- 定向API 1套76项、定向报备工作台组件1文件5项通过;全量API 52套602项、前端12文件56项通过。前后端TypeScript、Vite生产构建、依赖安全、部署契约、结构质量、R4页面契约、包体积及`git diff --check`通过;Vite仅保留既有Chart分块超过500kB提示,入口gzip约107.63KiB。
- Chrome本地生产预览在1600×1000及390×844下验证汇总文案、7份示例计数、“查看详情”跳转和六类状态颜色,无控制台或页面错误;首行滚动到可视区后待生成黄色状态可见。隔离页面数据只用于布局、响应式和交互覆盖,不冒充真实API/PostgreSQL验收。
- 本轮发布范围仅为测试环境`100.93.204.60`,不访问预生产,不修改余额、客户、通道或签名业务资料,不发送、补发、重投或重新入队短信。发布恢复资产、最终部署标记、真实服务和只读数据核验结果待发布完成后追加。
- 功能提交`4ff6ed078669b13efbdb140ea36aaff4631f7cb5`及此前本地提交已推送到`origin/main`,远端ref独立回读一致。测试机原标记为`dc201bf92ef039dd5beb3c16950e622c600f0026`;精确Git归档为2732881字节,SHA-256为`3b5529d66f768356122b5828d8ed2432575daa3b3bf81b38c9f198bf83c6ff4f`,本地与测试机一致。
- 首个恢复目录因测试机不存在预生产专用`/usr/local/sbin/cmpp-data-storage-check`,在数据库dump、代码覆盖、构建和服务重启前安全停止,保留为`/opt/cmpp-platform-backups/report-material-state-20260903T045831Z.incomplete`。按测试机真实挂载重新建立有效恢复点`/opt/cmpp-platform-backups/report-material-state-20260903T050247Z`,约699MB,包含PostgreSQL custom dump、Redis RDB、原运行目录、系统配置、发布包、原标记及服务/挂载/Stream基线;全部SHA、842项`pg_restore --list`、52606项运行tar和351项配置tar首次及切换前复核均通过。
- 候选目录按锁文件重新安装依赖,通过依赖防护、部署契约、Prisma生成和前后端/Gateway/Security Agent生产构建;95项migration全部齐全且无待执行项,本轮未运行数据库迁移。正式切换成功,上一运行目录保留为`/opt/cmpp-platform.previous-report-material-state-dc201bf9-20260903T050717Z`,最终测试环境`.deployed-commit=4ff6ed078669b13efbdb140ea36aaff4631f7cb5`。
- 发布后API、Send Worker、Submit Outbox、Gateway Callback、Protocol Log Worker、Gateway、Security Agent、Nginx、PostgreSQL、Redis、MinIO和Prometheus均active;七项应用服务`NRestarts=0 / Result=success`API、Callback、Gateway健康且Redis PONG。发布窗口至稳定复核均无error级journal。
- 三条Redis Stream的发布前后组状态逐字一致;没有产生短信发送、补发、重投或重新入队事件。PostgreSQL只读基线为已通过且非待生成25条、已通过且`pendingReport=true`1条、已删除3条;未为自动审核或颜色验收修改任何签名、通道或客户配置。
- 外部`12026`端口API健康HTTP 200;实际下载主资源`index-DESpdjJ1.js`和`index-D4ttoiTl.css`SHA-256分别为`6f612c92da38cecc2469bf1daf871918a541dee38e76fdb309edae94195d8ce4`、`f922d415d536224085b4eaebd3ee288833aa564ff7a8bfdc48ff0be0c584b70d`,与服务器产物一致。Playwright Chrome确认测试环境运营登录页HTTP 200、标题及登录按钮正确、控制台无错误;因没有有效平台管理员登录态,登录后的真实页面交互仍未冒充已验收。
## 2026-09-03 状态记录列表精简(测试环境发布完成)
- 状态记录列表由11列精简为7列:保留报备任务号、通道名称、状态变化和操作,将报备类型与报备对象合并为“变更对象”,动作与修改入口合并为“变更动作”,操作人与时间合并展示;备注从列表移至既有详情弹窗,搜索条件继续支持按备注查询,未丢失历史数据入口。
- 表格采用固定列宽和省略展示,总列宽约1101px;大屏PC内容区可完整展示,窄于该宽度时仍保留容器滚动作为兼容兜底。详情弹窗继续展示任务、通道、类型、对象、动作、修改入口、状态前后、备注原因及状态历史。
- 定向组件6项、前端全量12文件57项、TypeScript、Vite生产构建、入口包体积预算和`git diff --check`均通过;定向ESLint为0错误,仅保留页面既有Hook依赖警告。新增功能用例`TC-REPORT-WORKBENCH-020`。
- 本地生产预览连接真实本地API、PostgreSQL和Redis,运营端登录后读取11条真实状态记录;列表及详情交互正常,收起导航后1280px浏览器视口无需横向滚动且7列完整可见。未使用mock、静态数据或localStorage作为功能验收结论。
- 功能提交为`fe3c6e5b589cf475c611f5189e9243e657b5deac`,未推送远端。测试环境采用前端静态资源增量发布,没有执行数据库迁移,也没有重启API、Gateway、Worker、PostgreSQL、Redis或MinIO;恢复点为`/opt/cmpp-platform-backups/report-record-list-20260903T1654Z`。
- 发布包大小2734330字节,SHA-256为`d2381d1b31cc49418f370b66131dd74e180ba4448c75f7d5795fcc787b48b2c8`;测试环境最终`.deployed-commit=fe3c6e5b589cf475c611f5189e9243e657b5deac`。内外API健康HTTP 20012项相关服务均active,三条Redis Stream仍为`pending=0 / lag=0`,发布窗口无error级journal;全程未发送、补发、重投或重新入队短信。
## 2026-09-03 报备工作台累计版本与状态记录精简(预生产发布完成)
- 用户明确授权部署预生产。发布前重新确认本地`HEAD=dada0d978bb05d7046469c1ec77371ddb2fb03bc`,预生产原标记为`9a15d28da56af62225856b361ce2946466cc7210`;累计差异为17个提交、98个文件,包含整套报备工作台、签名资料逻辑、查询与监控适配,并非仅状态记录页面。没有新增migration,原有未跟踪方案文档未进入Git归档;本轮未推送远端。
- 预生产发布前数据盘UUID`ef4ee3bb-a19b-4aeb-b00c-aa2b995611c2`、PostgreSQL/Redis/MinIO三处绑定挂载、存储保护脚本、systemd drop-in和固定备份入口均通过。95项migration已齐全,API、Gateway、Redis和12项服务正常,三条Redis Stream均`pending=0 / lag=0`,供应商连接为`desired=9 / connected=9`。
- 完整恢复点为`/opt/cmpp-platform-backups/preprod-report-workbench-20260903T123848Z-before-dada0d9`,约605MB,包含PostgreSQL custom dump、Redis RDB、运行目录、环境/systemd/Nginx/Fail2ban/nftables配置、数据盘保护文件、原部署标记、服务/Stream/连接基线、候选构建和发布日志。840项`pg_restore --list`、52647项运行tar、253项配置tar以及最终SHA-256清单均通过;旧运行目录保留为`/opt/cmpp-platform.previous-preprod-9a15d28-retry-20260903T1252Z`。
- 精确Git归档为2735075字节,SHA-256为`84cbbc5620ccd0ea57b762269e3a0c91be96cbd70677b143bef91f4cd3b8aaa9`。候选目录通过依赖安全、部署契约、Prisma生成/状态、前端、API、Gateway和Security Agent生产构建;部署时仍为95项migration且无待执行项。
- 首次切换因包装脚本的`umask 077`被构建继承,候选目录无法由`cmpp-api`用户穿透,API在60秒内未健康并触发自动回滚。旧版本已恢复,但回滚构建同样继承限制权限,导致`api/dist`暂时仅root可读;按证据恢复运行文件的读取/执行权限后,旧版API、Gateway、四个Worker及Stream全部恢复。根因明确后改用标准`umask 022`,并在切换前以`cmpp-api`身份检查入口和Prisma依赖可读性,第二次发布成功。
- 预生产最终`.deployed-commit=dada0d978bb05d7046469c1ec77371ddb2fb03bc`。PostgreSQL、Redis、MinIO、API、四个Worker、Gateway、Security Agent、Nginx和Node Exporter共12项服务均`active`,七项应用服务`NRestarts=0 / Result=success`;内外`12026`、`sms.lisglo.com`、API、Gateway和Callback健康均通过,发布后error级journal为空。
- 服务重启后3条富泷供应商通道一度认证失败,供应商连接从9/9暂为6/9;旧版本回滚阶段同样出现,未修改通道配置或凭据。系统按既有计划自动重试,于20:56:52恢复`desired=9 / connected=9`并持续稳定;Gateway当前4条下游连接均在线且持续收发心跳。三条Redis Stream最终仍为`pending=0 / lag=0`,其entries-read仅随正常连接恢复、回执和协议日志前进;本轮未发送、补发、重投或重新入队短信。
- 工作站从预生产实际回读主资源`index-DHpz4GTj.js`、`index-rk3aXfEF.css`和状态记录分块`AdminReportRecordsPage-Bo0P2l0_.js`,均HTTP 200,长度分别为370340、236129和8658字节;登录后的状态记录真实交互沿用本地真实API/PostgreSQL/Redis验收结果,未在没有预生产运营登录态时冒充线上登录验收。
## 2026-09-04 运营看板、签名与报备配置增强(本地修改)
- 运营看板新增今日消息分片数和按分片计算的今日到达率,并按当天实时短信、分片审计、客户价及通道成本快照展示今日返还、计收、利润和利润率;聚合直接查询真实业务表,不依赖尚未生成的T+1日报,不改变原业务短信成功率口径。
- 企业签名列表的签名悬停信息补齐完整签名、企业、应用、用途、审核状态及创建/更新时间;导航分组和菜单项纵向间距收紧,保留滚动、折叠、角标和响应式逻辑。
- 签名质量详情的通道×运营商矩阵仅调整前端展示:表头和通道列吸附、单元指标分层、成功率颜色提示更清晰;整体/引流切分、所有原字段和现有后端接口均保留。
- 报备字段定义新增真实编辑接口和操作日志。未引用字段可调整代码、名称、类型和说明;已被通道或通用配置引用时只允许改名称和说明,前后端同时保护映射关键字段。通用字段可在签名/引流各自范围内原子调整顺序,集合变化时拒绝部分更新;未新增数据库字段或migration。
- 通道报备明细单条导出的500根因定位为Blob POST传JSON字符串时未设置`Content-Type: application/json`Nest未解析请求体。前端请求头已修复,后端为空请求增加可读400保护;导出仍读取真实字段、资料和文件,不改变报备状态,不发送、补发、重投或重新入队短信。
- 测试环境`100.93.204.60`当前ICMP和22端口可达,但约642ms且现有密钥认证失败;本轮没有部署授权,也没有把登录后的测试环境页面冒充已验收。
- 定向API 3套64项、定向前端3文件23项、全量API 52套605项、前端12文件61项通过;前后端TypeScript、Vite生产构建、依赖安全、部署契约、结构质量、包体积和`git diff --check`通过。Vite仅保留既有Chart分块超过500kB提示,入口gzip 107.68KiB,符合250KiB预算。
- Browser插件本轮不可用,按前端调试流程使用工作区Playwright Chromium验证本地生产构建。1600×1000运营看板和质量矩阵、390×844运营看板页面身份、非空、错误层、控制台及横向溢出检查通过;菜单项上下内边距实测7px,矩阵完整保留通道提交、成功率、平均到达和提交失败信息。截图数据只用于布局验证,不冒充真实业务数据。
- 本地真实PostgreSQL启动后,新看板聚合代码直接执行成功,返回当日零短信下分片数、到达率、计收、利润和利润率均为0,确认SQL语法、表关联和零分母处理可运行;本地API健康HTTP 200。Redis未启动时API持续输出连接拒绝,故未将该不完整本地栈作为页面功能验收,验证后已关闭本地API、预览和PostgreSQL。
- 本轮只做本地提交,不推送、不部署,不访问或修改测试/预生产业务数据;不发送、补发、重投或重新入队短信,不修改余额、通道或客户配置。本节与源码、测试用例一并纳入本轮本地提交。
## 2026-09-04 WPS报备资料兼容与工作台修复(本地验证完成,待测试环境发布)
- 以本地`main`的`48d0363`为基线实施,本地相对`origin/main`领先2个提交且未落后;没有pull、切分支或回退。既有未跟踪`docs/report-material-pool-remediation-plan-20260903.md`保持原样,本轮方案文档单独纳入精确提交范围。
- WPS导入新增原始OOXML解析:精确识别`_xlfn.DISPIMG("ID_...",1)`,经`xl/cellimages.xml`及关系文件定位媒体,再与ExcelJS标准Drawing图片按单元格合并;普通公式、宏/外部对象、不完整关系和非白名单图片继续拒绝,没有整体放宽公式安全校验。
- 真实样本`C:\Users\hectorzhao\Downloads\行业报备.xlsx`为20,976,525字节,解析得到工作表“行业”、17行、13列、43张业务图片,图片总字节20,672,756A1的84字节透明Drawing占位图被排除。该只读样本未写回或覆盖。
- 报备导入前端和API均将企业应用改为必选,并由后端校验应用属于所选企业;XLSX压缩文件上限调整为100MiB,增加500MiB解压总量限制。Nginx私有站点模板同步调整为110m以容纳multipart开销;这会提高单请求资源峰值,因此仍保留文件数、部件数、压缩/解压体积和格式安全限制。
- 批次报备文件弹窗与两个单条导出入口均可选择“系统Excel Drawing”或“WPS单元格图片”;默认保持现有Excel格式,WPS格式由同一真实资料快照生成并可被新解析器回读,不改变数据库资料、报备状态或短信链路。
- 报备字段库“添加字段”移入字段定义区域;通道字段配置弹窗加载真实通用字段作为右侧默认项,固定左侧卡片最小高度,移除按钮改为非危险填充的通用宽度。通道详情同时展示名称和编号;资料弹窗展示图片、字段名称/代码/导出名,并为未删除历史字段回填字段库名称。
- 运营看板指标按业务阅读顺序调整为发送总量、分片数、总体成功率、到达率、活跃签名、消费、返还、计收、利润和利润率;只调整排列,不改变上一提交新增的真实聚合口径。
- 定向前端4文件12项、前端全量13文件63项、定向API3套20项、API全量53套608项通过;前后端TypeScript、Vite生产构建、依赖安全、部署契约、结构质量、增量ESLint/Prettier、入口包体积和`git diff --check`通过。ESLint仅保留3条既有Hook依赖warningVite仅保留既有Chart分块超过500kB提示,入口gzip 107.80KiB,低于250KiB预算。
- 功能提交为`fb39c8b606a644e1a2907a372aba4a82d1968f47`,已连同本地原先领先的两个提交推送至`origin/main`;推送后重新fetch确认本地与远端均指向该提交、ahead/behind为`0/0`。既有未跟踪`docs/report-material-pool-remediation-plan-20260903.md`仍保持原样,未纳入提交。
- Browser插件及工作区Playwright依赖在当前会话不可用,尚未把组件测试或本地构建冒充真实页面验收。测试环境`100.93.204.60:12026`的旧版本API健康返回`status=ok`、运营登录页HTTP 200,但新提交尚未部署:普通SSH非交互认证返回`Permission denied (publickey,password)`Tailscale节点在线,但MagicDNS主机键无法独立比对,未绕过主机键校验;现有唯一私钥明确属于预生产,未用于测试机。部署标记、内部服务、Redis Stream、Nginx最终`client_max_body_size`和登录后真实页面仍待获得测试机安全认证后核验,不把外部健康探测冒充新版本验收。
## 2026-09-04 WPS报备资料兼容与工作台修复(测试环境发布完成)
- 用户补充测试机认证后,仅连接并发布测试环境`100.93.204.60`;发布前实际读取`.deployed-commit=fe3c6e5b589cf475c611f5189e9243e657b5deac`12项服务均activeAPI和Gateway健康,95项migration一致。Nginx实际生效值仍为`client_max_body_size 50m`,三条Redis Stream均`pending=0 / lag=0`。
- 发布前建立独立恢复点`/opt/cmpp-platform-backups/wps-report-20260904T092253Z`,约664MiB,包含PostgreSQL custom dump、原运行目录、环境/systemd/Nginx配置、Redis RDB、原部署标记、服务和Stream基线;`pg_restore --list`、两份tar可读性及四项SHA-256校验通过。候选构建和正式发布日志随后归档到同一恢复点并单独通过SHA-256校验。
- 精确Git归档SHA-256为`a383e0874968598050b00f9b5b4ab5ae775f3fa5beded59837043d9d3d37c069`,服务器回读一致。候选目录先通过依赖安装、依赖安全、部署契约、Prisma生成、迁移状态及前端/API/Gateway/Security Agent生产构建;首次迁移状态命令因工作目录写错停止,确认没有执行migration或切换服务后从正确`api/`目录继续通过。正式发布期间两次SSH因测试机高I/O和Tailscale中继链路重置,后台唯一发布进程持续运行,没有重复启动发布。
- 最终`.deployed-commit=bb435fb0ac1e7812fcdb59950a4b13757899ab39`,上一运行目录保留为`/opt/cmpp-platform.previous-wps-fe3c6e5-20260904T095352Z`95项migration全部一致且没有新增或待执行migration。Nginx唯一生效上传限制已由`50m`精确调整为`110m`并通过`nginx -t`,支持100MiB XLSX的multipart开销,同时保留应用层100/500MiB、ZIP条目和图片总量限制。
- API、Send Worker、Submit Outbox、Gateway Callback、Protocol Log Worker、Gateway、Security Agent、Nginx、PostgreSQL、Redis、MinIO和Prometheus共12项均active`NRestarts=0 / Result=success`API、Callback、Gateway、PostgreSQL和Redis健康通过。七项应用服务自发布窗口起error级journal均为0。
- 发布后三条Stream的`last-delivered-id`和`entries-read`与发布前逐项相同:commands为`1787806802603-0 / 130918`results为`1787806917609-0 / 191696`protocol logs为`1787806802967-0 / 40472`;全部保持`pending=0 / lag=0`,没有发送、补发、重投、重新入队或手工ACK短信,也没有修改余额、通道、客户或签名业务资料。
- 工作站从测试环境实际下载主资源`index-DnhPgg2m.js`和`index-D9xR3Zhi.css`SHA-256分别为`baa23f0aa62b3a8d1051718cca4a927316b4e2724244e3f39147888e3ea31a36`、`b193f9521c0104d35c645492cdf8c6e71e764349ff6bef59c8da77366e327cb4`,与服务器产物一致。真实浏览器读取到“聆界短信管理平台”运营登录页及用户名、密码、图形验证码和登录按钮;后续截图/控制台采集超时,且未使用平台管理员登录态,因此登录后功能与控制台仍不冒充已完成真实浏览器验收。
- 服务器本轮临时上传包和`/tmp`脚本已在日志归档后清理,完整恢复点及上一运行目录保留。预生产`8.160.169.106`未访问、未部署、未覆盖、未回退或修改。
## 2026-09-04 通道字段池单卡片高度补救
- 重新检查确认上一轮只设置左侧字段按钮`min-height: 68px`,没有阻止父级CSS Grid在字段较少时把自动行拉伸到剩余高度;添加字段导致可选数量变化后,单个字段卡片仍会重新分配高度,原验收结论不成立。
- 补救将字段池设为`align-content: start`并固定`grid-auto-rows: 68px`,同时把单个按钮的`height/min-height/max-height`统一为68px,确保签名和引流字段弹窗在任意可选数量下都不改变单卡片高度;不修改字段选择、保存接口或业务数据。
- 回归测试直接验证添加前两个卡片及添加后剩余卡片的高度均为68px;定向Vitest 1文件2项、前端TypeScript和`git diff --check`通过。本轮按用户补充要求仅本地提交,不推送、不部署;测试环境继续运行`bb435fb0ac1e7812fcdb59950a4b13757899ab39`,预生产未访问。
## 2026-09-04 导入签名审核必填字段修复与全流程验收
- 测试环境失败批次`cmtmt7tge003zcaledaw1atog`和`cmtmtfp3o004scale3hdm2bjp`真实记录显示,XLSX中的签名、图片及其他动态字段已进入导入暂存,其中图片已写真实`FileObject`;应用同时把短信签名、签名用途、企业名称和应用名称配置为必填动态报备字段。导出阶段会从业务实体解析这些系统身份字段,导入审核落库阶段却只检查`signatureReportValues`,因此在创建签名前误报“缺少必填签名报备资料”。
- 修复在导入审核落库前按既有导出语义从签名、企业和应用实体物化系统身份字段,当前签名用途为空时不伪造值,用户显式映射值覆盖系统派生值,未映射旧资料继续保留。新增纯函数与导入审核回归覆盖签名、用途、企业、应用和图片引用;对应功能用例为`TC-REPORT-MATERIAL-IMPORT-004`。
- 定向报备服务17项、API全量53套610项通过;API与前端TypeScript、API生产构建、Vite生产构建及`git diff --check`通过。直接执行不带构建配置的API `tsc --noEmit`会把测试文件纳入且因未加载Jest类型失败,已改用项目正式`tsconfig.build.json`复核通过,未把错误命令结果冒充构建失败。
- 功能提交为`41962e7a6e6cfd34b4313c8bf52d9345d37d8e10`,包含此前仅本地的字段卡片固定高度提交`0ec386e`。推送前fetch确认相对`origin/main`为`ahead 2 / behind 0`;首次非交互推送因凭据助手未进入交互流程而认证失败,随后启用系统凭据助手交互模式后成功推送功能及验收文档提交,未改写或回退远端。
- 测试环境发布前为`bb435fb0ac1e7812fcdb59950a4b13757899ab39`。发布包大小2766696字节,本地和服务器SHA-256均为`2d3c9a022ba1b6494a51e2ee0f3eb04eabb2513af25ba3631dae5ea70ea68783`;恢复点为`/opt/cmpp-platform-backups/import-review-fix-20260904T122649Z`,包含PostgreSQL custom dump、原运行目录、系统配置及发布包,四项SHA、`pg_restore --list`和两份tar可读性通过。95项migration齐全且无待执行项,没有执行迁移;最终`.deployed-commit=41962e7a6e6cfd34b4313c8bf52d9345d37d8e10`,旧运行目录为`/opt/cmpp-platform.previous-import-review-20260904T122649Z`。
- 使用自行生成的标准Excel Drawing工作簿`签名导入全流程测试-含图片.xlsx`走真实HTTP API:解析得到6列、1张图片,导入批次`cmtmxvjuh000xluleh38c4sjy`审核结果`approved / approvedCount=1 / failedCount=0`;生成签名`cmtmxvjyh0014lule5o2t16m9`为`approved`,四项系统身份字段、图片`FileObject`及6个通道图片材料均在PostgreSQL存在。报备批次`cmtmxvk8c0043lules3upx5f2`完成并生成6个真实通道文件,下载ZIP中的首个XLSX包含`xl/media`图片。批次生成后签名`pendingReport=false`,没有发送、补发、重投或重新入队短信。
- API验收使用本轮临时平台管理员,登录、近期认证、导入、审核、生成和下载均经过真实HTTP会话;结束时调用登出并删除临时账号,查询剩余数为0。浏览器已读取测试环境登录页、验证码控件和页面标题,控制台无warning/error;登录后页面交互需按浏览器安全规则由用户确认验证码后继续,不将当前登录页检查冒充已完成登录后验收。
## 2026-09-04 WPS报备兼容与导入审核修复(预生产发布完成)
- 用户明确授权发布预生产。发布前重新核验本地与`origin/main`均为`aaf96db2d018cfcea79b6cdbf553cee9cb982fa2`,预生产原标记为`dada0d978bb05d7046469c1ec77371ddb2fb03bc`;累计范围为9个提交、44个文件,包含运营看板、报备字段配置、WPS单元格图片导入导出、100MiB上传限制、字段卡片固定高度及导入审核系统身份字段补齐。没有新增migration,既有未跟踪补救方案文档未进入发布归档。
- 发布前数据盘UUID`ef4ee3bb-a19b-4aeb-b00c-aa2b995611c2`、PostgreSQL/Redis/MinIO绑定挂载、存储保护脚本、systemd drop-in和固定备份入口全部通过;95项migration齐全,相关服务健康,三条Redis Stream均`pending=0 / lag=0`,供应商连接为`desired=9 / connected=9`。
- 首次恢复点`/opt/cmpp-platform-backups/preprod-wps-import-20260904T211224Z-before-aaf96db`因`pg_dump`不接受Prisma连接串的`schema`查询参数而在数据库导出阶段安全停止;当时尚未构建、迁移、切换、重启或修改Nginx。改用去除查询参数的数据库连接后重新建立有效恢复点`/opt/cmpp-platform-backups/preprod-wps-import-20260904T211255Z-before-aaf96db`,约613MiB,包含PostgreSQL custom dump、Redis RDB、原运行目录、环境/systemd/Nginx/Fail2ban/nftables及数据盘保护配置、原标记和发布基线。
- 有效恢复点的8项最终SHA-256全部通过,`pg_restore --list`包含825项,运行目录tar包含52641项、系统配置tar包含370项;精确Git归档大小2768402字节,SHA-256为`d984c79d0deef1a83ec418b4806875eca210343bb76e03f174887614ba6517c1`,服务器回读一致。候选版本通过依赖安全、部署契约、Prisma生成与迁移状态、前端/API/Gateway/Security Agent生产构建以及`cmpp-api`用户运行文件可读/可执行门禁。
- 最终`.deployed-commit=aaf96db2d018cfcea79b6cdbf553cee9cb982fa2`,上一运行目录保留为`/opt/cmpp-platform.previous-preprod-dada0d9-20260904T211255Z`。95项migration仍齐全且无待执行项,本轮未执行数据库迁移。Nginx仅将`sms.lisglo.com`和兼容端口12026的两个`client_max_body_size 50m`精确调整为`110m`API专用域名保持`10m``nginx -t`通过后reload,没有修改数据盘、fstab、UUID、存储保护脚本或systemd存储drop-in。
- API、Send Worker、Submit Outbox、Gateway Callback、Protocol Log Worker、Gateway、Security Agent、Nginx、PostgreSQL、Redis、MinIO、Node Exporter和Prometheus均为`active`,相关应用服务`NRestarts=0 / Result=success`API、Callback、Gateway、PostgreSQL和Redis健康通过。`12026`、`sms.lisglo.com/api/health`和`api.lisglo.com/api/health`均为HTTP 200,主JS`index-CFz3CyND.js`及CSS`index-C3z6fQED.css`的公网下载SHA-256与服务器产物逐项一致。
- 发布后三条Stream的`last-delivered-id / entries-read`与发布前一致:commands为`1788517020869-2 / 84015`results为`1788527156466-0 / 45876`protocol logs为`1788527156467-0 / 32227`;全部保持`pending=0 / lag=0`。本轮未发送、补发、重投、重新入队或手工ACK短信,也没有修改余额、通道、客户或签名业务资料。
- 一条富泷供应商通道在重启后首次鉴权失败,连接短暂为`8/9`,系统按既有计划于21:20:25自动重试并恢复`9/9`,未修改通道配置或凭据。真实下游客户端受旧心跳租约影响的重复连接被连接数门禁拒绝,并记录3次既有`close of closed channel`连接协程panicGateway进程未退出、下游心跳持续、systemd error级journal为0,该已知重启恢复缺陷不由本次报备功能引入,继续保留专项治理。
- 浏览器控制在读取预生产运营登录页时连续两次超时,因此本轮没有取得可复核的DOM、截图或控制台证据,也未输入账号、密码或验证码;只把真实HTTP、资源哈希和服务端证据记为通过,不将其冒充登录后浏览器验收。
## 2026-09-04 大文件WPS报备异步解析与真实进度(测试环境发布完成)
- 40MB以上WPS文件同步解析会让单个HTTP请求同时承担上传、两轮ZIP/图片展开和ExcelJS解析,预生产证据已出现约126秒后由入口断开的499;单纯展示前端动画进度不能延长代理读超时。本轮将接口改为文件入MinIO并创建PostgreSQL任务后返回202,由独立`cmpp-report-material-worker`单并发解析,页面轮询租户隔离的真实任务状态。
- 新增`queued/analyzing/analyzed/failed`状态、0–100进度、阶段、错误、开始和心跳时间;Worker启动时将心跳超过5分钟的解析任务恢复为排队状态,领取时使用状态条件更新防止重复占用。该变更新增1项Prisma migration和1个systemd服务,发布时必须同时迁移数据库、安装并验证Worker,不涉及短信队列、通道、余额或客户配置。
- 报备导入使用独立100MiB上限,普通文件仍为10MiB、图片仍为2MiB。文件类型、扩展名和ZIP签名在入库前校验;工作簿公式、外部对象、解压体积、图片格式及图片数量关系在后台解析或提交阶段明确失败,不静默吞错。
- 分析阶段读取WPS`cellimages.xml`关系、单元格位置、扩展名和ZIP声明大小,不展开图片Buffer,并在交给ExcelJS前从临时解析副本剥离WPS媒体;提交导入时仍重新下载原文件并完整读取、签名校验和上传图片,没有放宽DISPIMG白名单或20MiB单图/300MiB图片总量限制。
- 真实样本`行业报备.xlsx`仍得到工作表“行业”、17行、13列和43张图片。相同进程环境下原完整图片模式约5522ms/RSS 259MiB,新分析模式约1899ms/RSS 227MiB,耗时下降约66%,结果计数一致;样本只读,未覆盖或写回。
- 定向API 3套25项、API全量54套616项、前端全量13文件64项通过;前后端TypeScript、API/Vite生产构建、依赖与安全门禁、部署契约、结构质量、入口包体积和`git diff --check`通过。
- 功能提交`5925cf493bc83bdeaeeb2a79cb6b8026db5d5772`已推送至`origin/main`并发布测试环境。发布前标记为`41962e7a6e6cfd34b4313c8bf52d9345d37d8e10`;恢复点为`/opt/cmpp-platform-backups/wps-async-20260904T145510Z-before-5925cf4`,约674MiB,包含PostgreSQL custom dump、Redis RDB、原运行目录、配置、发布包和基线证据,数据库清单、tar可读性及SHA-256均通过。上一运行目录保留为`/opt/cmpp-platform.previous-wps-async-41962e7-20260904T1500Z`。
- 新migration已执行,测试环境由95项增至96项;`cmpp-report-material-worker`已安装并保持`active/running`、`NRestarts=0`、`Result=success`。API、Gateway、其他Worker、Nginx、PostgreSQL、Redis、MinIO和Prometheus均正常,发布窗口API及新Worker无error级journal;三条短信相关Redis Stream发布前后均为`pending=0 / lag=0`,没有发送、补发、重投或重新入队短信。
- 真实HTTP上传20,976,525字节的`行业报备.xlsx`在约0.32秒内返回`202 / queued / 10%`,独立Worker随后完成解析并持久化`analyzed / 100% / 解析完成`,结果为13列、16条数据行、43张图片;错误租户查询返回404。将同一任务模拟为UTC口径的超时心跳后重启Worker,任务从70%恢复并重新完成到100%,验证了中断恢复。
- 真实Chrome页面从企业签名管理发起同一WPS文件上传,网络证据为`202 queued 10%`后轮询至`200 analyzed 100%`,映射弹窗显示13列和合计43张图片;1600×1000桌面端及390×844窄屏均无页面级横向溢出,浏览器控制台无warning/error。浏览器会话关闭后,临时管理员已从数据库删除且剩余数为0;验收任务和对应`FileObject`保留为可追溯测试证据。预生产本轮未访问或修改。
## 2026-09-05 签名导入映射、审核跳转及预览宽度修复(本地提交)
- 测试环境两个真实导入批次的只读证据显示:首次批次因源文件没有映射“签名用途”而在审核阶段明确报缺少必填资料;第二次批次把“签名*”和“签名类别*(1-营业执照/2-商标/3-APP)”同时自动映射到`signatureName`,导致19条暂存签名名均被类别值`1`覆盖。解析和提交接口均已成功返回,问题根因是通用“签名”规则先于用途/类别规则匹配,以及核心字段缺少重复映射保护,不是浏览器缓存或异步任务未执行。
- 自动映射改为优先识别签名用途、依据、类别和类型,再识别签名名称;前后端同时拒绝两个源列映射到同一核心目标字段,动态资料字段仍允许按既有兼容逻辑重复。提交成功后页面直接进入审核中心“导入批次审核”并自动打开本次批次详情,避免用户误以为没有进入审核。
- 映射弹窗新增页面私有样式约束,解析预览和映射表都使用可收缩容器,长预览内容在自身区域滚动,展开“查看前10行解析预览”不再改变目标字段下拉框宽度;没有向`global.css`新增选择器。
- 控制台所示`VM*:2`、`reportAllChanges`和`startTime`调用栈不在仓库源码、依赖声明或构建入口中,形态与浏览器动态注入的Web Vitals采集脚本一致。本轮没有增加全局错误吞噬或修改业务代码掩盖该外部异常;后续真实浏览器验收需用无扩展会话区分平台脚本和注入脚本。
- 定向前端组件测试2项、定向API映射测试3项通过;前端全量13套65项、API全量55套619项通过;前后端TypeScript、API生产构建、Vite生产构建、依赖安全、部署契约、结构质量及增量ESLint通过。Vite仅保留既有Chart分块超过500kB提示,增量ESLint仅保留3条既有Hook依赖warning。本轮按用户最终要求只本地提交,不推送、不部署测试环境或预生产,不操作短信链路、余额、通道及客户配置。
## 2026-09-05 全局CSS模块化治理(本地实施与发布前验收完成)
- 重新读取根目录`AGENTS.md`、`docs/css-development-guidelines.md`和完整拆分方案后执行。原`global.css`为213062字节、9846行,经PostCSS统计为1749条规则、2017个选择器、5321条声明和30个既有`!important`;现已删除并按原顶层节点顺序迁入14个所有权模块,由`src/styles/domains/index.css`固定顺序加载。各业务域文件均不超过1200行建议值。
- 迁移没有改变CSS级联:格式化新模块并重新生产构建后,迁移前后主CSS均为`index-CkSy6WDi.css`SHA-256均为`d7043ee2229a402c6b9284c9153536dd6393446a3b0fe7c47ee7dd05290539c3`,工作站逐字节比较无差异。机器基线保存完整选择器顺序、模块指标、所有者、摘要、既有例外和入口顺序。
- 新增Stylelint及显式历史兼容范围;未登记新CSS默认执行标准规则。增量Prettier现覆盖CSS,跨平台调用改为直接执行Node入口。CSS治理门禁阻止重建`global.css`、改变模块顺序或AST总量、新增未登记`!important`、新增宽泛业务标签选择器及无import所有者文件;Node四项门禁测试和实际临时违规样例均验证为能拒绝,样例随后删除。
- 新增GitHub CSS质量工作流,在PR中比较目标分支、main推送中比较父提交,避免只检查工作区。实施结果、模块所有权和后续维护边界记录于`docs/css-modularization-result-20260905.md`,方案文档同步改为已实施状态。
- 发布前真实Chrome基线使用测试环境真实API和PostgreSQL数据:运营端13个核心路由、客户端10个核心路由分别在1600×1000、1366×768、390×844检查,共69张截图;页面均非空、无框架错误层、无页面级横向溢出,控制台warning/error为0。临时平台管理员和企业管理员仅用于验收,发布后将精确删除。
- 前端全量13套65项、API全量55套619项、CSS治理4项通过;前后端TypeScript、API/Vite生产构建、Stylelint、增量ESLint/Prettier、依赖安全、部署契约、结构质量、包体积和`git diff --check`通过。入口gzip 107.85KiB,低于250KiB预算;只保留既有Chart分块超过500kB提示。发布、推送、发布后69页三尺寸回归、恢复资产、服务/Stream和临时账号清理结果将在完成后追加。
## 2026-09-05 全局CSS模块化治理(测试环境发布完成)
- 实施提交`458ddd97dfd0b46fdc2f75b1cde9555bb0fa70ee`和归档门禁修复提交`798e85c9300fe7a16add292dbb5b0ac54b63d783`已推送至`origin/main`。测试环境原标记为`65082959c05c975eb7856ee281811a37e1fc284a`,运行代码已切换到`798e85c9300fe7a16add292dbb5b0ac54b63d783`;上一运行目录保留为`/opt/cmpp-platform.previous-css-6508295-20260905T0055`。
- 发布前恢复点为`/opt/cmpp-platform-backups/css-modularization-20260904T164645Z-before-6508295`,约667MiB,包含PostgreSQL custom dump、Redis RDB、原运行目录、系统配置、原部署标记、服务与三条Stream基线和精确发布包。4项恢复资产SHA-256、843项`pg_restore --list`及两份tar可读性均通过;发布包大小2831781字节,SHA-256为`75d647f5d645fbd0ef0962312d7495111e5ef30bff81762660c0db627a5ca5d6`,工作站、测试机及恢复点副本一致。
- 候选目录在无`.git`的归档场景下通过依赖安装、依赖安全、部署契约、Stylelint、CSS治理及4项门禁测试、Prisma生成和状态检查、前端/API/Gateway/Security Agent生产构建。96项migration全部齐全且数据库无待执行项,本轮没有执行数据库迁移,也没有调整Nginx、systemd、通道或部署架构。
- 原子切换后API、Gateway Callback、Gateway、MinIO、Protocol Log Worker、Report Material Worker、Security Agent、Send Worker、Submit Outbox、Nginx、PostgreSQL和Redis共12项服务均为`active`8项应用进程均`NRestarts=0 / Result=success`。API、Callback和Gateway健康通过,发布窗口相关服务warning及以上journal为空。
- 三条短信相关Redis Stream发布前后逐项一致:`gateway.submit.commands`为`last-delivered-id=1787806802603-0 / entries-read=130918``gateway.submit.results`为`1787806917609-0 / 191696``gateway.protocol.logs`为`1787806802967-0 / 40472`;全部保持`pending=0 / lag=0`。本轮没有发送、补发、重投或重新入队短信,也没有修改余额、通道、客户或签名业务资料。
- 测试环境真实Chrome回归使用真实API和PostgreSQL数据:运营端13个核心路由、客户端10个核心路由分别在1600×1000、1366×768和390×844检查,共69个页面状态均已登录、非空、无框架错误层及页面级横向溢出;控制台warning/error为0,失败API或静态资源响应为0。外部入口API健康HTTP 200,实际下载CSS`index-CkSy6WDi.css`和JS`index-BLtRK0rD.js`的SHA-256与服务器产物一致;CSS摘要仍为迁移前后的`d7043ee2229a402c6b9284c9153536dd6393446a3b0fe7c47ee7dd05290539c3`。
- 两个临时验收账号已精确删除,数据库剩余数为0,并删除其5个Redis会话;本地认证状态文件和测试机临时发布包也已清理。浏览器自动化最初复用仅含运营端会话的状态文件时,客户端正确返回401并跳转登录;修正验收脚本为客户端真实登录后重新执行,最终30个客户端页面及全部网络检查通过,该测试夹具问题不属于平台回归缺陷。预生产环境未访问或修改。
## 2026-09-05 CSS门禁缺口修复(本地验证与测试发布准备)
- 用户授权修复、代码提交和测试环境发布,未授权推送或预生产访问。开始核验main/HEAD及origin/main为`64bfb9a`;工作区已有7份规范修改、未跟踪设计开发规范及报备补救方案,均保护不动,测试进度仅提交本轮精确新增段落。
- 根因:Stylelint历史兼容使用目录通配符,所有权仅搜索文件名,宽泛选择器识别不完整,AST计数不检查声明值/媒体条件,CI的main推送仅比较最后一个提交。详见`css-modularization-result-20260905.md`新增复核章节,用例`TC-CSS-MOD-007`至`012`。
- 新增逐文件所有权和历史AST内容摘要、真实TS/CSS import解析与入口可达性、新文件根className/选择器约束;Stylelint改为精确路径,CI覆盖整次推送及PR merge-base,归档执行完整静态检查。直接声明当前已锁定的PostCSS及selector-parser开发依赖,未升级版本;应用TSX、全部CSS、入口顺序、API、数据库和短信链路均未修改。
- 本地验证:门禁15项、前端13套65项、API55套619项通过;前端TypeScript/Vite和API正式构建通过,format/style/css、增量ESLint、结构、安全、部署契约和包体积门禁通过。主CSS仍为`index-CkSy6WDi.css`SHA-256为`d7043ee2229a402c6b9284c9153536dd6393446a3b0fe7c47ee7dd05290539c3`,入口gzip 107.85KiB。构建保留既有Chart超过500kB及耗时提示;API测试中的异常日志来自测试替身的失败场景,不是线上短信操作。
- 2026-09-05测试机SSH实时标记为`64bfb9ad3d6a4e6f57770839172ea50eee984a18`API/Gateway正常,三条短信Stream均pending=0/lag=0。测试机实际使用系统盘,不套用预生产UUID/迁盘规则;发布恢复点`/opt/cmpp-platform-backups/css-gates-20260905T013053Z-before-64bfb9a`约451MiB,包含PostgreSQL custom dump、完整运行目录、配置、服务/Stream/挂载与资源摘要基线;pg_restore目录、tar可读性及三项SHA均通过。
- Browser技能不在当前会话,按前端测试技能使用现有Playwright/Edge。测试环境真实运营端和客户端登录页在1600×1000、1366×768、390×844完成首次进入、刷新、跨入口导航,共6个状态,页面非空、无横向溢出,控制台/页面异常及失败HTTP响应均为0。证据位于本机临时目录`cmpp-css-gates-20260905/browser-smoke.json`及截图。未提交登录、未创建账号,登录后业务交互未重跑,不用登录页或单元测试冒充真实业务验收。
- 14个模块仍是历史全局兼容分区,进一步按业务收拢响应式和页面隔离未在本轮实施;静态根类检查不能证明实际DOM/Portal层级。发布采用明确提交归档,候选门禁及资源一致性检查通过后仅更新治理文件和文档,不运行全量初始化/迁移/重启脚本。测试发布结果另行追加。
## 2026-09-05 CSS门禁缺口修复(测试环境发布完成)
- 功能提交`ca1fc2847fc90b85861e63fd09a3a46cf1d4b4be`已本地提交并发布测试环境`100.93.204.60`;没有推送远端,没有访问预生产。11个提交文件仅包含治理配置、脚本、清单、直接开发依赖声明及本轮文档;其他会话7份规范修改及2份未跟踪文档完整保留,测试进度使用Git blob精确暂存本轮段落。
- 精确提交归档SHA-256为`b9747c3ec71d433b9bfe8deb651992ad34a62847d1683353480f566cc8adfb5f`,本机、测试机及恢复点副本一致。候选目录复用独立复制的现有node_modules,验证锁文件实际包图完全一致;无.git场景的Stylelint、完整CSS门禁15项、TypeScript/Vite生产构建和包体积检查全部通过。
- 发布前旧源文件和候选源文件分别与原提交及功能提交核对。Windows归档带CRLF,统一行尾后11项内容全部匹配;同时保存原始字节摘要并在写入前再次校验,未把真实额外修改当换行差异覆盖。候选与线上96个前端文件逐文件SHA一致;首次比较清单漏列3个Logo文件造成停止,补齐完整资源集合后通过,没有改动资源绕过比较。
- 恢复点沿用本轮独立的`/opt/cmpp-platform-backups/css-gates-20260905T013053Z-before-64bfb9a`,切换前再次验证数据库、运行目录及配置SHA。仅按提交清单逐文件替换治理文件和文档,实际运行树再次通过CSS及Stylelint门禁后更新部署标记;无服务重启、数据库迁移、Nginx/systemd改写或业务配置变更。
- 发布后12项服务ActiveState/MainPID/NRestarts与发布前完全一致;API、独立Callback、Gateway及MinIO健康正常。PostgreSQL只读查询确认96项已完成migration、未完成0项;三条短信Stream组状态逐字一致,pending/lag均为0。发布窗口warning及以上journal为0行,相对恢复归档日志末尾的新增应用错误匹配为0;所有既有dist文件摘要校验通过。
- 工作站从真实HTTP入口回读index.html、主CSS和主JSCSS/JS与本地构建字节摘要一致;index.html与服务器候选字节一致,相对本机构建仅有CR字符和末尾空白差异,去除CR并裁剪末尾空白后全文相同。发布后Playwright/Edge再次检查两端登录页三尺寸的首次进入、刷新和跨入口导航,共6个状态均非空、无横向溢出、无控制台/页面异常和失败HTTP响应。仅做未登录入口回归,未创建账号或绕过验证码,登录后业务交互仍未重跑;未以此冒充完整业务验收。
- 发布证据包含恢复点中的`release-manifest-verified.json`、候选及实际门禁日志、完整资源摘要、服务/Stream前后快照及journal,以及本机临时目录中的`browser-smoke.json`、6张截图和`http-after.json`。本段验收文档单独本地提交并同步测试机;不推送远端,不发送、补发、重投或重新入队短信,不修改余额、通道或客户配置。
## 2026-09-05 签名导入待审通知与通道组成本(本地提交)
- 当前main基于15a1f9d,已有文档改动和未跟踪方案保留。本次仅授权修改并本地提交,不推送、不部署。需求见first-version-development-requirements.md末节,用例TC-IMPORT-NOTICE-001/002、TC-CHANNEL-COST-001。
- 根因:导入资料先进入ReportMaterialImportItem,原pendingAudits仅统计正式签名等5类表,漏计导入待审;提交导入和审核完成未触发顶部刷新。真实测试库signature pending_review=19、approved=20、invalid=27、rejected=19,正式签名pending=0,解释原通知缺失。
- 修复:新增signatureImports可兼容旧响应的计数字段,按reportType=signature/status=pending_review并经batch.tenantId限定计数,计入total;右上角新增“签名导入待审”直达/admin/signatures?tab=import。导入及审核成功时触发既有刷新事件;不改正式审核流程、不重复创建任务。通道组省网/全国列表展示unitPrice/10000、四位小数成本,缺失显示—,零显示0.0000;无CSS、数据库结构、队列、路由或价格写入改动。
- 自动验证:前端13套65项通过,补充导入成功刷新事件断言后该2项定向测试通过;API全量55套执行,新增测试后619项通过、1项因既有dashboard响应断言未包含新字段而失败,更新该断言后operations定向32项全部通过(累计620项通过)。前端TypeScript/Vite和API构建通过;Stylelint、CSS治理15项通过。Chart既有包体告警仍在。
- 质量门禁:format:check和lint已执行,未宣称全绿。HEAD与本轮逐文件ESLint对照确认dashboard.queries.ts原有39条unused等错误、通道组表单原有1条set-state-in-effect错误,另有2条既有依赖警告,本轮相同。Prettier基线证明API查询、API测试、通道组表单3文件原已不通过;AdminLayout新增格式已修正。为保持最小范围未夹带整文件格式化或历史Hooks重构。git diff --check通过。
- 真实验证:从候选构建提取实际pendingAudits函数,在测试机用真实Prisma/PostgreSQL只读执行;全平台和所选QA租户signatureImports=19/total=21,不存在租户全0。没有替换服务器应用文件或启动新业务服务。
- 浏览器:本地生产预览http://127.0.0.1:4173代理测试环境真实API,正常算术验证码登录临时运营账号。1600×1000、1366×768、390×844进入及刷新通道组编辑页,两个成本列存在、真实零成本显示0.0000、无整页溢出;右上角新入口在三尺寸均进入导入审核页签;pageerror和console error均0。Browser技能不可用,按前端测试技能用Playwright/Edge。证据在本机临时目录cmpp-notice-cost-qa/browser.json、截图和lint-baseline.json。
- 验收边界:测试机API仍是15a1f9d,故候选页面上的新计数按旧响应兼容显示0;新统计用真实数据库函数单独验证,未把分段证据冒充新版本端到端部署验收。未执行新的文件上传/审核写入、通道组保存、非零/缺失价格真实夹具及失败注入;不发送短信,不改余额或通道配置。临时用户精确删除后0残留,logout后无剩余Redis会话,本机凭据/storageState及服务器凭据已清理。
- 后续交互建议(未实施):现有历史优先级10/20与编辑下拉1—5不兼容;同优先级/同省份会过滤原行。建议先修正历史值回显和冲突处理,再加入全国路由上下移动/拖拽、明确顺序预览、可搜索通道选择及未保存提示;与本次成本展示分开实施。
- 提交前补充:签名审核页页签由URL直接派生,修正已停留在该页时通知只改query而未切换页签的问题;新增同路由query切换回归测试通过。该文件另有HEAD已存在的1条preserve-manual-memoization错误和1条依赖警告,未扩展整改。
- 最终前端全量14套66项通过,最终TypeScript/Vite生产构建通过;本轮共13个目标文件精确暂存,已有文档段落保持未暂存。
## 2026-09-05 通道组编辑交互优化(发布前验证)
- 按用户确认方案完成通道组新建/修改交互:草稿编辑、历史优先级兼容、显式冲突校验、全国通道上移/下移/拖拽与撤销、顺序预览、可搜索通道选择、成本/地区/运营商/真实连接回写、不可选原因、保存摘要和未保存离开保护。保存继续使用真实API,保留既有组状态/描述及成员权重/主备属性;新建部分失败后以已创建ID重试,避免重复创建。
- 新增页面及弹窗私有CSS,由各自TSX直接导入并登记所有权;未重建global.css、未向14个历史兼容模块追加规则、未增加`!important`或宽泛标签选择器,也未改变domains/index.css顺序。
- 自动验证:通道组纯函数、选择弹窗和整页交互定向3套24项通过;前端全量17套90项、API全量55套620项通过。format:check、Stylelint、CSS治理15项、TypeScript/Vite生产构建、API构建、安全、部署契约和包体积门禁通过;既有Chart包体提示不影响构建。
- 候选页面通过测试环境真实API/PostgreSQL只读验收,所有业务写请求由浏览器路由拦截。1600×1000、1366×768、390×844均完成排序/撤销、重复优先级拦截、搜索空态、保存前预览和离开取消;无页面级横向溢出,pageerror和console error为0。验收未保存真实通道组、未修改成本或通道配置、未发送/补发/重投/重新入队短信。
- 测试与预生产发布前已分别建立独立恢复点并核验运行版本、服务、数据库迁移及存储保护。预生产从旧版本发布完整最新版本,预计新增1项向后兼容报备解析迁移及独立解析Worker;实际提交、推送、双环境切换和发布后真实验收结果在完成后追加。
## 2026-09-05 通道组编辑及完整最新版本双环境发布
- 功能提交`1e05a643e5398973bd32953fc95ed5c3aa2b0daf`包含通道组交互优化,并连同此前未发布的WPS异步解析、签名导入待审通知、通道组成本展示和CSS治理完整版本发布。精确Git归档SHA-256为`f600dc90cc69264e8ee3d351b6559cea507d7f4d76bd0edc0f96fc0d3268d138`,前端归档为`098f12c124eb4979d2888f4002bee25016c6f6ed9e19d247ecf2114ddf98e888`;工作站、测试机和预生产逐一一致。远端Git首次推送因现有认证失效未完成,服务器使用本地精确提交归档发布,不把部署误记为推送成功。
- 测试环境从`15a1f9d8eddd4f7233987fbf676a91f4e0bfab08`切换,恢复点`/opt/cmpp-platform-backups/channel-groups-20260905T1430`的数据库、运行目录和配置摘要均通过。96项迁移已齐全,无数据库迁移;API和报备解析Worker重启,Gateway未重启。API、Gateway、Worker、Nginx、PostgreSQL、Redis和MinIO均active,应用进程`NRestarts=0/Result=success`,发布窗口warning及以上journal为空。
- 测试环境短信记录发布前后均119509,三条短信Stream的XINFO GROUPS逐字一致。真实API登录后,签名导入待审为19;1600×1000、1366×768和390×844完成通知跳转、排序/撤销、冲突校验、搜索空态及保存预览,均无页面级横向溢出、控制台错误或失败响应。所有业务写请求均被浏览器拦截;临时管理员删除后0残留,精确删除3个Redis会话并保留操作审计。
- 预生产从`aaf96db2d018cfcea79b6cdbf553cee9cb982fa2`切换。发布前再次验证独立恢复点、PostgreSQL/Redis/MinIO数据盘UUID和备份盘保护;执行唯一待处理的`20260904090000_report_material_async_analysis`向后兼容迁移,迁移总数由95变为96。新增独立`cmpp-report-material-worker`,数据库池上限4API重启,Gateway及其他Worker未重启。
- 预生产API、Gateway、新Worker、Nginx、PostgreSQL、Redis和MinIO均active,三项应用进程`NRestarts=0/Result=success`;短信记录发布前后均86692,通道连接状态仍为connected 6、disconnected 7、failed 5,报备批次状态计数不变,三条短信Stream逐字一致,发布窗口warning及以上journal为空。数据盘和备份盘保护在发布后再次通过。
- 公网`https://sms.lisglo.com/api/health`返回ok;实际下载的主JS`index-Cf0GV6WF.js`和主CSS`index-CkSy6WDi.css`与本地候选SHA-256一致。三尺寸登录页首次进入及刷新均无整页溢出、控制台错误或失败响应。服务器两份历史管理员凭据对应账号当前均为deleted,正常登录返回401;未重置账号或新增预生产管理员,因此登录后通道组交互由同提交的测试环境真实验收和预生产API/数据库/资源证据覆盖,不宣称预生产登录后页面已验收。
- 两套环境均保留原运行目录及独立恢复点;未执行全量初始化脚本,未修改余额、通道、客户配置、fstab、UUID、数据盘挂载、存储保护脚本或systemd存储drop-in。未发送、补发、重投或重新入队短信。
## 2026-09-06 顶栏报备任务提醒(本地实现与真实测试环境API验收)
- 开始核验:main、HEAD与远端main均为`442dda711d5c9f778f3f76fd6d8fd69f14414ce6`,差异0/0、暂存为空。原有8份修改文档和3份未跟踪文档继续保护;其中testing-progress、功能用例及部署文档仅提交本节相关新增段落。测试机部署标记只读回读仍为442dda7,本轮未访问预生产。
- 根因与范围:AdminLayout原将签名清退、安全、系统监控放入同一alertNotificationsAppShell只有预警与审核两组。现新增平级报备任务提醒,将清退原路由/真实计数移入,增加禁用的报备进度提醒和待开发标签。抽取共用AlertNotificationMenu统一样式、计数和交互,三类通知互斥展开,审核与侧栏清退入口保留。继续使用既有四个轻量API及刷新事件,无后端代码、数据库结构、迁移、队列或消息生产者修改。
- 视觉复查发现390px顶栏裁切:导航/帮助的显隐类与公共icon-button处于同一节点,后加载的公共display覆盖响应式规则。将显隐类放在包装节点,按钮继续使用公共样式,修复重复导航/窄屏帮助占位;不增加优先级或important,不改变CSS导入顺序。新增CSS仅在布局菜单同目录直接导入并登记所有权,未改14个历史模块或shell.css。AppShell按现有Prettier门禁格式化,其他会话/锁屏逻辑未变。
- 自动验证最终结果:前端18套95项全通过(新增5项涵盖分组计数、待开发禁用、互斥/跳转、刷新/失败隔离与客户端无配置)。新增测试初次全量出现默认1秒异步超时及不适用的exact选项类型错误,已改用5秒有界等待、正确角色匹配及精确零角标断言,最终全量复验通过。TypeScript、生产构建、quality:verify、变更ESLint、format:check、Stylelint、CSS治理及其15项测试、bundle:verify、diff检查通过;Chart保留既有500kB提示,入口gzip 108.27KiB低于250KiB预算。当前shell无npm入口,均用既有Node执行package.json的等价脚本,未安装依赖。
- 真实验收:使用本地生产预览`http://127.0.0.1:4173`代理测试机真实API,正常识别页面算术验证码并登录持久QA管理员。候选前端未部署到服务器。真实响应清退0、安全6(严重1)、系统监控2(严重1)、审核21(含签名导入19);预警合计8,报备合计0。1600×1000、1366×768、390×844完成首次进入、刷新、三菜单互斥/开关、禁用占位和原清退路由跳转;按钮/弹层边界均在视口内,计算背景/边框/圆角/字号与预警中心一致。截图逐一复查,console warning/error、pageerror及HTTP失败响应均0。Browser插件/技能入口不可用,按前端测试技能使用已有Playwright/Edge。
- 数据与账户:用户授权新建并保留`codex_qa_admin`ID `cmtphgp340000yrle7v11jemc`platform_admin、active),安全入口见[部署文档持久验收管理员节](production-deployment.md#测试环境持久验收管理员2026-09-06)。2026-09-06 15:32左右PostgreSQL短信记录仍119509,三条短信Stream的consumer/pending/last-delivered/entries-read/lag与验收前一致(pending/lag均0)。账号与受限凭据按要求保留,浏览器测试正常logout;未发送、补发、重投、重新入队短信或更改余额、通道、客户配置。
- 证据:本机`%TEMP%/cmpp-report-notice-20260906`的before.json/png、after.json、reporting-1600/1366/390.png、browser.mjs、build.log。浏览器脚本只在内存读取安全凭据,不保存会话凭证或密码到报告。
- 边界:真实清退正数、真实故障/权限注入和客户端账号登录未执行,正数/失败/无配置由隔离单元测试覆盖,不冒充真实验收;未为造数据改变历史消息状态。纯前端入口调整未重跑后端/Gateway全量测试与构建。仅授权本地提交,不推送、不部署测试或预生产;既有文档改动保持未提交。
## 2026-09-06 通道组顺序与候选过滤调整(本地实现)
- 起始main/HEAD为`bd920f7`,远端main重新核验为`442dda711d5c9f778f3f76fd6d8fd69f14414ce6`,本地领先1个提交,暂存空;原8份修改文档、3份未跟踪文档继续保护,本轮仅精确提交功能用例和本节增量。测试环境SSH回读部署标记442dda7,未访问预生产。
- 只读复现:真实测试API的电信本地压测组`cmsvlitxw002pgdleix0hs04d`PostgreSQL成员顺序为备用通道priority10、主通道priority20weight均100;原添加弹窗仍有优先级输入,最初6项全部不可选却完整展示。旧nextAvailablePriority在Int上限时选择更小空位,可能导致新增通道插队。顺序撤销按钮是grid子项而默认拉满;保存按钮既有min-width为160px。
- 修改:编辑页仅显示顺序,移除拖拽和弹窗优先级输入;新增通过appendNationalRoute在末尾分配顺序,上限时仅草稿按原相对顺序压紧,编辑成员保留位置。撤销与保存共用局部160px宽度类。候选列表先过滤不可选项,再搜索并显示可选总数;省份选项不从删除/不兼容/其他已占用通道产生。既有允许配置的停用/暂断连通道仍真实标注。未改历史CSS模块、import顺序或Stylelint例外。
- 补发一致性:只读核对SendRetryService以attemptedChannelIds排除已尝试通道,并调用selectChannelForMessage;其selectChannelCandidate按资格过滤后取最小priority。全国顺序与后端一致,主备/权重只在同priority内影响选择,前端/后端均校验全国priority唯一;省网匹配优先与失败转全国保持。本轮无API运行时代码、数据库结构或队列改动,新增后端4项顺序回归覆盖乱序输入、历史负数/大整数、备用在前及不可用通道跳过。
- 自动验证:定向前端3套24项、后端2套13项通过;最终前端全量18套95项、API全量56套624项通过。前端TypeScript、前后端生产构建、format:check、变更ESLint、quality:verify、Stylelint、CSS治理及15项测试、bundle:verify通过;保留既有Chart包体提示,入口gzip108.26KiB低于250KiB预算。当前shell无npm,使用已有Node执行package.json等价脚本;未新增依赖。实现时Array.at不符合现有TS lib,已改兼容数组索引。
- 真实浏览器:Browser插件入口不可用,沿用前端测试技能与已有Playwright/Edge。用持久codex_qa_admin正常验证码登录,本地生产预览4173代理测试环境真实API1600×1000、1366×768、390×844均完成首次进入/刷新、上移、撤销、新建草稿连续添加末尾、已加入项隐藏、搜索空态及路由切换,撤销/保存计算宽度均160pxconsole warning/error、pageerror、失败HTTP响应均0。截图复查列表仅顺序,窄屏弹窗及页脚可用。所有通道组写请求设置拦截,本轮只在前端草稿添加,不点击最终业务保存。账户保留并正常logout。
- 动态环境:浏览器验收期间其他操作新增了一个真实停用通道,旧候选快照因此不再匹配;改为用当前页面实际收到的API响应核对过滤集合,未删除或改写该通道。只读数据库短信记录119509;三条短信Stream在核验时pending/lag均0且last-delivered/entries-read与本轮开始一致。未发送、补发、重投或重新入队短信,未修改余额、通道或客户配置。
- 证据目录:本机`%TEMP%/cmpp-channel-order-20260906`内before.png、after.json、editor-1600/1366/390.png、choices-1600/1366/390.png、前后浏览器脚本、build.log和api-tests.log。首轮浏览器脚本修正了API路径/定位器及草稿beforeunload确认处理;不把脚本超时当作功能通过。图片、响应报告不含密码,认证文件沿用部署文档受限入口。
- 验收边界:未真实保存现有通道组、未执行短信补发;参数映射/保存失败用组件隔离测试,补发顺序用真实代码、当前PostgreSQL/API顺序及无副作用策略测试交叉核对。无真实省网可选夹具,地区过滤和历史缺失项由组件测试覆盖;不冒充端到端投递或真实权限异常验收。仅本地提交,不推送、不部署测试或预生产。
## 2026-09-06 发送监控与报备状态消息实施(发布前)
- 范围:按用户授权修改、提交、推送、部署测试环境;本轮不访问或发布预生产。阈值及最低样本量默认留空、不告警,后续由用户配置。
- 起点:main/HEAD=69e3d732026-09-06 19:15回读origin/main=442dda711d5c9f778f3f76fd6d8fd69f14414ce6,差异0/2。原有AGENTS、开发/测试/部署规范、用例/进度及未跟踪方案受保护,仅暂存本轮文件或追加节。
- 实现:三种周期监控、真实Gateway写出和回执接收时间、尝试/业务去重、独立有界投影Worker、成熟桶/边界统计、规则与纳管版本、告警生命周期、历史快照和短信样本范围;顶部预警中心及运行概况保留。通知采用事务触发器、零网过程记忆、企业小时聚合、个人版本已读,双端页面和运营提醒入口。
- 根因证据:现有submittedAt是等待供应商响应后的时间,不能冒充发包时间;matchedSubmitRecordId实际未写入,使用已匹配消息/通道/网关号,重号不可评估;上游实际RegisteredDelivery与客户要求的下游回执不同,分别保留。测试库时区Asia/Shanghai,新表/SQL显式UTC。
- 资料池只读结论:pending-query要求pendingReport=true;生成完成置false;组添加通道没有重新置true。实际41个pendingReport=false签名存在有效路由和通道组,不会仅因新增通道自动重新进入待生成池;尚待生成对象可以动态计算新目标,但不会自动创建资料文件。本轮未修改此业务规则。
- 验证:前端20套99项、API59套638项、Gateway全量Go测试及vet通过;真实PostgreSQL隔离事务20项通过(含5秒边界、初评/定稿、重复、缺时间/回执请求、历史纳管版本、签名和引流通知、UTC、回滚)。数据库夹具明确为从不入队的隔离样本,全部回滚;测试替身不作为真实业务验收。新增API单测初次类型声明失败,修正后全量通过;引流夹具初次误用按运营商三条,与真实唯一约束冲突,改为既有全通道报备模型后通过。
- 本地TypeScript、前后端构建通过;格式、Stylelint、CSS所有权/级联治理及15项门禁测试通过,CSS全部由页面所有者导入,未修改历史模块或加载顺序。按当前门禁机械格式化了本轮涉及的旧代码文件,未变更其其他业务逻辑。ESLint无错误,有既有/关联Hook和any警告;入口gzip108.71KiB低于250KiB,图表chunk保留既有提示。
- 测试机19:0519:08基线:旧部署442dda7;短信119509、近72小时尝试0、待匹配回执0;提交命令/结果Stream pending/lag均0;数据库约2363MB、连接13/100、根盘可用24GB。Gateway desired=6、connected=0是发布前既有状态,不宣称供应商链路通过。当前没有真实高峰/长短信负载;500TPS性能预算及故障演练尚未执行,不作容量承诺。
- 本次独立恢复点:/var/backups/cmpp-platform/20260906-sending-monitor-191302,含PostgreSQL custom dump、应用、环境/systemd/Nginx/Prometheus/fstab、Redis RDB、旧版本;pg_restore列表、tar可读性及SHA-256均通过。未执行实际恢复演练。
- 此节为发布前证据;提交、推送、测试发布、真实双端浏览器结果在后续发布节记录,不预先标记完成。
## 2026-09-06 发送监控首轮测试发布与界面收尾
- 457319e62716a3a4deab03796affaceee1f5fb85已提交并推送。首次GCM推送返回Failed to authenticate user;核对既有helper与origin后仅重试一次,同样的进程级GCM_INTERACTIVE=never/GIT_TERMINAL_PROMPT=0成功;远端精确回读、fetch后0/0。未改凭据、Git配置或Deploy Key,成功并不能证明已查明首次失败内部原因。
- 测试机2026-09-06 19:29完成两项迁移及版本切换。候选归档SHA-256=d2c6b6b9c3a156db0e213104afea7f73ed0f753feaf95733fbb739a50cf03883;服务器Node22.21.1/npm10.9.4/Go1.26.0独立构建,CSS归档门禁及构建通过。保留原目录/opt/cmpp-platform-previous-20260906-monitor-442dda7;日志沿用原目录,未重启或配置PostgreSQL/Redis/MinIO,安全代理二进制摘要与原版本相同。
- callback→Gateway→API→Worker依序启动,8项应用服务active;新Worker非root、NRestarts=0,检查点每5秒更新、complete=true、pendingReceipts=0。使用普通pg脚本核验timestamp无时区列时需在该核验进程指定TZ=UTC;Prisma适配器与Worker已有明确UTC处理,不能把临时脚本的本地解析偏移误判成数据偏移。
- 首轮真实浏览器:5个监控页签×3尺寸=15项通过,额外规则和通知页三尺寸/刷新通过,无页面异常。真实API规则、摘要、rows、overview均200(样本1139ms,低负载单次结果不等于性能P95验收),非法page=0返回400。规则API仍返回空集合,页面下限/最低样本空、启用未勾选。
- 临时通知验收使用两个已有企业下的新客户端用户,以及全新draft、无应用/无路由的QA签名和rejected引流;仅引用既有全国通道,不改变企业、余额和通道配置,不发送短信。真实报备任务触发器产生签名/引流各1事件;双端实际消息和详情三尺寸已显示,进一步已读/追加/隔离与清理在最终节记录。
- 界面收尾:运行概况去除重复主标题,状态记录改用既有Tabs;消息详情分页失败就地显示,重试先清错误,以请求序号忽略关闭后的迟到结果,防止标记已读尚未返回时关闭弹窗后又被重新打开。新增关闭期间异步返回的回归测试。前端20套100项通过,类型检查/构建及格式、ESLint、CSS门禁通过;TypeScript曾发现新测试的exact/.at不符合项目类型目标,已修正后复验。API/Gateway无新增改动,沿用638项与Go全量结果。
## 2026-09-06 发送监控与报备消息测试环境最终验收
- 功能提交457319e及界面修复247fee6均已推送;测试环境19:49:52部署标记为247fee6d6b4c4aa5abdfb86d34b379552a3a2fa3。后者只更新6份对应源文件/文档及独立构建的前端资源,不重启后端或短信服务。完整归档SHA-256为864b0b3e43110510fabac2d2c354ab2f503e541946f375cd2e99b5e3102dc2c2,前端恢复资产位于本次独立恢复点下frontend-247fee6。最终记录提交只同步文档和部署标记,功能代码仍为247fee6。
- 最终真实浏览器:行业通道、验证码、整体兜底、告警记录、运行概况5页签×1600×1000/1366×768/390×844,共15项通过;规则与通知页覆盖刷新、路由切换和窄屏。规则API返回空集合,下限和最低样本量留空、启用未勾选;人工中断规则保存请求后错误可见,100/90草稿保留,取消后未写入规则。故障注入仅验证前端失败状态,不冒充真实后端故障恢复。
- 通知真实正数验收:PostgreSQL触发器为新建且不可路由的QA签名/引流产生首批2事件;运营账号及所属客户端分别读到第2版。仅QA签名回零再恢复后新增事件,最终同企业同小时第4版包含签名3条、引流1条。双端均重新未读,各自标记后摘要归零,互不代替阅读;双端×三尺寸6项通过,顶部报备状态变化通知正确跳转readiness页签,页面和控制台异常均0。另一个企业访问小时详情404、伪造租户头403、客户端访问运营监控401、退出后匿名401;非法page=0为400。
- 首轮最终脚本在第二个客户端登录时抢读尚未加载的验证码,出现正则空值;增加等待真实验证码文字后整轮重跑通过。此前关闭弹窗迟到请求缺陷已由247fee6修复;不把脚本失败、旧截图或组件测试记作真实验收通过。
- 19:57清理两个临时客户端、QA签名/引流/报备任务、通知事件/状态/小时/已读行,并精确清除1个遗留QA客户端Redis会话和两端临时凭据文件;操作日志保留,持久codex_qa_admin按用户要求保留。Tenant/TenantAccount/SmsChannel逐行聚合摘要与验收前一致;短信119509、签名55、引流1;通知事件/小时0,规则0、行业纳管0。没有发送、补发、重投、重新入队短信,没有更改已有余额、客户或通道配置。
- 19:57:46最终8项应用服务均active/Result=success/NRestarts=0API/Gateway健康。监控检查点每5秒更新,complete=true、poolMax=2、pendingReceipts=0stderr为0字节,API/监控服务发布窗口warning以上journal为空。三个Stream pending/lag均0;命令last-delivered=1787806802603-0/entries-read=130918,结果1787806917609-0/191696,协议日志1787806802967-0/40472。Gateway desired6/connected0保持发布前基线,未擅自调整供应商连接配置。
- 线上主JS index-CcT-At79.js SHA-256=3efb6da4e5ec852c86930c0a09089d34940170f7e9cf9271ec2c1961e4a8068d;主CSS index-Oaoh-Ppy.css SHA-256=c42f481be579764585c3e993ed91d2ea4b3f3c297ccbfd866b0a3358a34d8a0ae;真实HTTP下载与已构建运行文件一致。自动检查最终前端20套100项、API59套638项、真实PG隔离事务20项、Go全量/vet、类型/构建/格式/样式/CSS治理等通过。
- 证据目录:本机%TEMP%/cmpp-monitor-20260906内browser-admin.json、browser-notification-again.json、monitor各页/规则/双端通知三尺寸截图及各验证日志;认证不进入报告。低负载只读API样本15~27ms,不能代替高峰P95。未执行真实短信投递、500TPS容量测试、长时间压力或实际备份恢复演练。预生产本轮未访问、未部署。资料池结论仍为调查:已经生成且pendingReport=false的对象不会因组新增通道自动重入池,未修改此规则。
## 2026-09-06 运行概况裁剪与监控配置500修复(发布前)
- 用户授权修改、提交、推送和测试发布,并追加测试告警数据;本轮不访问预生产。起始main/本地/远端/测试标记f059674,远端重新fetch后0/0。原8份修改文档、3份未跟踪文件保护;用例/进度只暂存本轮精确变更。
- 20:10只读诊断:测试API日志显示20:05:54及20:09:06的Prisma P2010/UnsupportedNativeDataType void,指向target事务锁;独立只读事务SELECT pg_advisory_xact_lock真实复现,无业务写入。规则保存也有同样写法。浏览器确认运行概况仍有三个最近列表,monitor响应含byStatus和三组recent字段,targets正常返回7项。
- 修复:两处仅用于加事务锁的$queryRaw改为$executeRaw,锁粒度、参数绑定、事务、版本和审计语义保留。删除运行概况三组表格及后端明细查询/响应;保留byStatus聚合与独立记录页面接口。uplink查询文件按现有格式门禁格式化并移除原拆分遗留的47项未使用导入,其他上行查询逻辑不变。无CSS/Gateway/数据库迁移或发送链路修改。
- 验证:前端20套100项、API60套639项,前后端TypeScript/构建、格式/ESLint及结构/安全/部署/包体门禁通过。真实服务+Prisma在独立qa_monitor_config随机schema执行12项:加入、重复版本冲突、并发移除、重新加入、非法参数/不存在通道、规则保存及并发、非法样本、审计失败双路径回滚;结束删除自己的临时schema,公共业务表写入0。旧方式只读复现P2010,修复后真实保存通过,弥补上一轮只验证规则空态和故障拦截的不足。
- 数据计划:按用户授权新增6条明确标注“测试演示”的历史告警(三种类型×已恢复/已关闭)及趋势快照,演示异常→恢复/关闭,阈值只在历史快照中,不填全局规则,不改余额/客户/通道配置,不发送短信。告警页面真实读取演示行只证明展示和交互,不替代自动采集/告警生命周期验收;发布后记录实际生成与浏览器证据。
## 2026-09-06 监控配置修复测试发布及演示数据验收
- 功能提交4c210723cdb133b62462079f14491e37c1b87ed0已提交并推送,测试机20:28:51切换完成;精确归档SHA-256=e8faa1840de8a12b257a3e0d44f4e843a7501c8b36cabc4da8a95565ba7a20e5898份运行源码逐字节与归档一致。最终追加记录提交仅同步文档与标记,不改变功能代码。本轮不访问预生产,原有工作区文档和未跟踪文件未夹带提交。
- 本次独立恢复点/var/backups/cmpp-platform/20260906-monitor-config-fix-2025PG custom dump及目录清单、原应用、环境/systemd/Nginx/Prometheus/fstab、Redis RDB、旧标记与SHA256SUMS均验证通过;额外保留previous-api-dist和previous-frontend-dist。首个pg_dump因Prisma URL的schema查询参数被libpq拒绝,在写业务状态前停止;改为内存解析URL、通过PGHOST/PGPORT/PGUSER/PGPASSWORD/PGDATABASE传给pg_dump,重新备份及校验通过,密码不输出。未实际演练恢复。
- 候选使用精确提交、复用未变化锁文件对应的现有依赖,在独立目录运行前后端构建、Stylelint、CSS归档治理、bundle门禁,以及真实Prisma配置12项复验后发布。仅重启APIGateway PID444741、Send Worker PID444772、监控Worker PID444958保持;12项应用/存储/Nginx服务active。API重启后无新增warning以上journal,文件日志最后一条异常仍是发布前20:09:06的P2010,保留历史错误,不宣称旧日志为空。
- 真实Edge浏览器1600×1000、1366×768、390×844:运行概况进入/刷新无最近短信/状态报告/上行,真实响应仅byStatus,状态卡片与通道列表保留;行业监控通过界面加入/移除均200,刷新后仍已纳管,同旧版本提交409,非法enabled400、不存在通道404。用业务已停用的“本地电信备副本”验收,只改监控配置,结束恢复未纳管;当前version8,8条历史版本和审计保留,未改SmsChannel。首轮脚本误用原生selectOption操作自研Select,已改为真实按钮/option交互后整轮通过。
- 用户授权的告警数据:真实PG新增6条历史告警(三类×已恢复/已关闭)和36个初始趋势快照,名称均含【测试演示】,维度/记录ID前缀qa-monitor-demo-20260906,不对应真实发送对象。历史指标包含异常→恢复及异常→停用关闭,演示阈值只嵌入快照;业务SendingMonitorRule仍0。运行Worker可按现有逻辑追加无发送快照,不伪造短信/投影事实。数据按用户要求保留,日后清理须核对该前缀下的演示告警、快照、已读和检查点,不扩大到业务数据。
- 告警真实API总数6,恢复/关闭筛选各3;三尺寸列表和详情、6点历史曲线通过,console error/pageerror均0,无整页横向溢出。截图复核监控通道窄屏及告警详情清晰可操作。人工造数只证明真实API/数据库展示,不冒充自然产生的监控告警或真实投递验收。动态业务/规则/余额/通道表摘要造数前后一致,短信仍119509;未发送、补发、重投、重新入队短信。
- 最终前端100项、API639项、真实Prisma配置12项、类型/构建/格式/ESLint/结构/安全/部署门禁通过;未修改CSS或Gateway,不重跑无关Go链路测试。线上主JS index-UxUuzIeW.js摘要3da1b28cfa2997d2d93e374fdd5a575ed629814d6ce33a32bd7b1d0f2b68329f,主CSS仍index-Oaoh-Ppy.cssHTTP下载与运行产物一致。队列三个Stream pending/lag均0last-delivered和entries-read与上一轮基线相同;监控水位complete=true、pendingReceipts0。
- 证据目录:本机%TEMP%/cmpp-monitor-fix-20260906的before.json、after.json、runtime/joined/alerts/alert-detail三尺寸截图、前后端测试/构建/质量日志及受限测试脚本;脚本内无认证秘密,持久管理员正常退出后保留。原规则空态正常不等于配置保存正常,本次以真实服务写入/并发/回滚验证补足覆盖。未执行短信发送、真实高峰压测或预生产验收。
## 2026-09-06 整体兜底规则管理改造(发布前)
- 用户授权按已确认方案实施、提交、推送及测试/预生产部署。起始main/HEAD/实时origin/main及两环境标记均0e3424c,分叉0/0;8份已有修改文档及3份未跟踪草稿保护。本轮文档只提交精确追加段落,不夹带原修改或上轮未提交发布记录。
- 只读证据:同版本测试页面选择企业后搜索结果仍为“请选择”,已选仅显示内部ID;通用、新增、编辑和继承混在同一表单。风控规则提供独立列表/新增应用覆盖及“企业·应用”选择,真实GET均200,测试规则0。原型和说明见sending-monitor-redesign-plan-20260906.md第13节;截图/请求在本机%TEMP%/cmpp-monitor-rule-review-20260906。
- 实现:整体兜底独立规则管理,通用/个性化页签、名称及阈值列表、搜索分页、新增三种覆盖、对象联动、重复检测与锁定编辑、继承预填、当前/待生效区分、字段校验、草稿保护和保存回列表。后端新增名称/对象分页/编辑上下文接口与恢复继承入口,沿用管理员权限、乐观锁、整套覆盖及周期版本。历史已删除企业/应用/签名不可新增配置,可恢复继承;签名软删除字段为auditStatus。无数据库迁移、Gateway/Worker计算或队列契约变更。
- 样式仅在MonitorRuleManager.css,由同目录所有者直接import,登记严格roots;未改公共Select、历史CSS模块或Stylelint例外。门禁首次提示新文件未登记所有者,补充css-ownership.json后通过,不重算历史摘要。
- 本地前端21套105项、API60套639项、前后端TypeScript/生产构建、增量格式/ESLint、Stylelint、CSS治理及其用例、安全/部署/包体门禁通过。首次辅助函数拆分漏导入及测试定位类型错误经类型/全量检查发现并修复,最终全量重跑通过。
- 测试机真实Prisma/service隔离schema15项通过:跨企业名称搜索、20+3分页、签名联动、非法查询、三种范围、重复范围版本、当前/待生效、继承优先级、停用保留覆盖、恢复并发409、软删除历史、审计失败回滚。使用全新隔离Tenant/Application/Signature样本,public业务写入0,结束精确删除自己的schema;未发送短信。脚本tools/testing/verify-monitor-rule-management-postgres.mjs可重复执行。
- 本机证据目录%TEMP%/cmpp-rule-manager-20260906保存原修改备份、前后端测试/构建/门禁日志。真实登录后页面及两环境发布尚待执行,不能用上述单测和隔离集成结论代替;预生产仍需现有有效管理员安全入口,不擅自重建或重置账号。
## 2026-09-06 整体兜底规则管理改造(发布验收)
- 功能提交e4f93f7193496a204efe4e753018a1c1ceb35742已推送;GCM首次Failed to authenticate user,核对既有Git/helper/origin后在同一进程设置GCM_INTERACTIVE=never、GIT_TERMINAL_PROMPT=0重试一次成功,ls-remote/fetch精确回读且分叉0/0。未改全局配置、清凭据或新增密钥;临时变量不是永久认证修复。最终工作区仍有其他会话的规范、部署、日志等改动和3份未跟踪草稿,全部保护;project-daily-log.md曾短暂显示删除后变为修改,非本轮操作。
- 从已提交归档生成907文件SHA256清单;测试与预生产候选逐项匹配、分别完成前后端构建、Stylelint/CSS归档治理及安全/部署/包体门禁。测试候选再次执行真实Prisma隔离schema15项通过,public业务写入0。与本地21套105项前端、60套639项API、类型/格式/ESLint检查共同构成本轮验证,不冒充发送链路或容量测试。
- 测试22:27:37、预生产22:34:24发布e4f93f7;仅API重启,测试API PID455184、预生产2378254,所有其他既有服务PID不变且active/NRestarts0。无迁移(仍98项)、无Gateway/Worker/存储配置变更。测试上游desired6/connected0与原基线相同,预生产6/6;不能把测试上游既有未连接写成已修复。
- 独立恢复点:测试/var/backups/cmpp-platform/rule-manager-20260906T222440;预生产/opt/cmpp-platform-backups/rule-manager-20260906T222419,经既有链接落到/data。PG custom dump/list、application/config归档、Redis RDB和SHA256SUMS全部校验;未执行实际恢复。预生产跨设备rename在运行dist切换前失败,已改用同文件系统/opt/cmpp-rule-manager-previous-e4f93f7保留旧前端/API dist,再切换成功;数据盘恢复包保持不动。未重启存储或修改fstab/UUID/drop-in。
- 真实Edge测试:1600×1000、1366×768、390×844的通用空态、个性化列表、企业应用远程名称搜索、行内校验、草稿退出取消/确认、刷新/路由切换及滚动可操作;无页面横向溢出、pageerror或非预期console error。签名覆盖、应用+签名覆盖的联动选项和编辑上下文真实200;新管理/选项/上下文匿名401,非法页码/不完整范围400。单独注入请求中断验证错误与重试,仅用于失败展示验收,正常业务均为真实API/PG。
- 测试UI真实新增停用的应用覆盖v1,重复范围进入编辑且锁定对象;另一真实API保存产生v2后,旧表单保存409且保留输入,明确重新加载后更新v3;名称/类型筛选保留,恢复继承预览提示无下层规则,确认产生v4且使用已持久化配置。仅创建该测试覆盖,始终enabled=false,最终deleted=true;规则b264df0c-35cf-467f-b908-1aec5aa93502及4条版本、操作审计保留,通用阈值仍空。未改应用/企业/签名配置,未启用告警或发送短信。早期脚本的截图URL转文件路径、错误标签和自研Select定位失败已修正后续跑通,不作为业务Bug或通过证据。
- 预生产通过用户提供的现有管理员正常登录,未创建/重置账号;三尺寸通用规则、个性化空列表、远程应用搜索、编辑上下文、取消返回和刷新验收通过。原有2条规则(验证码通用启用、整体通用已恢复继承)及3条版本保持,未带入测试规则/演示告警。首次公网浏览器出现ERR_CONNECTION_CLOSED;匿名连通性复核后以无代理Edge完成验收,未改服务器网络、TLS或安全设置,不能把该现象称认证失败或根因已定位。
- 最终基础设施:两环境主JS index-a_5GyNeX.js、公共runtime及主CSS HTTP200且摘要等于运行dist13项检查服务active(测试postgresql为aggregate单元,实际数据库查询正常)。测试短信119509/Submit130769/签名55/引流1;预生产87287/87428/179/11,企业/余额/通道/应用配置摘要与切换前一致。三个业务Stream pending/lag0、水位与此前只读基线一致:测试commands1787806802603-0/results1787806917609-0/protocol1787806802967-0;预生产commands1788690572448-2/results1788696610600-0/protocol1788696610646-0。初版临时巡检误用cmpp:*未匹配Stream,已按实际gateway.*重读;不以空对象证明队列正常。健康检查complete=true/pendingReceipts0/poolMax2Inbox无待处理、Outbox均publishedAPI本次启动后journal无error。
- 本机证据%TEMP%/cmpp-rule-manager-20260906test-browser.json/test-writes.json/test-extra.json/preprod-browser.json、三尺寸截图、测试/构建日志;服务器恢复点保存before/immediate-before/after及release-*日志、最终infra与精确文件清单。浏览器账号凭据未入库/文档,验收会话退出;预生产验收只读,测试保存链路已恢复继承。未执行真实发送、高峰压测、实际数据恢复或预生产规则写入。
## 2026-09-07 WPS损坏图片与相邻节点误配修复(本地提交)
- 本轮授权修改并本地提交,不推送、不部署、不重新导入/审核资料。起始main/HEAD/实时origin/main为f885f0b,暂存空;9份已有文档修改、3份未跟踪文件继续保护,仅精确追加本节及对应测试用例。
- 前一轮只读诊断已定位预生产最近5次失败均为05_生活缴费_原行169-192.xlsx不同保存版本,停在35%。MinIO读取字节数与FileObject大小一致。最新文件生活缴费N7(身份证列)对应cellImage无blip;之前版本为N174。原跨节点正则将后一有效图片rId11配给损坏ID,实际M2/M169正常图片被误报。邻近04文件78张图片可解析。原文件SHA256为9d58d535f858960df5c03673b9c4bba8c292761c4b84c1bc8ea3cfe68d3962cf。不是仅修代码就能补回身份证图片。
- 修复仅涉及workbook-compatibility.ts:单节点边界读取、未引用残留可忽略、被引用损坏仍拒绝;重复图片ID/关系不再静默覆盖,External图片关系不接受;错误给出工作表及具体单元格;自闭合空单元格不能吞掉后一单元格公式。公式白名单、图片字节校验、分析/提交资源限制、数据库/队列/审核和权限流程保持,无前端/CSS/依赖/schema修改。
- 新增14项回归,含metadata/字节两模式×未引用残留及自闭合单元格、实际损坏位置、重复图片ID、媒体缺失、关系缺失/重复/外部。定向17项通过;API全量60套653项通过(测试中的Redis/Prometheus不可用warning来自既有隔离场景)。API生产配置TypeScript/构建、增量Prettier/ESLint与diff检查通过。曾误用基础tsconfig执行含测试文件的全量tsc,因该配置未加载Jest全局类型失败;改按仓库tsconfig.build.json核验生产代码,测试文件由完整ts-jest回归校验,未为此改动既有类型配置。
- 当前修复代码在本机读取此前只读取得的真实原始文件:两种模式均准确拒绝N7;只在内存清空N7公式、保留损坏cellImage节点后,两模式读取33张图片且不串位。独立Python ElementTree解析原始OOXML建立期望位置/图片SHA256,字节模式33张全部逐一匹配;原始文件摘要不变,未生成或上传替换业务表格。
- 证据在本机%TEMP%/cmpp-wps-diagnosis-20260907api-full.log、independent-image-hashes.json、real-file-verification.json及受控原始文件。真实客户文件不进入Git。此前浏览器只读状态核验尝试登录返回401,未取得该项浏览器证据;本轮未复试、重置账号或修改服务器。已依据PG持久失败记录、真实MinIO文件、运行解析器与本地修复解析结果完成复现/回归;新版本的线上API/Worker/浏览器验收待另行授权部署后执行,不将本地文件回归称为线上导入成功。
## 2026-09-07 夜间累计发送量审核(实现与发布前验证)
- 用户授权实施、提交、推送和测试/预生产发布,并要求复用短信审核。起始main为e281ff8,实时origin/main为f885f0b,暂存空;9份原文档修改及3份未跟踪草稿保护,仅提交本轮精确追加文档。发布同时包含此前本地WPS修复e281ff8。
- 只读根因:旧规则只对category=marketing/promo/promotion/营销的单任务号码数判断;CMPP单号码评估和批量快速入队没有跨请求夜间计数。已有短信审核提供CMPP模板不匹配同内容10秒聚合、号码列表/详情/批量操作,适合复用。测试和预生产现场版本均f885f0b;夜间规则均通用5000启用,无个性化覆盖,现场本夜首次Submit均0。测试119509条消息/130769次Submit;预生产本轮基线93243/91563、签名653,不能沿用昨天的旧数字。
- 实现:两张夜间计数/幂等表、审核续发租约字段及兼容迁移;所有业务入口在共享发送Worker首次提交前执行应用级夜间门禁,跨午夜连续,第5001条起挂起,保持分片/重试/幂等业务计数。首次初始化从持久首次Submit补齐历史;新增审核记录按应用、原始相同内容、10秒窗口聚合并复用现有UI。审核批准只释放已锁定任务,持久续发记录和15秒扫描恢复入队失败,稳定新jobId避免旧已完成任务吞掉续发。数据库故障向上抛出,不能当路由失败或默认放行。
- 规则沿用既有编码/ID和历史记录,改名并去除旧营销计算;应用覆盖/停用回落、强制人工审核、整数阈值、北京时间与夜间时段延期生效。UI只修改口径、说明及审核来源标签,无CSS/Gateway/依赖/余额/通道/客户配置调整。触及的既有文件按现行Prettier门禁规范化,并清理历史拆分遗留的未使用导入及等价控制字符判断;未扩大lint例外。
- 本机后端62套665项、前端21套105项回归通过;新夜间单元与发送门禁12项通过,生产类型和构建通过。测试机独立候选、真实PG双实例并发/隔离/午夜/幂等/覆盖/历史初始化/事务回滚及独立Redis审核恢复11组通过;public消息/Submit计数不变,Gateway调用0、业务队列写入0。固定时间在隔离service层注入,不构造真实短信。
- 现场真实测试页面三尺寸基线读取规则、编辑取消、短信审核空态/刷新通过,API200、无新增控制台错误,未保存线上业务规则。测试机初期Tailscale离线超时,用户恢复后正常密码认证;不是Git认证问题,未修改SSH配置。当前浏览器技能未提供,按frontend-testing-debugging技能和既有任意浏览器授权使用Playwright/Edge。临时脚本初次将Windows路径URL编码未还原导致截图失败,修正fileURLToPath后通过;隔离验证先修正模板变量表名与BullMQ优先队列计数口径后重跑通过,不作为业务缺陷。
- 本机证据%TEMP%/cmpp-night-risk-20260907,测试候选/opt/cmpp-night-candidate-20260907PG/Redis隔离结果/tmp/night-pg-verification.log。最终门禁及发布后真实页面/服务/队列验收另记下节;尚未执行真实短信发送、供应商压测或实际备份恢复。
## 2026-09-07 23:0823:26 夜间累计审核双环境发布验收
- 功能提交633ba597754c1b89943ea3a819f45042f41b019a已推送,回读origin/main一致、分叉0/0。首次GCM返回Failed to authenticate user,核对既有配置后,在相同GCM_INTERACTIVE=never、GIT_TERMINAL_PROMPT=0进程设置下仅重试一次成功;不据此认定已永久修复,不改凭据或全局配置。测试机Tailscale恢复后SSH可用。
- 两环境发布精确提交归档SHA256=b1c06c22b3e4f30d3389036b59a9c28dc34c1d236a66dd086ced7d495287cdd7912份已跟踪源文件逐项一致,包含此前WPS修复。独立候选生成Prisma Client、前后端类型/生产构建及Stylelint、CSS归档治理、安全、部署和包体门禁通过;两机分别重跑真实PG双连接池与独立Redis的11组隔离测试,public数量不变、无业务队列/Gateway写入。此前本机API665项、前端105项和CSS治理15项结果沿用,不冒充再次全量执行。
- 测试23:08:23、预生产23:11:59完成切换,均应用20260907143000_night_sending_risk迁移,完成迁移总数99.deployed-commit均633ba597754c1b89943ea3a819f45042f41b019a。仅API、发送Worker和报备解析Worker重启;保留原Gateway、安全代理二进制及旧哈希前端资源,摘要逐一一致,未重启Gateway/callback/监控/存储/Nginx。验收文档另作后续提交,不因此变更已验收功能版本或重启服务。
- 独立恢复点:测试/var/backups/cmpp-platform/night-risk-20260907T230742,预生产/opt/cmpp-platform-backups/night-risk-20260907T231021(既有受保护数据盘入口)。application.tgz、config.tgz、PG custom dump及目录、Redis RDB、SHA256SUMS验证通过;旧执行资产分别保留/opt/cmpp-night-previous-20260907T230742、/opt/cmpp-night-previous-20260907T231021。未实际恢复,应用回退不能撤销新增审核/计数数据。
- 发布脚本问题:测试备份最初因Prisma URL schema参数、继而PGDATABASE URI未作为连接串解析而失败,均发生于停止服务/迁移前;最终解析为PGHOST/PGPORT/PGUSER/PGPASSWORD/PGDATABASE进程变量成功。预生产cp -an对已有文件返回非零,在前端目录复制后中止;核对API旧资产已移动、候选/备份完整后,仅续接剩余复制、启动、验证步骤,未重复迁移。后续应使用显式文件存在判断保留旧资源,不能假设cp -n跨版本退出码一致或用忽略所有错误掩盖真实失败。
- 数据与服务:测试消息119509/Submit130769/签名55/引流1,预生产93243/91563/653/11,均与本次备份前数量一致;企业/应用/通道摘要不变。预生产余额摘要有一项差异,逐行核对备份与AccountTransaction确认旧短信于15:10:50 UTC最终失败自动退款760分;该短信08:18:35 UTC已入队,发生于新API启动前,非本轮手工余额操作。夜间窗口/预留均0,未造真实发送。三个业务Stream均pending=0、lag=0;预生产实际回执推进水位,不能称所有水位未变。13项预生产服务active,受影响服务NRestarts=0fstab/UUID/存储脚本/drop-in摘要一致,保护检查通过。
- 真实页面:测试与预生产均使用真实管理员、API及PG数据,1600×1000、1366×768、390×844检查规则读取、阈值5000、北京时间21:00–08:00、人工审核动作锁定、编辑取消、短信审核空态、刷新和路由切换;无整页横向溢出,相关GET均200,未保存业务规则。预生产Codex_admin最初停用/删除,用户23:16:06恢复后原凭据可登录,前两轮三尺寸业务GET均200且检查完成,仅static.cloudflareinsights.com统计beacon出现连接重置;第三轮23:21:57登录后,23:22:21发生user.disabled操作,最后回读401。23:24再试仍停用,PG确认status=disabled、sessionVersion=2;未新建、启用或重置账号。保留已完成页面证据,最终完整零异常脚本未通过,不声称持续登录可用或整个控制台零错误。
- 现存独立问题:测试安全代理发布前已因/run/cmpp-security-agent缺失反复启动失败(226/NAMESPACE),未扩大本轮修改;预生产ReportsService日报刷新在发布前21:34、22:34及发布后23:12仍出现5000ms事务超时,发送/报备Worker没有本轮新增错误,不能称所有应用日志正常。两项留待专项诊断,不影响已执行的夜间规则只读及隔离验收。
- 证据:本机%TEMP%/cmpp-night-risk-20260907的测试/构建日志、两环境三尺寸截图、测试browser.json及预生产browser-observations.json/最后一次browser-failed.json;两机独立恢复目录before/after、verification.json、migrate.log、services及storage摘要,预生产account-compare.json。未发送/补发/重投/重新入队真实短信,未执行真实供应商高并发或实际备份恢复;线上审核当前为空,同内容审核/续发恢复由真实PG和隔离Redis验证,不能冒充真实短信审核放行。
## 2026-09-08 运营修复实施与本地验证(测试部署前)
本轮授权为格式化器修复及六项运营需求、本地提交、测试部署;未授权推送或预生产发布,不处理导入导出优化。开始基线main 50ae372,保留发布工具、部署文档、metrics及更早脏文件,只纳入本轮精确文件或文档追加hunk。
根因:热力图每行多次新建Intl.DateTimeFormat,独立进程39756次调用RSS约55MB至1169MB;复用格式化器对照约55MB至63MB。阈值保存日志明确为spawn /usr/bin/promtool ENOENT,而官方安装目录为/usr/local/bin。消息旧按检测维度生成,现新增每日应用唯一键;筛选旧标签将内部历史状态重复呈现。
已实现规则见operations-fixes-20260908.md。API全量64套674项通过;前端23文件108项通过(--maxWorkers=2;首次高并发运行出现4项超时,未放宽断言,限定并发重跑通过)。API构建、前端生产构建、安全/部署/包体检查通过;CSS新增页面归属已登记。真实测试API连接本地候选UI检查四Tab日期独立、创建弹窗遮罩/Escape及关闭、三个视口无水平溢出,控制台无错误;截图尚需部署后等待指标完成加载再验收。
待执行:精确提交归档验证、真实PG隔离并发与规模测试、标准测试部署、线上阈值保存恢复及三视口浏览器验收。测试过程不发短信、不创建真实通道或客户配置、不触发外部Webhook;未完成项目不能视为上线通过。
## 2026-09-08 13:39 运营修复测试环境验收完成
- 本地业务提交2c228a94e13b628447720c24bed45fb169acca6f,测试环境已部署该精确版本;没有推送或预生产部署。历史预警不重写,当日旧版本已生成消息不重复生成,后续新预警按每日企业应用唯一消息。
- 精确提交归档:前端23文件108项、API64套673项全量通过,类型/格式/lint/样式/CSS检查通过。工作区先前674项含1项未提交metrics测试,未夹带到发布包。候选生产构建、安全、部署、包体检查通过;2个exhaustive-deps warning(无lint error)保留记录。
- 真实PostgreSQL隔离schema cmpp_fix_20260908_1788844913115:两个服务实例并发,5条检测归为4条应用/企业消息;重复执行0新增;非代表签名搜索、按消息分页/未读、整组事务抑制通过。该schema保留审计;业务public表未造测试配置,未启动检测/发送/Webhook生命周期。
- 实际heatmap服务处理19788条PG检测耗534msRSS253353984→305582080字节,增长49.81MiB;仅隔离进程GC后302989312字节。相同调用规模的旧表达式此前独立进程增长约1.06GiB,此次不是单凭服务重启判断效果。正式测试API发布前RSS约417MiB;发布后同一PID101308经多轮页面查询约230262MiB(观察至13:39),未进行长时/并发导入验收,导入导出优化未实施。
- Edge真实测试API浏览器:1600×1000、1366×768、390×844;首页10项数据真实加载、无水平溢出;4Tab独立日期及10/25/50/100选项,100条服务端回读;刷新/路由切换、创建弹窗遮罩/Escape不关闭及按钮关闭、报备状态唯一项通过。窄屏截图等待侧栏过渡结束后复核;脚本异常与console error均0。Browser插件不可用,按frontend-testing-debugging规范使用本机Playwright/Edge。
- 真实报备API共258条,全部历史exporting;按reporting或exporting筛选均返回258条,证明合并标签不丢历史记录。failed/rejected实际样本为0,对应查询均0,失败历史状态真实非空样本未覆盖。
- 阈值真实页面85→84,版本3→4且effective;再恢复85,版本5/effectiveVersion5。PG只读回查hostMemory={warning:85,critical:95}Prometheus实际规则85/95且health=ok。public短信记录全程119509,完成迁移99→100。
- 标准release发布编号20260908T052302-2c228a94e13b-2c6dd8a1plan→精确提交已执行validation证据→preflight→prepare→deploy→verify通过,verificationWarnings为空。独立恢复资产/var/backups/cmpp-platform/20260908T052302-2c228a94e13b-2c6dd8a1-attempt-1788845221951986051;备份可读和摘要已检,不代表实际恢复演练。旧候选及旧依赖均保留。
- 首次使用标准工具暴露并修复:测试sudo交互掩码输入、归档EOL绑定兼容现有CRLF、前端worker上限2、vendor链接以整个应用目录为边界(仍拒绝外部目标)。Windows31项29过2平台跳过,测试机Linux31项全部通过。工具及其原有第一期文档仍在受保护未提交集合中,未将前一会话整批工具夹带提交;实际工具摘要绑定发布计划。
- 原保护项AGENTS.md、metrics两文件、package.json、三份部署脚本的diff与开工快照相同。相关需求/设计/测试用例已同步;本轮验收文档另做精确增量提交。证据:本机.local-data/releases/上述编号/以及%TEMP%/cmpp-fixes-20260908/browser-acceptance.json、threshold-browser.log、status-api.log及deployed截图)。自动发布报告不自动导入人工业务结果,人工验收见同目录business-acceptance.md与本节。
- 未执行:预生产发布、Git推送、真实短信发送/重投、外部Webhook发送(测试机配置0个)、次日定时自然触发、长时导入压力与实际备份恢复演练。已有每小时日报事务超时线索另案保留,不在本轮六项及格式化器修复范围。
## 2026-09-08 14:49 分页交互修复与提交前验收
- 授权:两项分页修复并本地提交,不推送、不部署。开工main/HEAD为6d3c783;只读ls-remote确认远端main为50ae372,本地领先2提交、暂存为空。发布工具、metrics和既有文档等修改继续保护;相关脏文档只提交本轮追加内容。
- 需求/设计:[需求分页补充](first-version-development-requirements.md#2026-09-08-分页交互补充)、[运营修复分页补充](operations-fixes-20260908.md#分页交互补充2026-09-08)、用例OPS-PAGE0908-0105。没有后端、端口、CSS或数据库结构变更。
- 只读复现:真实测试页面质量Tab容量控件位于page-actionsGET /api/admin/report-details返回pageSize=10、total=294、10行且页面无容量选择。当前代码同样固定10。新增deferred回归还明确复现旧25条请求晚返回覆盖100条新列表(修复前失败),据此加请求序号/卸载失效保护,当前错误继续显示。
- 实现:四个质量Tab的容量Select与各自底部分页合并,空结果保留选择;报备明细默认25且支持10/25/50/100,改容量回首页、清空勾选、保留已应用筛选。公共Pagination新props可选,旧消费者不出现额外下拉;以独立输入组件按页码重置跳转草稿,消除既有effect触发的质量门禁错误。
- 代码验证:node node_modules/vitest/vitest.mjs run --maxWorkers=2,全量24文件118项通过;定向包括质量5项、报备工作台9项、公共分页3项。TypeScript --noEmit、Vite生产构建、changed-code格式与ESLint、结构检查、Stylelint、CSS治理及15项工具测试、安全/部署检查、包体门禁、git diff --check通过。当前环境npm不在PATH,直接执行package.json对应的已有Node CLI,未安装依赖。ESLint保留两个既有loadData依赖warning0 errorChart分包约181.65KiB gzip、入口106.42KiB gzip,包体门禁通过。
- 真实浏览器:Browser插件及其skill未提供,使用本机Playwright/Edge。最终生产构建本地127.0.0.1:4173临时预览代理到测试100.93.204.60:12026真实API;后端精确版本仍2c228a94e13b628447720c24bed45fb169acca6fcmpp-api active、Redis PONG。正常使用已有专用管理员登录并退出,无认证状态落盘。未修改测试运行产物或后端端口。
- 验收结果:四Tab底部容量、独立日期/容量保留、三视口1600×1000/1366×768/390×844下拉完整可操作、刷新和跨路由通过,页面无水平溢出,console/pageerror/HTTP业务错误均0。签名质量2026-08-20真实10个结果,四档均返回完整10行;未报备样本为空,四档空态可选且无越界。报备明细总294,四档分别返回10/25/50/100行,第二页请求容量正确,回25后回到第1页且勾选清空;按现有签名搜索命中6条,改容量后关键词/总数保留;无匹配词返回0且分页正常。原状态记录页面未新增下拉,真实页码跳转仍有效。
- 验收脚本问题与边界:独立Vite开发服务器曾出现本机连接超时,改用同一验收进程创建/关闭生产预览后通过;一次脚本假定Escape关闭Select导致等待超时,按当前触发按钮关闭方式修正后全流程通过,未扩改Select。错误/乱序以隔离测试验证;未报备真实非空、热力图超过100个维度、全部旧分页消费者的逐页人工验收未覆盖。真实API数据来自现有服务及PostgreSQL查询;本轮不修改数据库,未另取得测试受限数据库配置作直接SQL对账。
- 证据位于%TEMP%/cmpp-pagination-20260908before-quality/report截图、acceptance.json、filter-acceptance.json、三视口截图、frontend-tests.log、build.log、format.log、lint.log和开工diff快照。截图/脚本/凭据不进入提交。临时预览已关闭。
- 交付边界:本地代码、需求、设计和用例完成;本节随本轮精确文件/追加hunk作本地提交,提交号见Git记录。不推送、不测试部署、不预生产部署;不发送/补发/重投/入队短信,不变更余额、通道、客户配置或恢复管理员。测试环境仍运行旧2c228a9,本地提交不等于已上线。
## 2026-09-08 17:14 日报生成超时修复与本地提交前验收
- 授权:修改代码并本地提交,不推送、不测试部署、不预生产部署、不补跑历史报表。开工 main/HEAD 为 2a9d03be2edc06dbd9a494e971e6b04a8336619f,暂存空;只读 ls-remote 回读远端 main 为 50ae37242bc33acf1038fb62618fc4cd95409956,本地领先 3 提交。17 个已有脏跟踪文件及原未跟踪发布工具/诊断脚本继续保护;涉及三份旧脏文档仅追加并精确暂存本轮增量。
- 需求/设计:[可靠性补充](first-version-development-requirements.md#2026-09-08-报表生成可靠性补充)、[日报生成超时修复](report-generation-reliability-20260908.md)TC-DAILY-0908-0109。明确单日期三类报表原子事务、T-4~T-1 和既有财务口径,历史缺口不自动扩窗。
- 根因证据:预生产 633ba597754c1b89943ea3a819f45042f41b019a 三类表最新 reportDate 均为 9 月 2 日;9 月 3~7 日源短信非空。保留日志 93 次事务超时,9 月 8 日 16:12 的上限 5000ms、实际 7510ms。成本 CTE 扫全部 accepted 历史提交,单条 SELECT 实测 9090.976ms 已超过整日报表事务预算。
- 实现:应用成本 CTE 按原短信 queuedAt 限定日期,保留全部跨日提交的成功分片成本;日事务默认 30000ms、maxWait 5000msREPORT_REFRESH_TRANSACTION_TIMEOUT_MS 正整数覆盖且最大 120000ms,并设置事务局部 statement_timeout。删除前获取 PostgreSQL 日期 advisory lock;单日失败保留旧报表并继续其他日期,最终汇总抛错,只有全成功才标记本日完成。启动/周期定时器销毁清理,调度日与窗口共用同一时刻。未新增迁移/API 写入口/历史重算队列。两份已修改 TS 按当前 Prettier 门禁格式化,并显式忽略原 refundCents 解构值以修复该文件既有 lint 错误,列表/CSV 语义不变。
- 预生产只读结果一致性:在同一 REPEATABLE READ READ ONLY 事务中、statement_timeout=15000ms9 月 4 日原 SELECT 8919ms、当前候选 SELECT 100ms;两行全部结果列(含金额,按数组避免同名列丢失)摘要均为 576592fc45b7f3137882229321eaf905d1e9bba12631ccfe1a0b2016c759231b。仅移除 INSERT 头部执行 SELECT,防写入检查通过;事务最终 ROLLBACK,不调用线上生成服务。这是单日查询对照,缓存可能影响耗时,不宣称完整任务同比提速或全日期金额对账已完成。
- 代码验收:API 全量 64 套 694 项通过(工作区包含原保护 metrics 的 1 项额外测试,未夹带提交);最终报表定向 1 套 29 项通过。API TypeScript 生产构建、前端 TypeScript(既有 lint 组成)、changed-code Prettier/ESLint、结构检查、Stylelint、CSS 治理及 15 项工具测试、安全/部署静态门禁、git diff --check 通过。npm 当前不在 PATH,执行 package.json 对应 Node CLI;未安装依赖。API 命令为 node node_modules/jest/bin/jest.js --runInBand、node node_modules/typescript/bin/tsc -p tsconfig.build.json。
- 真实数据库/API:新增 tools/testing/verify-report-refresh.mjs,强制独立 REPORT_TEST_DATABASE_URL、loopback 地址及 cmpp_report_test_ 数据库前缀,不使用业务 DATABASE_URL。独立本机 PostgreSQL 8 组通过:7 个报表维度与完整自然日、跨日补发/审计优先/历史兼容、重复幂等、真实 SQL 失败三表回滚且后续日期成功、跨连接日期锁、超过旧 5 秒的成功事务、200ms 限额超时回滚恢复、真实 ReportsController HTTP 筛选/分页/汇总及三类 CSV。10 条消息/10 次提交的应用 9 月 4 日收入 4000、成本 800、利润 3200(0.0001 元整数单位)一致;单次注入 5.2 秒延迟后单日事务实际 5248ms 成功。金额源列采用生产 bigint,报表表完整列/类型/唯一约束,源表只建查询用列,未做全库迁移验收。测试 schema 残留 0,临时 PostgreSQL 已停止;测试资料目录保留。
- 证据:%TEMP%/cmpp-report-fix-20260908/{baseline.json,api-tests.log,report-tests-final.log}%TEMP%/cmpp-report-diagnosis-20260908/{profile-select.cjs.result.jsonl,compare-candidate.cjs.result.jsonl}%TEMP%/cmpp-report-pg-1788858316792/integration.log。脚本、源库结果未输出凭据或短信正文。
- 未执行:预生产完整任务写入验收/自然定时观察、两环境部署、历史缺口补齐、完整应用登录与浏览器。本轮无前端改动;本地 HTTP 是独立真实报表 Controller/Service/PG,不代表完整认证/UI 验收。旧 api/tools/verify-report-recalculation.ts 含过期金额断言和业务造数,不执行也不在本轮改写。T-5 更早缺口仍须部署修复后单独授权补齐。
- 交付:本地报表代码、测试工具、需求/设计/用例和本节一起按精确 7 文件/文档增量提交,提交号以 Git 为准;未推送、未测试部署、未预生产部署、未短信发送/补发/重投/入队,未修改业务余额、通道、客户配置或管理员。提交前保护校验确认全部已有跟踪修改未被覆盖。
## 2026-09-08 夜:浏览器异常、顶栏连接失败与公共分页(进行中)
- 本轮授权:修改、本地提交、发布测试环境;预生产只读诊断。开始分支mainHEAD/origin均ebb185b22b4457a3b5ed1c9bcc6c45992a3e7f21,分叉0/0staged为空。19个既有tracked脏文件及release工具/诊断等untracked逐文件备份并保护,不能纳入本轮提交。两环境当前部署标记均ebb185b。
- 已完成只读归因:公共Select可见label造成“每页数量”换行;DevTools异常与官方#792的函数名及偏移一致,用户反馈另一台Chrome152.0.7977.77 F12 Console;后续脚本捕获见下文,不把业务代码改动当成浏览器内置脚本修复。
- 网络证据:2026-09-08 21:0521:13源站API/Nginx稳定,API NRestarts0、无新OOM36次公网H1/H2匿名六接口请求均401,无关闭、GOAWAY或5xx;Nginx没有限流/上游超时证据。历史另一台电脑ERR_CONNECTION_CLOSED未复现,实际关闭层尚未确定。确定应用存在整批刷新叠加和失败清零缺陷,按operations-fixes-20260908.md本轮设计做最小修复。
- 本轮证据目录:本机TEMP/cmpp-starttime-pagination-20260908(基线保护/本轮证据),TEMP/cmpp-notification-network-20260908(只读链路采样及findings.md)。不写入认证状态或客户记录。后续追加测试、提交和标准测试发布结果。
- 深入浏览器证据:临时Chrome152.0.7977.76捕获DevTools Performance Metrics匿名脚本,首行softnav=true,第2行19429列确为`t.entries[0].startTime`SHA256 0f2eb3b63431416befd0d826255fb1736117e0ddbca120c5c3e54aca03a1810d。官方修复6a47f933(2026-08-31/Chromium543499029)明确修正空entries;已在隔离浏览器F1标准设置取消软导航并刷新,脚本前缀变false,A/B均无pageerror。仅证明来源/直接缺陷及开关控制,未在另一台电脑复现;不改用户浏览器配置。证据TEMP/cmpp-devtools-headless-20260908/ab-valid。
- 用户本机侧边浏览器已登录预生产,已读到真实运营看板与通知菜单,当前dev日志error/warn为0。进一步跨路由CUA调用发生工具超时及kernel reset,不当作应用错误或通过。预生产本轮未发布。
- 21:32追加排查安全误封:20:00后仅1次管理员登录失败,无新增安全告警/封禁;当前nft IPv4/IPv6封禁集合为空、Nginx deny记录0,安全代理及Fail2ban active且NRestarts0。Nginx信任22个网络并使用CF-Connecting-IP/real_ip_recursive,两观测Cloudflare地址均在信任范围,API只信任loopback;没有错误来源识别或安全误封依据,不调整安全策略。
- 本地实现完成:分页2文件、通知布局/调度/API透传共8文件,所有业务调用仍为原六GET。通知定向18项通过;分页与关联页面18项通过。全量前端25文件132项通过(21:36:08,45.74秒)。首轮类型检查抓到分页测试误用了Playwright的exact参数,已删除两处不属于Testing Library的参数,字符串名称仍默认精确匹配,分页4项重跑通过;随后完整lint(含TypeScript/结构/CSS)、format:check、生产build、bundle:verify、security:verify、deploy:verify均通过,git diff --check通过。未修改后端、数据库、Gateway或CSS,无本轮API/Go测试需求;真实页面待测试发布后验收。
- 独立代码复审无阻断:覆盖单批/退避/超时部分成功、隐藏离线/锁定/卸载/身份失效和StrictMode。首次未知保留现有数字占位,但明确显示加载/未取得结果;六类失败均保留既有真实计数,不伪装正常零。实际signal→fetch测试使用测试隔离,单独标记,不当作业务验收。质量证据quality-results.json及各-final.log保存于本轮TEMP目录。
## 2026-09-08 22:03 标准 prepare 前端候选依赖修复与授权更新
- 现场阻断:测试发布 20260908T134432-6816f5617819-b92bbb04 的前端候选只执行根 npm cisecurity:verify 通过 createRequire(api/package.json) 校验 API brace-expansion 适配器时缺少本地依赖而向上解析错误版本。主线程先用标准 status 取得 phase=prepare、backup=null;没有备份、停服或切换,原失败候选保留。
- 最小修复:tools/release/remote.py 仅将候选 API npm ci 移入 frontend 或 api 条件;显式 Prisma 生成、API 构建和线上 API 产物/依赖切换仍只在 api 影响范围内执行。没有修改 security:verify、跳过门禁、手工修补线上依赖或替换标准编排。tools/release/test_release.py 仅追加 Preparation 的 4 项回归,两工具文件保留原未跟踪状态,未暂存、未提交整套既有第一期工具。
- 先失败后修复:新增测试在旧实现上复现前端候选缺 API 依赖及安装失败场景断言失败;修复后 Windows 标准 self-test 共 35 项,33 通过、2 项分别因符号链接权限与 Linux flock 限制跳过。测试以真实临时 tar、文件摘要和目录切换核验前端部署不改变线上 API 目录,不调用服务命令;受控命令替身只用于隔离失败场景。
- Linux 隔离验证于 22:00:38 返回 exitCode=035/35 通过,临时夹具残留 0Linux 日志 SHA-256 已回读核验为 77106f006cf22ea33c3b744c9c7cbf43d3885b32f4c6d71d8d00b49b1578e900。本地 dependency mitigation、security deployment、deploy verifier 通过;两 Python 文件解析和尾随空白检查通过。未修改 JS/Shell,因此未把未执行的对应语法或格式检查记为通过。
- 证据:%TEMP%/cmpp-starttime-pagination-20260908/release-prepare-before.log、release-prepare-after.log、release-prepare-fix.patch、release-linux-unit/result.json、release-linux-unit/linux-unittest.log。用例 REL-PREP0908-01~04 已追加,候选安装与线上切换边界同步部署/工具设计文档。工具摘要变化使旧计划失效,后续使用新计划、匹配精确提交的已执行验证证据和 fresh preflight;发布与业务验收另记,不以隔离测试冒充上线。
- 最新授权:用户已明确允许测试环境验收通过后推送本轮提交并部署预生产,取代本轮早先仅本地提交与测试部署的后续执行限制;此前文字继续保留为历史事实。记录时 6816f5617819546850b1188508eda37866f4ca3c 仅本地提交、未推送,预生产尚未执行本轮发布。授权不包含其他既有脏文件、短信发送/补发/重投/重新入队、余额/客户/通道配置或恢复管理员。
## 2026-09-08 22:35 测试前端开发运行时实证与构建模式修复
- 新证据纠正此前推断:只读下载测试实际 /assets/index-TLGANFcU.jsSHA-256 a8db74bfdb24ef0892ca77fee891297d492d07b979c8653d5fd7c86c186e080c,包含 19 处 react_stack_bottom_frame 和 2 处 jsx-dev-runtime。remote.prepare 统一 NODE_ENV=test;本地对应 Vite 以 NODE_ENV===production 决定 isProductionReact 插件沿用该值,确认发布过程实际产出了开发版 React,不能用“执行过 build”替代资源模式核验。
- 第三轮 browser/run-2026-09-08T14-27-36-420Z/fetch-diagnostics.ndjson 中 18 次 fetch-signal-abort 均可见在线,耗时约 3.114ms、reason=AbortError,全部经过 JS 225:176295 的通知 effect cleanup。146:26427 对应 commitPassiveUnmountEffectsInsideOfDeletedTree_begin146:25089 对应递归 passive unmount 遍历;不是 15 秒 TimeoutError,不是已逐项证实的 StrictMode 双 effect。确认存在开发包与布局卸载取消链,不宣称它解释另一台电脑历史 ERR_CONNECTION_CLOSED;正式包行为须重测。
- 工具最小修复:仅前端 npm run build 使用复制的 NODE_ENV=production 命令环境,其他安装/门禁/API 生成构建保留 test,父进程不污染;原 API 安全依赖补丁保留。主线程新增 vite.config.ts 的 cmpp-production-build-guardapply: build、configResolved 检查 isProduction,非 production 明确失败,不应用 serve/Vitest。没有修改通知业务计数口径、全局错误过滤或后端端口。
- 已执行:环境回归在旧实现明确失败(test != production),修复后 Windows 标准 self-test 37 项中 35 通过、2 项因符号链接权限与 Linux flock 限制跳过;包含新环境隔离与前端构建失败阻断回归。真实 NODE_ENV=test、development 两个 Vite 负例均由新守卫拒绝。默认构建、lint 当前正在执行,Linux 新 37 项结果待其他执行任务返回;本节不提前记录通过,也不复用前一版 Linux 35/35 充当本版结果。
- 证据:主 TEMP/cmpp-starttime-pagination-20260908 下 index-TLGANFcU.live.js、live-react-mode-evidence.json、release-build-mode-fix.patch、release-build-mode-before.log/after.log、build-mode-test.log、build-mode-development.log,以及第三轮 fetch-diagnostics.ndjson。两 Python 文件语法与尾随空白检查已通过。工具仍未跟踪、未暂存;Vite 配置及最终版本/测试/标准发布结果由主线程后续精确提交与追加。
- 待验收:新候选生产运行时、真实分页/三尺寸/刷新/切页/六通知请求与故障恢复,及授权顺序内的测试验收后推送、预生产独立发布。新工具摘要和配置改变后使用匹配精确提交的新计划及 fresh preflight,不把旧包只读观测或本地负例视为正式包业务完成。
最终检查结果补记(2026-09-08 22:36):默认 npm run build 成功,npm run lint 退出码 0;两个真实 test/development 构建负例准确拒绝。Linux 新版工具 37/37 通过、0 失败/0 跳过,耗时 0.192s,日志 SHA-256 为 305e7df43ff9d6506a755fd8d5e0adb6926e5ee89eb719d8baa015c231a4060b,位于主 TEMP/release-linux-unit-buildmode-2026-09-08T14-34-37-205Z/linux-unittest.log。本结果补齐上文执行中的本地检查;正式候选及真实部署页面仍待验收。
## 2026-09-08 22:56 正式前端测试发布验收与推送
- 精确提交 809175b544f2526891ba6d2dece1a50eadaf57a0 的标准 validate 全部 7 项检查通过;前端全量 25 文件 132 项通过,22:41:28 开始、耗时 81.86s。测试标准发布 20260908T143956-809175b544f2-e5a889cd 已完成 deploy/verify,状态 deployed-infrastructure-checked、verificationWarnings=[]、affectedServices=[];本次未重启 API/Worker。独立恢复点为 /var/backups/cmpp-platform/20260908T143956-809175b544f2-e5a889cd-attempt-1788878932275256962,未执行实际恢复演练。
- 真实测试浏览器于 22:50:0722:51:02 验收,acceptance.json success=true68 条观察记录、非预期错误 0、lifecycleAborts 0;旧开发包的 18 条非预期 ERR_ABORTED 在相同脚本中新版不再出现。expectedFaults 的 18 条是 6 个通知 GET 主动取消各产生注入/network/console 三类记录,不是 18 个故障请求;没有伪造成功响应。正常非零安全告警 6、系统监控 4、待审合计 21 在故障时保值并提示不可用,随后真实 200 恢复。另有 1 次正常待审提示框由脚本关闭,不计应用错误。
- 报备明细真实 total=29410/25/50/100 四档第 1/2 页、改容量回首页、刷新/跨路由通过;四个质量 Tab 的日期/容量独立与底部隐藏可访问标签通过。质量首 Tab 所选 2026-08-27 仅 7 行,其余所选维度样本为空;不能声称质量全部满 100 行或第二页覆盖。1600×1000、1366×768、390×844 截图已由主线程复核。证据:主 TEMP/browser/run-2026-09-08T14-50-07-200Z/acceptance.json 及同目录截图。此处主 TEMP 为 %TEMP%/cmpp-starttime-pagination-20260908。
- 测试验收后已按授权推送。首次 Failed to authenticate user,核验 Git 2.54、GCM 2.7.3 与合法 helper 配置后仅重试一次成功;远端精确回读 809175b544f2526891ba6d2dece1a50eadaf57a0fetch 后分叉 0/0。没有清凭据、修改全局认证配置或夹带未提交文件;首次认证失败内部原因仍未查明。
- 截至本节,预生产新计划正在生成,本轮尚未 deploy;用户 Edge 现有会话因空闲锁定,已请用户自行解锁,未修改账号配置或恢复管理员。预生产需独立发布与页面验收;另一台电脑历史 ERR_CONNECTION_CLOSED 未现场复现,不能由测试环境成功宣称网络问题根除。
## 2026-09-08 23:14 预生产发布完成与分层验收
- 已推送的精确提交 809175b544f2526891ba6d2dece1a50eadaf57a0 于 23:00:00 完成预生产切换。标准发布编号 20260908T145536-809175b544f2-b331cf90deploy/verify/status/report 完成,deployed-infrastructure-checked、verificationWarnings=[]、affectedServices=[]、error=null。独立恢复点 /opt/cmpp-platform-backups/20260908T145536-809175b544f2-b331cf90-attempt-1788879559918031565;未做恢复演练。前文 22:56 尚待发布是当时状态,本节追加当前结果。
- 23:03:45 只读复验:API PID 2469775、Gateway PID 2374059 均 active/NRestarts=0,与切换前相同;Redis PONG,三个业务 Stream 的 pending/lag 及变化量均 0;所采应用日志和 journal 新增 error 标记 0。首页、主 JS、JSX runtime、CSS 四资源全部 HTTP 200,公网与磁盘摘要一致;主 JS 为 index-CxA-S7x7.js、SHA-256 da8973bf49ac792147a6501c7f1b9a8393d900d355f1b0ed4397a80313f0c8f1。首次 CSS 请求失败的原异常未保留,后续四资源成功不能据此关闭其原始网络原因。
- 匿名浏览器 1600×1000、1366×768、390×844 页面与截图复核正常,验证码均 200、pageerror 均 0,实际主 JS 不含 react_stack_bottom_frame/JSX dev runtime。两个 /cdn-cgi/rum POST 由只读验收策略主动阻断,单独列为预期;另一次外域 GET 在响应头前真实 ERR_CONNECTION_CLOSED,初始探针未保留具体来源,网络关闭层仍未确定,不归为已修复。原自动化还误要求登录页自发请求 session;经核验页面没有该请求,独立匿名 GET /api/admin/auth/session 返回预期 401,不能冒称执行登录。
- 生产 React、通知轮询及公共分页修复已发布;测试环境的真实业务验收结论保留原环境。预生产现有登录会话因空闲锁定,待用户解锁,登录后分页/通知业务验收尚未完成;未读取新凭据、修改账号配置或恢复管理员。Chrome DevTools startTime 沿用此前注入归因与已合入上游修复的证据,应用不屏蔽异常;不宣称所有 Chrome 或历史网络 CLOSED 问题已解决。
- 证据:主 TEMP/public-verify/run-2026-09-08T15-03-44-416Z/verification.json 与 public-verify/anonymous-2026-09-08T15-07-16-145Z/review.json(主 TEMP=%TEMP%/cmpp-starttime-pagination-20260908)。后者状态为 anonymous_ui_verified_with_network_limitation,明确保留原始自动化失败和人工复核差异,不记为登录后全通过。
## 2026-09-09 九项运营修复执行结果(23:10 CST)
授权:修改并本地提交;未授权推送、测试部署或预生产部署。设计及根因见 [九项运营修复](operations-fixes-20260909.md),用例 TC-OPS0909-01 至09。本轮实现与本地验收完成,线上验收待部署。
- Git 开工核验:main / HEAD / 实际 origin/main 均为 6d63eb5452ffc7c802960d044bf598cc8646564d。开工已有19个 tracked 和21个具体 untracked 文件;40份开工副本逐一校验,既有文件内容保留。metrics、发布工具/脚本、AGENTS及已有治理文档不夹带。需求/UI/监控设计/系统用例/本记录仅提交本轮追加部分。
- 根因:报备 SQL 未按消息运营商聚合,三网任务重复取通道/签名总数;首页错误采用供应商分片,现按 queuedAt 上海自然日客户消息 billingUnits 求和。到达率保留供应商口径,未改变计费。
- 关闭交互:检索74个文件127处公共 Modal 调用,默认禁止遮罩/Escape关闭,并修复卸载时未取消的焦点动画帧;通道编辑的显式旧设置一并收敛。保留显式关闭、dirty确认和成功保存。只读签名详情抽屉非创建/编辑表单,未改其交互。
- 自动验证:前端27文件136测试通过(maxWorkers=2);API66套701测试通过(工作区含原有未提交metrics测试,不将其计作本轮新增/提交)。前后端TypeScript/生产构建、lint、格式、Stylelint、CSS治理15测试、bundle/security/deploy静态门禁通过。lint仍有既有AdminAnalyticsPage loadData依赖警告,0 error;入口gzip107.14KiB,在250KiB预算内。Gateway/队列发送链路未改,未执行发送smoke或压测。
- 真实环境:本地独立克隆库 cmpp_qa_nine_1788964857865 从原本地95迁移版本执行既有迁移到100;未迁移原库或远端。真实PostgreSQL、API和生产构建浏览器登录验收,非mock/假会话。认证使用现有Redis7通过独立DB15及本轮随机key前缀,队列留在独立本地Redis;不接短信发送Worker。Browser插件不可用,采用已安装Playwright + Edge。
- 非零数据:隔离SQL记录经真实API验证三网1/2/3次,未知运营商不分摊;7条业务消息共14客户分片,对应两通道8条提交尝试,首页仍14。 fixture为已拒绝/失败数据,仅SQL写入独立库,无入队/发送。当前用户告警已读数减1,重复读不再扣,read/unread列表与总数一致;其他用户隔离由现有实现及单元测试覆盖。
- 浏览器:企业/通道签名活动独立字段和三尺寸1600×1000、1366×768、390×844;创建通道遮罩/Escape不关闭且显式关闭正常;HTTP地址关/开跟随参数,非法扩展码在居中错误框展示且不保存配置。历史告警默认近7日取得真实Prometheus25个周期,选择今天后请求成功,三尺寸截图;短信历史记录详情不再有每行通道组,顶部保留;独立库清退消息经真实API展示去前缀,数据库原文不变。上述成功运行无未捕获pageerror,未声称逐个手工验收127处弹窗。
- 当前环境只读证据:本轮约22:20预生产今日10257条客户消息、18270客户分片、31482供应商分片;近7日三网尝试13311/13647/13572、未知28,证明口径差异。测试和预生产仍为809175b544f2526891ba6d2dece1a50eadaf57a0,均未发布本轮代码。MinIO/Gateway写路径不在修改范围,未验证文件上传和真实短信链路。
- 原失败保留:前端首轮高并发超时、观察器按钮/label不匹配、日期选定后未点确定、SQL fixture先用非统计状态failed以及清退fixture先缺关联检测记录均修正后重跑,不能记为产品通过。Prometheus隧道曾Connection reset造成一次真实503,重建只读连接后成功;未屏蔽应用异常。Redis5不支持认证GETDEL且原库缺表,后改独立库及真实Redis7进行隔离验收。
- 本地启动影响:首轮API启动曾自动尝试连接两个通道,因本地Gateway不可达失败,写入本地CmppConnectionState运行状态;未发送短信、未修改通道配置。后续延后启动重连、关闭相关扫描器与归档/报表调度。临时QA用户/操作日志/告警和业务fixture及认证前缀按本轮ID清理;不恢复或改写原有运行状态。
- 遗留边界:创建通道390宽原有布局拥挤,关闭按钮可见可用,未扩大为视觉改版;历史告警受Prometheus保留和采样限制,含等待触发周期,最后采样不等于恢复时刻。预生产历史ERR_CONNECTION_CLOSED根因和已有管理员会话锁定未在本轮解决,未尝试恢复管理员。未推送、未测试部署、未预生产部署,线上真实业务验收未执行。
本地证据目录:C:/Users/hectorzhao/AppData/Local/Temp/cmpp-nine-fixes-20260909。自动日志api-full.log、frontend-final.log、build-last.log、api-build-final.log、lint-last.log、security.log等;浏览器成功记录browser-run7.log、browser-extra2.log、browser-retirement2.log、browser-counts2.log及各browser-*目录截图/结果,失败日志保留。敏感认证值不写入文档或Git。
## 2026-09-10 引流拦截需求评估与方案
仅文档授权;本地main为5bcdbb2a03637b1ab1aeda59a4e1db9cc9fc4243,实际ls-remote远端main为6d63eb5452ffc7c802960d044bf598cc8646564d,暂存区空,保护既有19个跟踪修改及全部未跟踪文件。核对检测器、两条原文最长匹配路径、报备路由、Prisma模型和平台失败回执后,新增[专项方案](drainage-send-gating-plan-20260910.md),同步需求/风控索引/16项待执行用例。明确旧只识别规则被新需求替代的生效关系、多目标交集、号码清洗且原文不变、URL字面包含边界、审核和legacy任务兼容、拒绝回执/费用幂等、队列与撤销并发、数据迁移及阶段实施。
证据仅当前源码/模型和真实Git远端读取;未启动服务、未连接业务数据库或远端API,未验证PostgreSQL/Redis/MinIO/Gateway当前状态,未执行业务测试、构建、浏览器或发送。文档完成不代表引流门禁已实现。业务边界待明确项列在方案第9节;本轮运行代码/配置/数据库无修改,未提交、未推送、未测试部署、未预生产部署。文档开工副本及保护核验记录位于%TEMP%/cmpp-drainage-design-20260910。
用户随后明确URL规则:登记父域名授权自身及任意层级子域,路径/参数不限制,排除lisglo.cn.evil.com等伪包含。已将方案3.3改为URL解析后的hostname相等或点边界后缀匹配,同步需求和TC-DRAINAGE-GATE-05;仅历史带路径资料的迁移策略等仍待明确,域名边界已确定。
文档核验完成:4份既有文档保持开工字节前缀不变,专项方案6个相对链接有效,16项验收用例均明确待执行;git diff --check通过,暂存区仍空。src无修改;api仅保留开工已有metrics两文件修改。本轮交付为新增1份方案与4份既有文档追加,无代码实现、业务测试或提交/发布。
2026-09-10解释与补核:用户确认引流资料须平台审核通过,已写入方案及用例。将旧带路径资料/通道级报备术语改为业务示例和实施核查项。只读核对单条/批量路由失败、recordCmppFailureReceipt、queueFinalReceiptDeliveries及HTTP投递配置:CMPP路径生成REJECTD并按请求标记投递;非CMPP路由失败只刷新任务进度,未调用统一失败回执,列为后续闭环修复点。无代码修改或真实发送复现。
2026-09-10用户最终确认:旧通道报备配置由用户调整,仅要求配置功能正常;非CMPP提交本来就不应推送回执,未来另提需求。已修正专项方案的现状评价、来源分支、实施范围和验收条件,同步需求与用例;撤销此前将非CMPP不推送判为缺口及纳入修复的判断。未修改代码/配置/数据,未迁移旧报备,未提交或部署。
## 2026-09-10 引流发送资格实施与本地验收(13:20 CST)
授权:修改、本地提交、测试环境部署;未授权推送、预生产部署、发送/补发/重投/重新入队短信或修改既有客户/通道/余额配置。实施见 drainage-send-gating-plan-20260910.md 第10节,用例 TC-DRAINAGE-GATE-0116 分层记录。
- Gitmain 开工 HEAD 5bcdbb2a03637b1ab1aeda59a4e1db9cc9fc4243,实际远端 main 6d63eb5452ffc7c802960d044bf598cc8646564d。本轮保护42个已有具体文件;发布工具、metrics、AGENTS及治理草稿不提交。本轮变更前副本、日志及浏览器证据位于 %TEMP%/cmpp-drainage-implementation-20260910。
- 实现:全目标规范化与同签名审核校验、通道交集、批量/普通路由、Gateway每分片最终复核、域名边界及伪URL排除、判定快照、CMPP拒绝回执耐久恢复、非CMPP不推送、多引流统计和短信详情。运行时仅新门禁产生拒绝,不处理旧批准或重发旧短信。治理清理未实施。
- 新增 schema 迁移在独立真实 PostgreSQL 克隆库 cmpp_qa_drainage_1789017023546 应用成功;另一个早期迁移试验库保留,均未改本机业务原库。真实规则+资格HTTP接口验证NFKC号码/原文不变、两个目标通道交集、平台审核、报备撤销、写事务与复核并发锁、伪后缀/query/userInfo、转发请求拒绝、持久化决策及报备SQL;结果 real-gate2.log。仅构造隔离数据库夹具,无发送Worker、Gateway transport或提交outbox。
- 自动检查:API全量67套723项通过;最终定向2套152项通过。前端27文件136项通过;TypeScript、API构建、前端production构建通过。Gateway全量Go测试及vet通过。lint(含类型/Stylelint/CSS治理15项)、format:check、security:verify、deploy:verify、bundle:verify通过。原有API metrics未提交测试包含在工作区总数中,精确提交的发布validate独立核验,不冒称所有测试文件均被提交。改动文件必要格式化和未使用导入清理用于满足当前门禁,未触及其他会话源码。
- 浏览器:Browser插件不可用,使用既有Playwright/Edge,真实本地API+独立PostgreSQL库;Redis5仅隔离本机队列,登录使用测试Redis7的DB15独立随机前缀,经SSH转发,结束删除仅本轮认证键和临时QA用户。1600×1000、1366×768、390×844通过,拦截原因、显式关闭、刷新与跨路由正常,无pageerror。首轮在详情请求返回前断言历史占位,已修正测试等待,并为加载中新增明确提示;最终production构建再次验收通过。证据 browser-final.log 及该目录最新 browser-* 截图。
- 环境:13:12重新核验测试SSH和health可达,线上版本仍809175b544f2526891ba6d2dece1a50eadaf57a0。期间两次SSH连接超时,Tailscale通过DERP后恢复;不记作认证失败或网络根因已永久解决。本次测试发布包同时包含此前九项运营修复提交与本功能;不推送远端。
- 未执行:真实短信提交、供应商零Submit/长短信跨分片对账、客户回执ACK/离线送达、费用和部分已发记录对账、TPS/故障注入容量测试;没有专项发送授权,以上不以单元、夹具或浏览器代替。既有通道配置不修改,MinIO材料无变更。提交及标准发布阶段、磁盘/恢复资产与目标页面结果在后续记录补齐。
## 2026-09-10 引流门禁测试部署完成(14:00 CST)
应用0c3f820cc92eeae8c996ac7d6d8d6db98e049ea7已本地提交并通过标准工具部署测试,原版本809175b544f2526891ba6d2dece1a50eadaf57a0;未推送、未部署预生产。精确提交validate为API67套722项、前端27文件136项及相关门禁通过。首次preflight的安全代理运行目录缺失由用户单独授权修复,复检后正常发布。13项服务active、三个Gateway Stream pending/lag=0、消息/提交数不变、迁移/资源摘要/日志验证通过。真实测试管理员和六页面、三尺寸历史短信详情通过,线上不回填旧消息。
[本次发布验收](release-20260910-test-drainage.md)记录完整版本、工具未提交摘要、备份、容量清单与阶段时间。候选77.9秒、备份35.7秒,停服务至恢复约14秒;发布后系统盘可用10.37GB,比发布前减少约1.48GB,旧版本/候选/备份未清理。真实发送、供应商Submit、客户回执ACK和费用对账仍未执行,不能以页面通过代替。原网络超时根因与预生产历史故障未宣称关闭。
## 2026-09-10 通道敏感词需求评估
授权仅评估。main/HEAD为8694782,实际远端main为6d63eb5452ffc7c802960d044bf598cc8646564d,暂存区空;保护全部已有源码、工具、网络及HTTP评估文档。本轮完整阅读UI规范及当前敏感词页、词库/风控和普通/微批路由、最终Gateway门禁与结果处理,新增[channel-sensitive-words方案](channel-sensitive-words-plan-20260910.md),同步需求/风控索引及12项待执行用例。
现状为全局SensitiveWord原文includes命中统一block,无通道模型或Tab。建议独立库、候选排除、原选路算法、最终复核;零写入方可有限重选,部分已发不整体重发,全候选排除才形成适用失败闭环。普通包含/三网统一/全排除失败为建议首版规则,不将未经确认的抗干扰或等待恢复加入实现。中等规模跨模块改造,不能仅改UI;无固定工时或TPS承诺。
本轮未连接真实API/PG/Redis/MinIO/Gateway进行业务验收,未启动或发送短信、未改规则/网络配置。仅文档与源码评估,功能和12项用例均未执行;无代码修改、无提交、无推送、无测试/预生产部署。文档保护副本及核验位于%TEMP%/cmpp-channel-sensitive-assessment-20260910。此前绕过OpenWrt任务仍未通过候选网关出口验证,本评估不宣称该任务完成。
本轮文档核验:四份既有文档的原字节前缀保留,其他开工保护文件摘要未变;专项方案链接和diff检查通过,暂存区为空。
## 2026-09-10 通道敏感词方案缩减为仅选路过滤
用户明确因性能考虑,暂不做入队后通道敏感词复核。已修订专项方案、需求和风控索引,以及TC-CHANNEL-WORD-08/09/10/12等用例:普通/微批及原有新选路时按快照过滤;已读取快照的微批与已选路消息不追溯配置变化。移除新增Gateway/逐片检查、发送授权锁、final决策和配置变化触发重选,保留管理端编辑并发保护及既有引流门禁。前一节初稿的最终复核/零写入新增重选描述由本记录取代,不再作为第一版验收要求。
仅文档修改,未修改代码或网络/业务配置,未提交、未推送、未测试或预生产部署。保护副本位于%TEMP%/cmpp-channel-sensitive-routing-only-20260910;执行文档一致性、链接及diff核验,不重跑业务测试。
## 2026-09-10 通道敏感词实施与本地验收
授权:按修订方案修改、本地提交、部署测试环境;不推送、不部署预生产,不发送/重投短信或改现有线上业务配置。开工main=8694782,真实远端main=6d63eb5;测试版本0c3f820。原metrics、工具、规范、网络/HTTP评估文档受保护,提交只纳入本轮代码及主题文档精确部分。
实现:独立通道词Tab/API、运行时参数/平台管理员校验、version冲突、软删除恢复和事务审计;普通/微批选路快照排除候选,运营端最近10次解释;CSW失败与channelWordFinalizationPending耐久恢复,非CMPP不新增回执。Gateway/逐片检查未改。新增迁移不改历史配置。设计和边界见channel-sensitive-words-plan-20260910.md第8节。
验证:API全量69套745项通过;后追加恢复用例,发送链定向138项通过。前端全量28套139项通过,API构建/类型、production前端构建、lint/格式/CSS/安全/bundle通过(lint既有28警告)。初轮测试选择器及测试类型错误已修正;原页面空依赖列缓存随组件拆分取消,避免旧查询闭包。隔离真实PostgreSQL迁移与并发/路由/失败SQL验证通过;100条微批通道词读写各1次,390~441ms包含既有引流,不是发送TPS。
真实浏览器:production构建、Nest API、隔离PG、Redis7认证前缀,三尺寸CRUD/软删除/独立筛选/关闭/刷新/跨路由/详情通过,pageerror=0;匿名API401。未启动短信发送Worker/Gateway transport。证据%TEMP%/cmpp-channel-sensitive-implementation-20260910,包括real-api-failure.log、browser-1789026246272、各质量门禁日志。实际短信发送/客户回执ACK/费用流水与完整吞吐未执行。
本地实现和验收完成;本地提交、测试部署正在执行,推送/预生产未授权。测试部署成功后另补精确版本、恢复资产、磁盘增量及真实页面验收。
## 2026-09-10 通道敏感词测试交付完成
应用`8e4bc5a20e4d98e96fc8572fabbac149ba12c8e6`已本地提交,并通过标准工具部署测试;精确归档validate为API69套745项、前端28套139项及门禁通过。13项服务active,三个Stream pending/lag=0,消息119509/提交130769前后未变,新增迁移/HTTP产物摘要/日志验证通过。已有管理员正常登录、新Tab真实空词库API200、三尺寸显式关闭/刷新/跨路由/历史详情通过;没有保存线上词库或发送短信。观察器同名关闭按钮修正后通过,原失败保留。
[发布验收与容量清单](release-20260910-test-channel-sensitive-words.md)记录精确版本、工具未提交摘要、独立备份、47目录盘点和时间。prepare56.5秒、备份35.2秒、停止至恢复17.0秒;系统盘可用10.35GB→8.81GB、使用率92%,增量约1.54GB,旧版本/候选/备份均未清理,容量治理未完成。未推送、未部署预生产,实际发送/客户回执ACK/费用流水与完整吞吐未执行。
## 2026-09-14 HTTP整改代码与隔离验收(提交前)
- 授权:按http-api-assessment-20260910.md整改,提交、推送、部署测试;不操作预生产,不发送/补发/重投/入队短信,不改现有余额、通道、客户配置或恢复账号。
- 开工本地main/实际远端d13ca0713abd6afbea5a62af39bcbb876b8bb186、0/0、staged为空;保护metrics、tools/release及全部旧文档/工具草稿。测试SSH已实查,应用8e4bc5a20e4d98e96fc8572fabbac149ba12c8e6、系统盘可用24,643,088,384字节、76%;没有/data目录,sudo -n需要密码。仅测试环境,预生产版本未在本轮重新核验。
- 实现:共享签名/固定GET兼容、DTO/schema/query、未知错误公共化和交互ID;上行仅公共字段,按用户决定移除通道/供应商/内部匹配信息。确定性HTTP消息与受理快照/发送待办同事务;不确定结果requires_review,不自动重建。回调事件/投递同事务,新版本待办恢复、租约、尝试/退避同事务和无冒号任务编号,历史记录不回填。新迁移只追加,应用回退不会删除待办,但旧应用不识别新待办,回退前必须核对排空或保留后续恢复安排。
- 文档阅读器:公开/api/client-docs及原JSON地址保留;客户端同源iframe复用单一MD和阅读组件,文档HTML内嵌所需样式/脚本,无需扩大Nginx资源白名单。版本从MD元数据读取。补应用切换过期响应保护及无配置阅读状态;原业务Tab不主动改变操作语义。CSS所有权已登记。
- 本地验证:首次API生成缺少隔离NODE_ENV/DATABASE_URL失败,补明确隔离环境后Prisma generate/API构建通过。HTTP定向最终4套47项通过;工作区API全量此前71套779项、前端29套141项通过(含保护中的旧metrics修改,不作为精确发布候选证据)。前端生产构建、类型检查、入口gzip107.17KiB/250KiB门禁、部署/安全检查通过。CSS首次漏登记所有者失败,登记后CSS治理15项和stylelint通过。旧文件未用import造成lint失败,限定本轮触及文件清理无用import后通过;未改保护文件以消除失败。
- 隔离真实验证:测试机新建PG15439与Redis16389,仅127.0.0.1及/tmp/cmpp-http-remediation-inqN9k。实际Nest控制器+鉴权+Prisma完成GET签名、分页、跨租户404、nonce/篡改、参数拒绝和上行字段核对;合成回调在受控Redis发布失败后恢复,首次HTTP500、60秒后HTTP200PG尝试[500,200],历史version0未重投。该轮0短信/0供应商Submit。另真实PG事务测试用隔离前置依赖核对待办故障回滚及202原子快照,保留1条合成消息fixture,未冻结/扣费、未入队短信,不能当发送业务验收。
- 迁移:隔离数据库从HEAD schema执行追加迁移通过,历史写法兼容进一步核验单列证据。恢复资产不删除;不做生产数据回填。
- 页面:cua.getState本轮仍返回nodeRepl.fetch request failed,不能推断未登录。使用已有Playwright+Edge独立无头上下文验收本地实际文档页,三尺寸、复制/失败降级、检索/空结果、示例切换、MD下载同字节与刷新通过,pageerror=[]。未用隔离文档页冒称测试环境已登录客户端及其他Tab全部通过。
- 证据:本机TEMP/cmpp-http-remediation-20260914(保护摘要、targeted/api-full/frontend-full/http-final、browser-result、截图、integration-result、事务及迁移脚本);独立测试进程已按确切cwd/PID停止,PG/Redis临时实例与目录保留待本轮收尾。只读测试环境SSH有一次超时,成功与失败分别记录,不归因于Git或密码。
- 当前状态:本地代码/设计/手册/用例完成本阶段;尚未本轮提交/推送/测试部署,未部署预生产。下一步仅暂存本轮代码、两份HTTP专属文档及三个台账新增段落,从精确提交跑标准release validate,再推送与测试preflight/prepare/deploy/verify。测试sudo需标准掩码入口,真实短信正向/计费与已登录客户端最终验收仍未执行。
### 2026-09-14 12:58 HTTP整改精确提交与发布候选验证
代码提交f0e843436c715010d3eaec72a5e0c81816a6e5bd已推送并实时回读,fetch分叉0/0。首次GCM认证失败,核验现有helper后按标准流程仅重试一次成功,未改凭据配置。标准release validate独立候选API72套780项、前端29套141项及类型/格式/lint/style/CSS全部通过;候选production构建和107.17KiB入口预算通过。带历史fixture的追加迁移确认旧记录保留、recoveryVersion=0、空租约;隔离PG/Redis及本地文档进程已停止并保留证据。
标准preflight实际返回sudo需要密码,已提供本机标准掩码输入入口;尚未prepare/deploy,无迁移/服务切换或正式备份。测试现版本仍8e4bc5a,预生产未操作。真实已登录客户端、短信正向/计费及Gateway链路未验收;完整容量资产盘点需sudo。具体计划、摘要、证据、原失败和续接步骤见[本轮发布记录](release-20260914-test-http-api.md)。其他会话草稿仍未纳入提交;发布工具使用本机既有未提交版本并独立登记摘要。
### 2026-09-14 13:18 HTTP整改测试发布收尾
认证入口纠正后,标准LF预检发现旧源码CRLF差异;逐字节确认后新建CRLF计划20260914T050659-f0e843436c71-48bc2b23,复用同一精确提交有效证据,重新preflight通过。prepare→deploy→独立verify→report完成,测试实际应用f0e843436c715010d3eaec72a5e0c81816a6e5bd,服务正常、verificationWarnings为空;独立恢复备份约496.57MB保留,停止至恢复约13.5秒。
测试实际公开文档/JSON为200,七query/唯一幂等头/未认证401关联ID通过;Edge三尺寸、检索、示例、复制降级、同字节下载和刷新通过,无pageerror。未将公开页验收冒称已登录客户端完整验收,未发送/补发/重投/入队短信,未作真实计费/供应商链路测试。测试系统盘78%、可用22,848,892,928字节,51目录容量清单和上一有效8e4bc5a组件保留;历史资产清理目标未完成。密码仅标准输入传递,不写入文件;原认证/路径/换行失败和等待不并入停机耗时。详见[最终发布记录](release-20260914-test-http-api.md)。预生产未操作,文档收尾提交不改变测试选定应用版本。
## 2026-09-14 HTTP全量模拟链路验收计划
用户专项要求在测试环境全面测试HTTP正常/错误参数,并使用历史模拟通道模拟上行、回执和webhook。本轮仅测试,不扩展至预生产或真实供应商;不继承历史清理、重投授权。需求和业务设计不变,按HTTP整改方案及手册检验实现。
已核验本地/实际远端40c8e27、暂存区空,保护已有metrics/发布工具/文档。测试基线PG无pending/dispatching提交、Inbox均completed,六条LGST通道指向100.91.249.119:17900,三组只含这些模拟通道。使用新建本轮应用、签名、凭据和回调端点,现有客户/通道/余额不手工修改。测试正常费用从现有测试企业账户按原正价325计费并对账。
计划最多30条独立业务消息(请求/参数/查询不计消息数),常规新消息最高1条/秒,同键并发只检查幂等;虚拟号码限定13800001xxx、13000280xxx、18900280xxx,最多160个模拟Submit分片。覆盖四接口、鉴权/nonce/时间/body签名、DTO/幂等/权限/QPS、结果/上行查询分页隔离;回执与MO经过真实Gateway/PG/Rediswebhook覆盖HMAC、2xx、4xx、429/5xx重试、超时、重复事件和手工重试边界。独立HTTPS受控接收端仅接收本轮合成数据,不绕过服务端SSRF;临时接收端与模拟器测试后关闭,旧Tailscale17900转发保持。
单例观察上限90秒,自动重试按真实60秒退避,收尾排空最多180秒;未知目标/错误路由、账务不一致、重复Submit或持续积压即停止新增业务消息并保留证据,不清队列、不手动伪造ACK。尚未执行的场景不填通过,缺陷先记录和最小复现。
## 2026-09-14 真实HTTP全量验收发现的Webhook DNS缺陷
测试环境 f0e8434 上,专用模拟应用已产生真实送达回执,但5个Webhook事件均在2次尝试后失败,lastError为 `Invalid IP address: undefined`,受控HTTPS接收端无请求。Node自动地址族选择以 `all=true` 调用自定义lookup,旧实现仍返回单地址三参数,违反回调契约。保留原SSRF解析、私网拒绝及地址固定,只按all选项返回固定地址数组或原单地址。未改变重试、计费、发送与租户规则。真实Node HTTPS连接旧实现失败/修正实现200,本地真实HTTP连接回归及API全量73套783项、类型构建通过;线上修复与Webhook全场景验收尚待标准发布完成。用户已另行授权本修复提交、推送及测试发布,不涉及预生产。完整结果将登记 [HTTP全量验收](http-api-full-acceptance-20260914.md)。
### 2026-09-14 HTTP全量模拟验收阶段结果
已记录140项检查,9条真实模拟短信(8送达、1失败并退款)、6条上行(3matched/3ambiguous)、真实队列/计费对账完成。Webhook DNS callback最小修复92b112c已提交/推送/标准部署测试,精确候选782项通过。IPv6 URL500、日历日期自动归一化、body-parser错误契约3项待修。公网回调成功/状态码重试仍被测试机198.18.x.x代理DNS路径阻塞,固定真实公网IP的只读TLS探针200;正等待临时仅专用域名hosts映射授权,尚未改网络。详见[完整阶段记录](http-api-full-acceptance-20260914.md),不宣称全量通过。
## 2026-09-14 HTTP全量验收后续修复与授权
用户已授权本轮全部已发现Bug的修复、复测、提交/推送、测试部署,以及仅测试机专用回调域名的临时hosts映射;映射有30分钟独立精确移除timer,验收结束主动移除。无默认网关/DNS服务/OpenWrt或预生产变更。12个既有本轮回调已真实HTTPS送达;200/204成功、400/302终止、429/503/超时重试、持续503上限及人工重试保护均通过,HMAC、eventId与60秒退避一致。
HTTP-FULL-B02:去除URL IPv6方括号后区分IP字面量与DNS,DNS失败转稳定400;同时规范化IPv4-mapped IPv6后复用私网校验,避免修复引入私网绕过。B03:先校验ISO8601年月日/闰年/时分秒/时区,拒绝Date自动归一化;覆盖query与cursor,不改变查询跨度和归属。B04:只对/api/openapi/v1/sms的body-parser已知错误输出统一problem+json和X-Request-Id400/413/415正文固定,不泄露原始输入;非公开路径和未知错误继续原处理链。无迁移、短信链路、计费或权限规则变更。线上边界复测及最终收尾待新候选发布。
## 2026-09-14 HTTP全量验收最终闭环
截至 2026-09-14T07:49:14.156Z,测试环境精确版本97d133442350b9725422ed4e55386f47e37004fd。HTTP-FULL-B01至B04已修复、提交、推送、标准发布并真实复验;74套809项精确候选测试、格式、Lint、类型、构建及安全门禁通过。235项真实请求/断言中229项通过,另6条原始非通过记录已分类并有复测,不删除失败历史。20条短信19送达/1预期失败退款,23个模拟CMPP Submit,21成功计费单位,净扣6825,余额1848101→1841276。7条上行3歧义隐藏/4匹配且ACK完成;24个Webhook事件22送达/2预设终止,31次真实HTTPS收件,签名、密钥轮换、状态码、退避、超时和人工重试均核验。三个Redis Stream pending/lag均0;本轮待办排空、三个应用停用/凭据撤销、receiver及隧道关闭、hosts原字节恢复。未操作预生产、真实运营商或其他客户配置。
完整矩阵、根因、发布恢复资产/容量与未执行项见 [HTTP全量验收报告](http-api-full-acceptance-20260914.md)。本段更新此前阶段性“待修/待授权/阻塞”状态,不将其当当前状态。
## 2026-09-14 四项配置与引流运营商报备修复(本地提交范围)
### 范围与只读证据
- 起点本地 main 与实际远端 main 均为 ac6449028c4ab072ef16a219f61d592e2d453a7e,起始暂存为空。保护既有 metrics、tools/release、HTTP 接入及需求/测试/发布草稿,不推送、不部署、不发送/补发/重投/入队,不修改线上配置或业务数据。
- 2026-09-14 17:11:47(北京时间)只读核验预生产应用 d13ca0713abd6afbea5a62af39bcbb876b8bb186。号码 188****3795 的 MSG-b3b529de-602c-44a8-9cc9-bce3a5a8360f 在 15:39:30 至 15:41:51 有 10 条路由敏感词快照,全部 hits=0、reason=null;多轮候选选择均保存快照,详情逐条显示正常结果导致噪声。只过滤展示,审计/短信状态保持。首次只读查询使用不存在的 createdAt 后改用 queuedAt;未进行数据修复或发送。
- HTTP 白名单原解析已支持英文逗号,本轮明确输入说明并补混合分隔符回归。引流新增/编辑此前缺少同签名重复校验;通过同签名 advisory 事务锁将检查与写入串行化,状态恢复亦校验。
- 原引流任务按通道级 carrier=null 管理,现按通道×运营商管理,并更新路由、签名汇总、报备明细、批次/导出和状态更新。明确运营商结果优先于旧通道级状态,材料变化使旧审批失效。设计先更新于 drainage-send-gating-plan-20260910.md 第 11 节。
- 真实 PostgreSQL 首轮创建暴露旧部分唯一索引仍限制三维键,新增 20260914093000_drainage_carrier_reports,保留全部旧记录,改为明确运营商与历史通道级两个部分唯一索引。新迁移仅在本轮独立本地库执行。
### 已执行验证
- API 全量:74 suites / 811 testsAPI TypeScript 生产构建通过。
- 前端全量最终:30 files / 144 testsnpx vitest run --maxWorkers=2);TypeScript 与 production 构建通过。最初新增三网测试发现 Select 未传递 aria 名称,修复公共组件并删除关闭时无用的 portalStyle 状态重置,覆盖三网选择与重新打开。另一轮并行构建/测试发生 17 项超时及关联断言失败,保留原日志;限制 worker 后及最终稳定代码两次全量通过,未提高超时或删除断言。
- npm run lint、format:check、quality:verify、style:check、css:verify15 tests)、security:verify、bundle:verify 通过;lint 留存 3 条非阻断提示(原报备页 effect 依赖、IP 解析函数导出、测试 any)。git diff --check 通过。原未格式化测试/服务文件随当前格式门禁格式化,无业务扩展。
- tools/testing/verify-drainage-carriers.mjs:独立 loopback PostgreSQL 16414 / cmpp_qa_carriers_20260914,实际服务 HTTP 适配器 16416,25 项通过。覆盖迁移旧行完全保留及两类唯一约束、trim 重复、跨签名、自身修改、5 请求并发新增、并发改值、删除值复用及恢复防绕过、三网保存/汇总/路由、旧审批不覆盖明确失败、材料修改审批失效、批次目标与列表及 HTTP 白名单落库回读。一次新增数据扩充后列表断言受默认 10 条分页影响,限定验收签名并读取 100 条后通过。
- 浏览器连接器本轮仍为 nodeRepl.fetch request failed;使用已安装 Playwright + Chrome。本地 Vite dev 入口加载超时后,改用 production 构建 + preview 16418,真实业务组件连接上述服务与 PG1600×1000、1366×768、390×844 无横向溢出。三网分别保存(移动通过、联通失败、电信未报备)后刷新读取一致,重复值 HTTP 400,发送详情不显示零命中快照,切换弹窗与重新打开选择器通过。无框架错误;控制台仅验收入口 favicon 404 和故意触发的重复值 400。
- 证据目录:%TEMP%/cmpp-drainage-carriers-20260914preprod-records.json、api-full.log、frontend-final-stable.log、real-http-final2.log、real-fixture-final.json、ui-evidence.json、carrier-1600.png / carrier-1366.png / carrier-final-390.png 及质量日志)。保留初次失败和最终结果。
### 交付边界与遗留
- 本轮仅本地修改、文档和本地提交;未推送、未部署测试、未部署预生产。迁移和代码未在两套线上环境生效。提交号见本条记录所在提交;最终汇报提供精确 SHA。
- 隔离 HTTP 适配器直接调用真实业务服务与 PG,不包含完整 Nest 全局认证、生产反向代理和 worker;不得将其当作在线全功能验收。测试环境/预生产完整登录页面、权限与租户隔离在线回归、MinIO 报备文件导出/导入实物、Redis/Gateway 实际短信发送与计费闭环本轮未执行。原链路单元回归通过不替代物理发送专项验收。
- 53 项已有保护文件在最终核对中保持摘要(仅本轮文档采用追加并精确暂存);其余脏文件和草稿不纳入提交。历史重复资料不自动清理,历史通道级审批不批量重写。上线须先按标准发布流程执行新索引迁移,回退不可直接删除三网任务或重建旧索引。
## 2026-09-14 客户端模板、接口文档、工作台与回执整改(发布前)
- 起点 main 7f9abe3,实际远端 ac64490,测试机 97d133442350b9725422ed4e55386f47e37004fd。用户明确要求修改、提交、推送、测试部署;预生产、短信发送/重投、客户配置变更不在范围。测试发布包含上一轮引流三网报备提交和 20260914093000_drainage_carrier_reports 兼容迁移。既有 metrics、tools/release 和文档草稿全部保护。
- 只读根因:测试库 http-cmu0xgl6o000k5mle3hrw4avd 为 deliveredreceiptStatus=delivered、deliveredAt=2026-09-14T07:34:41.935Z,回执表原码 DELIVRD;另外两条送达样本一致。旧 listClientMessagesPage 投影三条均 receiptStatus=null、deliveredAt=null、receiptRecords=[],因 listMessagesPage 未选择回执标量。仅补主记录两个标量,不加载全量尝试关系,不改消息状态/回执消费/账务。页面优先聚合最终回执并格式化北京时间。
- 模板 toolbar 改为输入/查询操作/添加三列、窄屏堆叠;正文 132px 纵向滚动;页脚脱离 legacy button 规则,使用公共按钮和原风险确认流程;表单应用、名称、签名、内容,不提交 category,历史值保留。
- /client/http-docs 独立路由与菜单;原接口配置页移除文档 Tab,保留其余功能。读者把示例移回所属正文,取消编号侧栏切换;第 11 节示例分配回鉴权与各接口章节,3.2 重写为三个步骤,37 段非 text 示例哈希逐一保持。新页面与 CSS 同目录登记所有权。
- 工作台复用 batchTaskStatusMeta/normalizeBatchTaskStatus,短信内容列读取 content。设计见 client-ui-remediation-20260914.md,用例 CLIENT-0914-01 至 07。
- 本地 API 74 suites / 812 tests 通过,API 构建通过;前端最终 31 files / 146 testsmaxWorkers=2)通过,类型/生产构建通过;代码 Lint 无错误(3 条旧依赖/any 提示),Stylelint、CSS治理15项、格式、包体及安全门禁通过。保留初始 worker 启动超时、回执标签断言、类型错误、CSS所有权/语法失败,后续修正和重测分开记录。精确发布候选仍需标准 validate。
- 浏览器连接器仍 nodeRepl.fetch request failed;使用已安装 Playwright/Chrome。独立本地 PG 16414 + 真实服务 HTTP 适配器16419 + production preview16420,未启动 Gateway/发送Worker:模板长短正文高度均132px、按钮143px,三尺寸1600×1000/1366×768/390×844无横向溢出;编辑顺序、删除hover、真实回执成功/失败/空值及15:34:41时间、工作台正文/已完成、文档三步示例、检索与复制通过。复制未执行请求。此为真实服务组件验收,非完整在线登录/鉴权验收。
- 本机证据 %TEMP%/cmpp-client-polish-20260914api-full.log、frontend-final.log、css-final.log、style-final.log、format-final.log、browser-results.json 与 templates/receipts/home/docs 三尺寸截图。隔离库仅使用本轮专用样本;测试线上只读抽样。客户端登录账号尚待用户提供,不恢复旧账号、不造认证会话;在线页面与发布结果后续追加。
### 2026-09-14 23:25 CST 客户端四项修复已推送/测试部署
应用 4665079ca3d2f985c85c5c1d08f8fe173047e9bd 已推送,远端回读一致;测试从 97d1334 经标准发布升级,包含此前 7f9abe3 报备迁移。归档候选前端 31/146、后端 74/811、类型/格式/lint/style/CSS 门禁通过,远端 production/API 构建通过。候选前端首轮两项 worker 启动超时已保留证据,同候选全量复测通过,未跳过测试。
三条真实测试消息的数据库回执保持不变,已部署客户端分页查询服务已由 null 恢复返回 delivered 和真实时间。线上文档三尺寸/43 内嵌示例/检索通过;HTTP 剪贴板受限时实际提供选中后手动复制。当前版本、服务、迁移、队列和日志检查通过无警告。完整登录后客户端页面仍待可用账号;连接器失败不等于用户未登录,本地真实 PG/服务组件验收不替代线上登录验收。
计划 20260914T151450-4665079ca3d2-874a39f8,备份 attempt-1789399125391792291。远端准备 61.7 秒、备份 34.5 秒、停止开始至启动完成约 13.4 秒。系统盘净增约 1.46 GiB、可用约 17.21 GiB,历史资产未清理。设计、详细证据及未验证项见 [客户端页面与接口文档整改](client-ui-remediation-20260914.md)。预生产未部署;未发送短信或修改业务配置。
## 2026-09-15 HTTP 签名简化实施与测试发布(进行中)
起点main/实际远端bcb278be29857b73ec11e04650923f473875ca9b,暂存空,53个已有文件保护摘要在.local-data/http-signature-20260915/protected-hashes.json。测试机SSH初期超时、Tailscale relay可达,后续恢复并回读线上4665079ca3d2f985c85c5c1d08f8fe173047e9bdsudo仍需掩码输入。
按B6实施POST原始正文HMAC、GET末尾无LF,保留内部幂等摘要和Webhook规则;旧签名不回退尝试。原2.4移1.4、公开/客户端共用MD,补OpenAPI签名描述。页面只读复现加粗示例标题未识别,reader支持加粗标题。相关设计先更新于http-api-assessment-20260910.md。
定向31项、初轮API全量75套817项及构建通过。独立本地PG16424/cmpp_qa_http_signature104迁移)、Redis16425、真实Nest16426验收16组通过,包含查询、隔离、篡改、旧算法、重放、幂等及MD下载,短信/批次数均0。仅安全辅助日志隔离为空实现,不将日志持久化标为验收。未启动发送或回调WorkerRedis5.0.14提示建议6.2+,实际nonce命令通过。样本初轮漏carriers、参数错误码断言与真实DTO不一致、幂等样本漏credentialId,修正并保留失败日志;不视为业务缺陷。另一本地PG16安装缺dict_snowball,使用既有完整pgsql安装启动本轮隔离实例。
CUA本轮可用,实际后端文档三尺寸1600×1000/1366×768/390×844无页面横向溢出;1.4/2.2/2.3顺序、36个具名示例、目录跳转、复制、刷新、错误码检索和空结果通过,控制台无warn/error。当前仅本地页面,线上验收另记。证据目录.local-data/http-signature-20260915;最终精确候选门禁/提交/推送/发布后补。无预生产或业务配置修改、无短信发送。
## 2026-09-15 HTTP改造与追加四项合并实施(进行中)
前一接口协议提交18ecf8045f488af349812938d513753aa25ec237已推送;用户暂停发布时原计划仅preflight成功,prepare停在密码提示,已停止本轮终端,测试保持4665079。后续四项与此前协议一并交付,不取消前述改造。main/远端18ecf80、暂存空;已有metrics、tools/release及文档保护。
本轮统一签名/引流三网列组件、隐藏认证申请入口,新增两端共用浏览器签名页;@noble/hashes小模块用于HTTP站点本地计算,不上传秘密。33文件158前端测试、类型/生产构建、lint/style/CSS15门禁通过;组件测试曾标签/断言匹配失败,修正后全量通过,保留初始日志。生产构建浏览器POST/GET文档向量、复制、清空、1600/1366/390尺寸通过;Vite dev导航超时,使用同源码production验收入口。完整在线登录页另验。
真实测试旧版本72条参数请求发现上行号码过滤未校验(B01),HTTP独立应用被CMPP开关拒绝(B02),均已最小修复并补回归。首轮GET误用空字节摘要导致测试401,按旧协议应为{}摘要,修正后69/72通过,3条为B01真实缺陷;没有短信创建。一次正常发送因B02返回422,未创建短信。API上一轮75套825项通过,新增B02后全量及真实发布候选门禁待完成。
用户明确授权仅专用企业、应用、模拟通道及号码发送/回执/Webhook和必要测试配置。已新建HTTP隔离0915企业、2应用、3条远端loopback模拟通道、测试余额及对应流水;原客户/通道无修改。模拟器仅接受指定测试账号与号码、最多40个Submit,不连接运营商。当前准备上线新代码后完成真实链路复验及测试收尾。证据.local-data/http-complete-20260915。
用户要求安全复用sudo密码:已存当前Windows用户DPAPI加密文件(仓库外),不写明文;本机受保护未跟踪release.py仅新增test专用--sudo-credential及测试,47项工具测试含5项平台跳过。发现PowerShell7模块路径影响PowerShell5解密,调用时移除继承PSModulePath后真实只读SSH通过。工具变更后新计划绑定新摘要,不复用旧preflight。工具仍未提交,不能以应用SHA冒充工具版本。后续发布/推送及完成证据另行追加;预生产不在范围。
### 2026-09-15 HTTP 全链路复测:引流 URL 冒号边界误拦截(进行中)
- 测试环境 c781313 的 78 项异常参数、新签名及旧协议拒绝用例全部通过。已获得实际模拟 Submit、DELIVRD/UNDELIV、黑名单与频次拦截、退款、上行及 Webhook 503 后自动重试成功证据。
- 真实发现 HTTP-0915-B03:正文“调测内容:https://qa0915.example.com”的识别结果是完整 URL,但 drainageTargets 向左扩展时把归一化后的中文冒号加入 URL,抛出 DRAINAGE_INVALID,已批准引流资料仍不能发送。此问题属于 URL 边界误判,不能把误拦截算作报备校验通过。
- 修复目标:显式 http(s) URL 前的文字冒号不属于 URL;继续扩展恶意域名后缀、userinfo 和 query,保留已有安全校验。最终复测与发布状态后续追加。
- 定向回归:修复前 2 失败/20 通过,修复后 22/22 通过;候选全量门禁及部署后真实 URL 验收待执行。
## 2026-09-15 HTTP 接口联合改造测试环境验收收尾
代码 c781313 与补充修复 cbc4a03 已提交推送,测试环境精确运行 cbc4a033251c7496414b1e7aa6233ed49bd108ec17:36 核验)。包含最新签名协议、双端计算页、报备三列及认证入口隐藏,未遗漏前序范围。最终后端 830/830、前端 158/158,类型/构建/质量门禁通过;最终真实参数回归 78/78,前序独立配置回归 15/15,引流六分支复测通过。25 条隔离记录、13 次模拟 Submit,账务余额与流水一致、冻结净额 0、队列 pending/lag 均 0。Webhook 成功/503 重试/400 终止/超时上限及上行已验收,16 次业务回调 HMAC 正确。专用配置、凭据和模拟器已停用,hosts 精确恢复,未发送至真实运营商。
最终标准 verify 唯一提示为业务计数 +6 条短信/+2 次 Submit,已与本轮六个引流用例逐条核对,工具状态保留 deployed-needs-review,不伪造全绿。浏览器连接超时,测试环境登录后 UI 尚未验收;独立“验证码限制”的具体规则仍需明确。预生产未操作,容量治理未完成。完整证据、失败记录、时间、版本与恢复资产见 [HTTP 接口联合验收记录](http-api-acceptance-20260915.md)。
## 2026-09-16 产品统一更名为聆界短信平台(本地完成)
- 用户要求将项目产品名称由CMPP平台更名为“聆界短信平台”。设计与兼容边界维护于version-3.0-baseline.md“产品名称统一”,需求及TC-BRAND-20260916-01/02同步。
- 已更新浏览器标题、登录页标题/Logo替代文本、双端AppShell品牌名称、充值回执替代文本、平台Swagger/客户OpenAPI名称、HTTP文档页面与MD、两类报备导出工作簿作者,以及当前根规范/UI规范/需求/测试用例/版本基线名称。历史实施记录不追溯改写;CMPP协议、工程包名、服务/存储标识、目录路径、业务逻辑和接口签名不变,工程版本保持3.0.0。
- 11:27 CST验证:前端33文件158项通过,后端76套831项通过;前端tsc --noEmit及最终Vite生产构建、API tsc -p tsconfig.build.json通过;结构质量检查、包体预算检查、git diff --check通过。构建HTML标题与编译后的HTTP文档渲染函数确认新名称。当前终端npm不在PATH,直接调用仓库node_modules内对应CLI完成等价验证,未改全局环境。
- 质量门禁遗留:定向ESLint在official-export.service.ts报告47个原有未使用导入错误,另有LoginPage/RechargeReceiptDialog共3个既有警告;Prettier在official-export.service.ts和RechargeReceiptDialog.tsx报告原有格式问题。已将名称替换在内存中还原后复核,两文件修改前格式检查仍失败、official-export修改前仍47个lint错误;未以整文件格式化扩大范围,不能宣称全部门禁通过。初次Vite构建存在既有大chunk提示。
- 真实浏览器三尺寸、登录后页面、Swagger真实API及报备导出验收未执行;当前项目无可解析的Playwright依赖,未安装依赖或将隔离测试冒充真实业务验收。未连接/修改线上服务,未发送、补发、重投短信或改业务配置。
- Git核验main/实际远端仍为86cb9aea36f7759eef9cc4f0949a9bca7f85617b,暂存区空。已有metrics、发布工具、部署脚本、版本及文档草稿保留,仅对共享文档精确替换名称/追加本轮记录。本地修改完成;本地提交、推送、测试部署、预生产部署均未执行。
### 2026-09-16 更名本地提交范围核对
用户追加授权本地提交。本次精确暂存更名代码、规范标题及需求/用例/进度中的更名段落;package及lock版本、main.ts的Swagger版本变更和既有未跟踪version-3.0-baseline.md草稿不纳入本次提交。3.0.0版本元数据仍留在工作区,提交不代表版本标识已发布。前述测试为本地工作区结果,不冒称隔离候选精确提交的全量验证。既有metrics、发布工具、部署脚本与其他文档改动保留。推送、测试部署及预生产部署未执行。
## 2026-09-16 五项联合整改启动
用户确认实施phase-4-send-pipeline-redesign.md第10节,并授权通道测试免签名/引流检测、HTTP参数化发送调试、监控告警人工清除与刷新保留真实快照;提交、推送及测试环境发布/充分长短信验收。main=a0209f93bc8eee6cb08a9d7cace4163b26749ae6,实际远端86cb9ae,暂存区空。61份已有修改/草稿保护摘要及原文位于.local-data/five-fixes-20260916,前轮版本及发布工具不自动纳入。测试SSH首次连接超时,尚未认证;本地工作继续,部署/真实环境待连通后执行。尚未修改业务代码或操作线上状态。
## 2026-09-16 五项改造开发进展(18:00,本地,未提交/推送/部署)
- 承接用户确认:执行发送链路第10节、通道测试跳过签名与引流、HTTP参数化真实发送调试、告警手动清除、监控失败保留最后成功快照。测试机开机后SSH已恢复;在线版本仍为cbc4a033251c7496414b1e7aa6233ed49bd108ec。预生产未操作。
- 新增耐久工作/事件日志及告警事件/采集水位迁移;按工作→消息→账务/批次顺序收尾,补发选路限速在事务外,通知/账务/Outbox入同一事务。修复探测异常被吞、事务会话缓存、迟到结果重复计费、超时终态覆盖及多消息批次进度事务隔离细节。
- 通道测试除去入口检测,同时修正Gateway最终引流授权入口;仅按真实Submit归属确认的无租户/无批次测试消息豁免,普通客户消息仍校验。
- 本地隔离PostgreSQL 16434/cmpp_qa_completion_20260916已执行全量106迁移(后续UTC默认值细化尚需新库重放)。真实数据库验证并发24事件/12唯一事实、事务故障回滚与接续、租约接管、三段齐段成功、CMPP/HTTP通知幂等、非零975计费/超时退款一次/迟到回执、三段失败只创建一份后继Submit/Outbox。路由与限速在补发事务测试中被隔离,不作为真实路由/Redis/Gateway通过依据。
- 证据脚本tools/testing/verify-attempt-completion.mjs;日志.local-data/five-fixes-20260916/completion-integration.log。故障注入故意产生completion_retry_wait,不是线上异常。
- 最近定向隔离回归:发送链路+最终通道校验142/142;发送链路+监控服务147/147(范围重叠,不相加);HTTP页面/签名15/15。后端类型检查通过。后续改动须复验;真实浏览器、完整回归、故障恢复矩阵、实际CMPP/Webhook投递与测试部署仍未完成。
- 保护既有61项修改快照,未把原metrics/发布工具/文档草稿视作本轮内容。此前产品命名提交a0209f9尚未推送。本轮新增metrics两处接入需精确hunk暂存,不能包含此前指标修改。
### 2026-09-16 18:25 本地验证与交付准备
前端全量35套163项通过(115.33秒),后端77套835项通过(171.189秒);类型检查通过。新增隔离PG全量106迁移重放和11组耐久工作/告警验证通过,包含独立OS进程并发及挂起旧消费者恢复,日志在.local-data/five-fixes-20260916。第12次失败转人工处理及数据库告警采集已补验证;日志中的故意故障注入不得当线上异常。最新采集改动需候选精确提交回归。
真实环境尚未部署;独立Playwright获用户允许,专用Edge等待用户完成登录。测试Outbox发布开关及独立进程已核验。为通过更名涉及文件的既有门禁,仅移除official-export未使用导入并格式化该文件及RechargeReceiptDialog,业务规则不变。保护项未纳入;开始准备精确暂存,尚未提交/推送。
### 2026-09-16 19:10 测试环境验收发现并修复Gateway即时应答竞态
五项应用实现a350aca及更名a0209f9已提交/推送,测试环境按标准工具部署a350aca(计划20260916T104026-a350aca88336-7f5f9fd9)。候选前端163项/API834项及类型/格式/lint/样式门禁通过;与工作区API835项相差1项来自受保护的既有metrics测试,未夹带。106迁移完成,预生产未操作。
隔离真实HTTP/CMPP/Gateway/PostgreSQL/Redis验收已观察2/3/4段、乱序及重复回执、失败后唯一后继、最终失败退款、断线CMPP恢复9份客户分段回执、不申请回执不创建CMPP投递、Webhook TLS/503/超时后自动恢复。HTTP页面真实202及报文展示通过;无签名且含未报备链接的3段通道测试真实受理。监控实际恢复告警留存,故障注入保留最后真实快照并恢复刷新。完整对账及三尺寸页面/人工清除收尾仍在进行,不宣称全部通过。
对账发现两条测试消息首尝试只提交2/4、1/3段后误判SUBMIT_TIMEOUT,各自动产生一个后继。已只读确认Gateway发送后登记pending的窗口;真实TCP在未修代码CMPP2.0第206次、3.0第7次复现,详见方案10.12。按同一mu→sendMu锁序保护写包和等待者登记;修复后两协议各500次×5轮共5000次即时应答通过,Gateway全量go test ./...与go vet ./...通过。需重新提交/标准部署该补充修复并新增目标环境样本验证;原异常保留,不将异常重试样本计为无重复发送通过。
### 2026-09-16 19:20 五项整改测试交付收尾
本轮更名与五项实现已提交推送,测试最终应用010ba3216889032a6160cdb14d8536b616ae7102;首次a350aca验收发现即时SubmitResp误超时竞态,已补本地真实TCP复现/修复/全量Go门禁/标准第二次发布,新增6条2/3/4段全部一次提交成功。前端163项/API候选834项及生产构建通过,106迁移完成。
最终20条隔离业务短信加1条通道测试;20账单、20HTTP业务通知均完成,CMPP9份客户分段回执实际接收并ACK,不申请回执样本无CMPP目标;独立503及超时回调均自动恢复。修复前2条误超时自动补发保留为异常证据;最终24业务Submit/24耐久工作全部完成,三个Stream pending/lag均0,账户流水对齐。无签名/未报备链接3段通道测试delivered且不生成客户通知。监控三尺寸、真实快照失败保留/恢复、恢复告警留存和一次人工清除审计通过。
标准工具最终deployed-needs-review仅提示业务数量变化:119597/130835→119603/130841,精确对应补测6条/6次,已人工对账;版本/资源/服务及日志检查通过。工具businessAcceptance未自动更新,不改报告伪造完成。全部证据、原失败、耗时、恢复点、磁盘增量/治理未完成项及矩阵未覆盖项见[交付验收记录](release-20260916-test-completion.md)。预生产未操作,未做性能容量对照、真实72小时等待或全部逐断点/旧版恢复演练。
本轮专用应用/接口/凭据/Webhook和两个模拟通道已停用,模拟器/隧道/监听器/临时hosts/本地隔离PG停止或撤销;短信账务及审计数据保留。61项旧工作保护核对完成,共享文档/metrics只增本轮内容。最终收尾文档及测试日志标签修正单独提交推送,不重启应用。密码及会话不进入Git。
## 2026-09-17 签名退网与四TAB查询优化方案(未实施)
- 授权:只读核查并编写方案。main与实际远端4eb7b16、暂存区空;09:37预生产实际010ba32。原50项已有修改/草稿继续保护,不纳入本轮交付。
- 已核查代码、线上编译入口、PG检测结果/真实索引及本会话CPU取证:04:00:0104:04:07产生5831条检测,逐维度重复扫描与CPU窗口高度吻合,缺历史进程CPU/SQL采样不能唯一归因。当前TAB状态独立,但企业/通道各自调用同一全量heatmap;质量及未报备所有日期实时查库;活跃度检测快照不做近三日刷新,历史又受当前报备维度影响。
- 用户确认每天凌晨刷新T-1~T-3;热力图保留所选日D之前30天,不新增当天列。方案明确实际T和D、T-4冻结、迟到回执、历史维度/未报备判定冻结、生成失败/缺口、批量聚合/索引验证、任务租约/fence、跨日去重及预警通知分离。
- 新增[优化方案](signature-quality-optimization-plan-20260917.md),向既有签名清退设计追加替代关系,需求及TC-SQA-20260917-01~16同步,全部实现验收用例待执行。取证脚本与结果在忽略目录.local-data/cpu-20260917,不含认证秘密。
- 本轮仅执行文档路径/编号/规则一致性及diff检查;未执行业务回归、迁移、重算、登录后四TAB真实HTTP/浏览器验收或新旧SQL性能对照。没有把既有组件mock测试当本轮真实功能通过。
- 本地修改:五份文档;业务代码无改动。本地提交、推送、测试部署、预生产部署:均未执行;未发送/补发/重投短信、未改余额/通道/客户配置或触发外部通知。
## 2026-09-17 上行待认领只读诊断(未修复)
- 预生产010ba32共253条上行:159待认领、92已匹配、2未匹配。147条共享接入号多应用直接返回ambiguous,其中143条接收前72小时实际仅有一个候选应用的同通道accepted发送;另12条手机号多记录全部同应用。已用当前线上编译匹配函数与真实PG只读事务复现两个分支,未启动调度/写入/投递。
- 明确应用归属与原短信唯一关联不能混为一谈;155条可进一步收敛不等于可直接自动认领。另发现窗口按处理时刻、无上界/通道限定、路由take10先截断等风险;现有89条自动关联只读边界核对未见手机号不符/未来关联/缺同通道accepted证据。
- 详见[上行匹配诊断](uplink-matching-diagnosis-20260917.md),区分已证实根因和未发生证据的风险;取证在.local-data/cpu-20260917/uplink-*。未执行HTTP/浏览器验收、写入故障注入或代码修复,未认领/发送/重推上行。
- main/实际远端4eb7b16、暂存区空;已有保护项及前轮签名质量方案保留。新增诊断、追加进度,执行文档路径和diff检查;本地提交、推送、测试部署、预生产部署均未执行。
## 2026-09-17 上行归属修复与签名质量日报优化(本地实现)
- 授权:修复上行待认领问题、执行`signature-quality-optimization-plan-20260917.md`并本地提交;本轮不推送、不部署,不操作历史上行认领/重推,不执行真实短信和外部通知。开始及提交前main/实际远端均4eb7b16,暂存区原空;65项已有修改/草稿已做摘要及副本保护。
- 上行:共享接入号不再提前判歧义;receivedAt前72小时同通道accepted记录按应用归并,原短信不唯一则不填原短信编号。供应商MO编号独立保存;事件入库/候选/通知、人工认领/通知分别事务化,重复事件和并发认领串行核验,通知只创建耐久意图。既有159条待认领没有自动认领/重投。
- 日报:六个新增表和版本/日期复合外键;03:00三日刷新,T-4起冻结,历史页面不回查明细;缺口、刷新/失败、截止时间和事后补建来源可见。企业/通道新接口只返回各自分页维度;四TAB查询/日期/筛选/错误独立,保留D-1~D-30。退网批量accepted窗口去重,规则/日报版本首次认领冻结,失败重试沿用;检测与通知等待完整上游批次,不重复生成历史预警。
- 真实验收:本机独立PostgreSQL16端口16435,新库108项迁移通过(含单独非事务并发索引)。`verify-signature-analytics.mjs`12组验收通过:当天/历史数据源、跨日去重、2/3/4段、缺片、旧无分段明确回执、加权耗时、三日刷新/冻结、旧版本保留、页码越界总数、失败回滚/重试、双worker/fence与规则快照。`verify-uplink-matching.mjs`3组通过:重复事件一份CMPP及一份HTTP通知意图、并发认领、存储故障整笔回滚并恢复;没有启动外部通知消费者。
- 前端:生产构建,完整真实Nest应用+PG+隔离RedisEdge/Playwright在1600×1000、1366×768、390×844检查首次、四TAB查询、刷新,补充历史日报、抽屉、企业服务端筛选、TAB日期独立和请求失败仍显示上次真实结果;28个相关请求、页面异常0。匿名401、非法分页/维度400、正常查询200。Browser插件/技能未提供,沿用用户已授权的独立Playwright;会话只在内存传递。
- 自动门禁:API78套842项、前端35文件163项通过;API/前端类型与生产构建、结构检查、ESLint、Prettier、CSS治理/样式、Bundle预算通过。ESLint仍有发送链路既存测试27项any警告,无error;构建既有chunk提示在预算内。覆盖率门禁见下方补充;Gateway代码未变,无本轮Go/实发/性能容量结论。
- 性能:30000消息/600维度活动聚合,旧10343.912ms,新624.940ms,热缓存下降93.96%accepted逐维度一致。原EXPLAIN单维度源访问30113行×600外推18067800,新批量60039;样本外推不冒称全批实测。未测整机CPU、365日真实大批次、峰值内存、p95和短信队列;不能据此宣布预生产CPU问题已完全解决。
- 原始证据保留于忽略目录`.local-data/signature-optimization-20260917/`integration-6、uplink-real-3、browser-5、performance-1及最终门禁日志。前面失败(迁移SQL未生成、缺carriers、测试断言漏计新增样本、账号缺email、浏览器按钮名称/模糊标签定位)已修正后重跑;不删除原失败日志。Redis5.0.14.1的BullMQ版本建议及PG驱动在嵌套关系读取时的并发query弃用提示保留,未改依赖版本。
- 文档:优化方案第8节、上行诊断第6节、需求/测试用例/清退设计同步。本地提交仅纳入本轮代码、两项迁移、验收脚本及相关文档精确新增段落;已有metrics、版本、部署和发布工具修改保留。推送:未执行;测试部署:未执行;预生产部署:未执行。历史日报补建、真实外部MO投递、线上权限/供应商扩展码、午夜冻结过程、现场恢复/回退及完整容量指标未验证,按后续授权实施。
- 最终补充:API全量覆盖率语句67.76%/分支52.88%/函数68.62%/行70.54%,增量覆盖率87.98%/77.03%/95.91%/91.22%,均通过各自门槛;前端覆盖率88.48%/85.09%/84%/88.19%163项通过。固定日报refreshFor为任务启动日后,类型检查、9项日期测试及真实PG模拟跨午夜通过:T-1跨日仍记录原启动日,T-3跨入T-4拒绝发布且回滚。最终browser-final仍为三尺寸28请求、页面异常0。最后停止本轮本机PG/Redis/预览服务,保留验收库及日志资产。测试基于受保护工作区,发布时仍由标准工具核验精确提交证据;未把本轮本地检查冒称部署验收。
## 2026-09-17 首页运营数据整改方案与 UI V1(未实施)
- 当前授权仅编写方案和设计图。main为627fa7e,实际远端main为4eb7b16,本地领先2提交,暂存区为空;已有修改保留。本轮未连接线上环境或改业务代码。
- 已核对AdminHome、dashboard查询、Prisma字段、Gateway回执时间、intake、分片补偿、货币单位和现有规范。旧统计按queuedAt,而新需求按今日收到回执;billingUnits适合作为去重后的业务分片当量,segmentTotal用于完整性核验;gatewayReceivedAt保留当前Gateway实际接收时刻。线上时间覆盖和成本数据仍待核验。
- 新增[方案](homepage-receipt-metrics-redesign-20260917.md)及[UI V1](designs/homepage-20260917/homepage-v1.png),内置imagegen生成,提示词同目录保留。明确9指标、两个点击才查询的日期明细、跨日整条成功/一次收入、成本快照、返还和运营状态。消费排行暂按替换为返还区域设计,待用户反馈。
- 需求和HOME0917-01~14待执行用例入口已同步。完成图中文字/层级和示例加总检查、文档相对路径与diff检查;这不是业务、浏览器或性能验收。未运行回归/类型/构建,因为未修改业务代码或CSS。
- 本地修改:方案、UI图/提示词及三份文档追加。本地提交、推送、测试部署、预生产部署:均未执行。未发送/补发/重投短信,未改账务、客户或通道配置。
## 2026-09-17 首页 UI V2 修订(仅设计)
用户要求顶部三组缩小至原约三分之一,改为一行三块紧凑指标;“今日回执收益”改为“今日营业状况”,今日企业消费排行按现有六列及详情/导出入口保留,不替换为返还模块,运营状态保留。此修订优先于前轮方案的返还区域解释;方案顶部已标明替代关系。内置imagegen基于V1重绘[UI V2](designs/homepage-20260917/homepage-v2.png),原图保留,提示词同目录。已视觉核对指标、排行列和运营状态;全部数字为示例,无业务代码/CSS修改,无业务验收、提交、推送或部署。
## 2026-09-17 首页整改实施(提交推送前核验)
- 按V2完成紧凑三栏、9指标、两个按需日期明细;保留企业消费排行并增加今日返还金额列,详情/CSV同步,运营状态保留。新增独立home接口,旧客户端不变;长短信以业务单位补齐分母、完整成功才计成功片/收入,跨日与重复回执、通道成功片成本分别核算。
- 四个统计表、两项迁移(本地新库110迁移通过),耐久触发失效、原子批次投影、版本快照、15分钟用户绑定与安全回收;原始短信/回执/账务不改写。本地真实PG、Nest API、Redis验收通过,三尺寸和完整桌面截图见[实施方案第9节](homepage-receipt-metrics-redesign-20260917.md#9-2026-09-17-实施与验收结果)。无Browser技能,使用既有授权Edge/Playwright。无短信发送或外部投递。
- API854、前端163及覆盖率门禁通过;类型/生产构建/定向ESLint/样式/结构/CSS治理/包体检查通过。真实数据库故障与并发认领、四日及缺片/跨日/重复/退款边界通过;页面无明细预请求,错误保留真值、CSV/详情通过,页面异常0。本地样本2020消息/6000新增片,总览p95约55ms、明细约20ms,不推断线上CPU/容量。
- 原始证据 `.local-data/homepage-implementation-20260917/`。数据库端口、Redis旧RDB、浏览器两个定位失败已修正并保留原日志;Redis版本建议保留。尚未验证线上源时间覆盖、真实大数据与现场回退、完整供应商短信闭环。
- 起点main627fa7e、实际远端4eb7b16、暂存区空;67项原工作已备份并核对保护。仅本轮代码、迁移、方案/UI/截图、验收脚本和文档精确追加进入提交;版本/metrics/发布工具等不夹带。用户授权提交推送,不含部署;测试环境、预生产环境均未改动。最终提交与推送结果单独补记。
## 2026-09-17 有效签名唯一性与导入补资料兼容
- 授权:修改并本地提交。起点 main/实际远端均5e4d644,暂存区空;保留版本、metrics、发布工具及文档已有修改,本轮不推送、不部署。
- 根因:创建/更新无名称查重,数据库仅ID唯一;状态审核/恢复也可重新占用名称。按 [通道与报备设计](phase-4-channel-reporting-plan.md#2026-09-17-有效签名名称唯一性) 增加有效状态查重与两个部分唯一索引,空应用独立处理。新增/改名/换应用/审核/提交/恢复均覆盖,并发冲突返回409。补齐Prisma7 pg驱动真实P2002嵌套元信息识别,不吞其他数据库错误;audit.service清理原未使用导入并格式化,业务改动仅签名防重。
- 批量导入保留原ID和字段合并逻辑;优先有效记录,其次停用历史记录;审核时重查及并发创建冲突后补资料,未映射资料、用途、链接保留。已指定的目标不暗中替换为另一条签名。
- 验证:本机独立PG16、Redis16436、完整Nest真实API;新库cmpp_qa_signature_unique_v3全部111迁移成功。verify-signature-uniqueness.mjs七组通过(TC-SIG-UQ-20260917-0107),12路新增仅一条201/其余409,三个并发导入同一ID;两类索引直接写入阻断、状态恢复、空应用变更、租户隔离、真实驱动冲突和临时历史重名表迁移回滚均通过。未发送短信、未创建外部通知消费者业务、不修改线上资料。
- API全量80套868项及覆盖率门禁通过(语句67.90%、分支53.22%、函数68.78%、行70.68%;新防重模块语句/函数/行100%、分支96.66%)。API构建/类型检查、定向ESLint/Prettier及diff检查通过;最终仅清理旧未使用导入后补跑定向测试。前端/Go无改动,未重跑无关测试。
- 原始证据在忽略目录.local-data/signature-uniqueness-20260917/。保留初次测试夹具缺邮箱、映射字段键错误、根目录Prisma配置路径错误及真实驱动冲突识别失败的日志,修正后新库v3验收通过;Redis5.0版本建议及pg查询弃用提示仍存在,未扩展升级依赖。
- 历史兼容:线上有效重名尚未盘点;如存在则迁移明确失败并整体回滚,不能自动删除或合并。未执行测试/预生产部署、线上迁移、浏览器页面验收、文件上传/解析及MinIO回归;本轮真实导入验收覆盖资料暂存/审核应用层,文件解析路径未改变。
- 本地修改、测试和需求/设计/用例同步完成,提交前仅本轮文件及共享文档精确追加进入暂存;其他原始修改保留。提交号在交付回复中报告;推送、测试部署、预生产部署均未执行。
## 2026-09-18 长短信三项缺陷整改(本地修改及提交)
授权范围:修复、测试、文档及本地提交,不推送/部署。开始核验本地main1676cfe、实际远端main5e4d644,暂存区为空;版本、metrics、发布工具/脚本及其他文档草稿保留,不纳入本轮。设计先补第10.13节。
已修复:同次最终失败/成功及明确回执超时不再重开收尾,后续失败片仅审计;矛盾回执留原始记录并产生异常,保持账务和通知;统一Submit和Segment候选按通道/上游身份消歧,分片更新限定发送尝试,显式submitId不再被同Msg_Id另一尝试覆盖。保留unknown、未齐片、历史超时恢复和同供应商跨连接匹配。无需迁移,无线上历史数据修正。
验证(2026-09-18):新隔离cmpp_qa_receipt_fix全111迁移通过;verify-receipt-finality.mjs真实PG八组场景通过,重复终态选路由复现的2次变为1次,跨尝试更新2条变为目标1条,失败/退款/失败通知保持一致。选路仅在确定无可用路由边界隔离;账单用已退款快照,非线上退款。verify-attempt-completion.mjs十一组真实PG回归通过,包括24并发、双OS进程、回滚/接管/fence、三段通知、非零账务与唯一补发Outbox。
API全量81套/880项通过并达覆盖率门禁(语句67.73%、分支52.89%、函数68.76%、行70.60%);最终小幅兼容调整后定向2套/150项及八组真实PG、十一组并发恢复复跑通过。TypeScript生产构建通过;本轮文件ESLint零错误、30条既有any警告,Prettier及diff检查通过。新匹配器单测行覆盖100%、分支89.65%。早期旧mock未提供真实关联造成14项失败,补全关系及查询形状后通过;未降低关联约束。真实PG保留pg驱动并发query弃用警告,未出现事务失败。
可重复运行:先构建api并迁移独立本机cmpp_qa_*库,设置COMPLETION_TEST_DATABASE_URL后运行tools/testing/verify-receipt-finality.mjs和verify-attempt-completion.mjs;脚本拒绝非本机或非隔离库。原始日志保留.local-data/receipt-fix-20260918/,不进Git。此轮仅调用真实后端服务/持久层,不启动Gateway、HTTP通知投递或在线发送。前端/Go未变,未重跑其验收;目标环境、Redis/Gateway完整网络闭环、线上CPU降幅未验证。不得把本地通过视作测试/预生产已修复。本地隔离数据库进程收尾关闭,数据及日志保留。
## 2026-09-20 签名质量四段条、通道运营商缩减及模板拒收策略
- 基线:本地main c20c2246b263b22a6a84c8ac10d9f320197a8fb6,实际远端main 5e4d644788b453528e513b1c14c28b120e221b64;开始暂存区为空。保留版本3.0、metrics、发布工具/部署脚本、手机号规则迁移及其他草稿,不纳入本轮提交。
- 需求/设计:first-version-development-requirements.md“2026-09-20”节、template-optout-policy-design-20260920.md、phase-4-send-pipeline-redesign.md本轮补充;用例TC-OPT-20260920-0112。
- 根因:原质量条仅绘制成功比例;通道后端在检测到被活动通道组引用的已移除运营商时直接拒绝;原发送链没有模板/通道内容改写及尝试内容快照。本轮改为互斥四段条、仅悬停未知数据;允许能力缩减并保留原路由能力过滤;模板策略独立匹配且不得改变计费及Gateway分片数,单条/微批/补发共享,原文/Submit/Outbox同事务。Gateway授权按尝试快照核对,短信详情增加原文与尝试内容,客户端只返回自身原文。
- 迁移:新增20260920090000_template_optout_policy,旧内容不重写。初次工作区数据库包含113条迁移;随后复制原已提交迁移及本轮迁移,排除未提交20260918110000_refine_mobile_drainage_prefixes,在独立cmpp_qa_optout_commit_20260920执行112条迁移全部通过,并重新执行真实API/PG和浏览器验收。
- 自动验证:API全量85套/971例通过,覆盖率语句67.95%、分支53.55%、函数68.91%、行70.72%;前端37文件/168例通过,现有覆盖率门禁88.48%/85.09%/84%/88.19%。TypeScript、API构建、前端production构建、npm run lint、format:check、stylelint/CSS治理、bundle:verify及git diff --check通过;lint保留9条既有hooks警告,production大chunk提示但包体门禁通过。Gateway go test ./...及go vet ./...通过,队列契约未改动。
- 初次覆盖率运行并行竞争资源,前端24例触发原5000ms超时;串行安排并限制maxWorkers=2后168例全通过,没有放宽时限或断言。新增通道单测首次缺少required desiredConnections导致类型失败,补齐测试夹具后971例全通过。原失败记录保留。
- 真实验收:tools/testing/verify-template-optout.mjs使用真实NestJS、PostgreSQL16及本机Redis5.0.14.1(运行库提示建议6.2+,已记录环境差异)。验证登录/客户端入口拒绝、外应用/非法策略拒绝、固定分片保护、审计持久化、活动通道组引用下缩减保存、direct_send无templateId仍应用、单条及微批快照、换通道补发恢复原文、费用字段不变、事务回滚及旧Outbox快照不变;Outbox全部pending,未启动Gateway/SMSC或发布器,未实际发短信。
- 浏览器:当前环境无Browser插件,按前端验收技能使用独立Playwright/Edge、真实API及会话,1600×1000、1366×768、390×844分别验证策略保存、固定勾选、四段条、刷新/跨路由、原文/尝试详情、通道弹窗减少运营商后保存及PG回读,无pageerror。发现并修复既有窄屏查询遮挡/弹窗运营商溢出,仅增加同页响应式规则,保持桌面布局;已查看截图核对。
- 证据:.local-data/template-optout-20260920/ 下 api-coverage-final.log、frontend-coverage-final.log、migrations-commit.log、browser-accepted.log、lint-accepted.log、format-accepted.log、api-build-accepted.log、build-accepted.log、bundle-accepted.log、go-test.log、go-vet.log及template/quality/detail/channel三尺寸截图。验证脚本不保存会话或密码,fixture.json仅含隔离业务ID。
- 边界/未执行:未操作测试或预生产配置;未推送、未部署、未执行运营商发送/实际回执推送/资金结算;冻结历史报表不重算。测试证明本地真实持久化和页面,不能冒称线上或实际送达验收。提交仅纳入本轮源文件、迁移和本轮文档增量,提交号以本轮Git提交为准。
## 2026-09-20 CMPP 字段兼容性方案实施与本地提交
- 用户授权:在另一个会话最新代码基础上审查侧边方案、执行修复并本地提交。核验 main 为 b24cd7c,远端 main 为 5e4d644,工作区有其他会话修改,已保护并仅暂存本轮文件/共享文档新增段落。不推送、不部署、不修改预生产数据/配置、不重投真实短信或回执。
- 实施 CMPP-FIELD-0106:七个 uint32 字段 BigInt+CHECK、显式协议数值适配与响应序列化、2.0/3.0 回执布局、序号 0 与在途回绕保护、CONNECT 非零完整状态、3.0 大包上限及计数/长度校验。并发实测发现 Prisma 空更新 upsert 首次竞态 P2002,增加同 receiptKey 已持久化确认,不掩盖其他失败。与最新终态/发送尝试归属代码兼容;仅清理受影响模块无用 import/格式,无业务规则扩展。
- 验收:API 全量及增量覆盖率均 87 套 / 990 项;API 构建、Gateway 全量 test/vet、嵌套 gocmpp test、5 个队列契约、变更代码 lint0 error/32 存量 warning)、格式与 diff 检查通过。额外嵌套库 vet 存在原有两条 WriteByte/ReadByte 标准接口签名提示,未隐瞒或跳过配置,详细登记于方案第 10 节。
- 真实本机 Nest callback + PostgreSQL + Redis0/2147483647/2147483648/4294967295 七字段、最大 uint64 字符串、并发/批量重复、上行去重、大非零 ACK、非法输入无写入、历史 NULL 不重开通过。另真实 PG 终态 8 项、完成态 11 项通过。CMPP 2.0/3.0 本机真 TCP 回执、零序号恢复/ACK、认证状态 256/max、99 号码 3471/3490 与异常长度拒绝通过。不是线上供应商/客户验收,也不是整套进程联调。
- 迁移:从已提交基线排除其他会话未提交 mobile-rule 迁移,新空库部署 113 迁移成功。七表 21 行小样本证明末表负值使此前 DDL 整体回滚,锁等待 5 秒失败回滚,旧值/NULL/7 索引保留;最终有效扩容约 106ms、WAL 81800 字节。生产规模、真实发布备份/恢复与 3.0 供应商非规范布局抽样待上线前补验,禁止把小样本当容量承诺。
- 证据:.local-data/protocol-fields-20260920/ 保留原失败和复验日志;最终 real-chain-verified.log、migrate-verified.log、api-coverage-final.log、api-incremental.log、go-final.log、gocmpp-final.log。专用 Redis 5.0.14.1 的真实 Stream 验证有效,但低于 BullMQ 推荐 6.2;PG 并发 query 弃用提示记为存量,未修改依赖。测试脚本要求全新本机 cmpp_qa_* 数据库,避免固定最大 Msg_Id fixture 跨轮冲突。
- 方案/需求/用例同步:docs/cmpp-protocol-field-compatibility-remediation-20260920.md 第 10 节完整映射 T01~T18。无前端/CSS改动、未执行浏览器回归;客户端 JSON 类型保持不变。业务状态与资金未通过迁移回填。后续所有相关进程须与 BigInt schema 配套,旧客户端不能读取高位值;应用回退不执行 bigint 缩回 integer。
## 2026-09-21 未报备签名漏统计修复与本地提交
预生产001d5f2只读诊断发现:【宜都市万商市场投资有限公司】今日64条、当前应用有效同名签名0,SQL_ASCII使中文排除字符集合误判,旧提取全部NULL。用户随后授权修复并提交;新增共用SQL提取函数,实时与日报均按完整括号排除嵌套,保持原日期/应用/签名库/分页及冻结历史规则,无迁移。15:33:24预生产READ ONLY对照旧0/新64,不是线上发布。
本地真实PG16.14 UTF8/SQL_ASCII新空库各113项已提交迁移;26输入、64条案例、租户应用/签名状态、日期边界、13组两页、三类搜索、参数校验、真实日报落库和Nest控制器HTTP、冻结历史保护均通过,Submit=0。首次分页夹具用不支持的2返回400,改现有10并新库复验通过;旧运行目录initdb缺dict_snowball改用完整既有运行库通过,失败证据保留。API87套990项全通过,覆盖率68.05/53.73/69/70.77达到门禁,生产构建、定向lint/格式通过。
代码与需求口径一致,相关需求和TC-UNREPORTED-ENC-001004同步。原始证据.local-data/unreported-signature-20260921/,详情见[诊断及修复记录](unreported-signature-diagnosis-20260921.md)。本轮仅本地修改和提交,无推送、部署或历史重算;不包含其他会话草稿。真实HTTP为最小控制器验收,未注册应用全局登录鉴权,未做浏览器或线上页面验收;前端/Go未变不重跑。预生产仍需单独授权部署后验收。
提交前从暂存区导出的精确候选另行通过API86套922项、覆盖率68.05/53.73/69.02/70.77和生产构建;候选产物在两种编码新库重新执行完整真实PG/HTTP/日报脚本通过。前述990项含他轮未提交测试,不作为本次精确提交测试数。最终candidate-api-coverage.log、candidate-build.log及real-*-candidate.log留档;专用PG已停止,数据保留。
## 2026-09-21 六项运营整改:实现、隔离真实验收与提交推送
用户授权本轮修改、提交、推送,并明确模板唯一规则改为企业应用×模板名称。六项代码完成,设计先行并同步需求及TC-OPS6-001~007;其中通道移除组成员替代此前仅跳过规则。新增应用模板名部分唯一索引和通道组成员兼容约束,历史数据不重写;签名搜索/变量校验、首页小时曲线、未知映射、质量列删除、报备四条件、通道移除提示/事务均已实现。
本机PG16.14独立数据库115项迁移、真实Redis、全Nest认证API、production前端通过;并发模板只一个成功,跨签名/跨应用/软删除/恢复符合最终口径;通道省网/全国移除、故障回滚、第二数据库连接并发失配拒绝通过。三尺寸18张真实页面截图和刷新/路由/相关交互通过,无pageerror,未发送短信、未启动Gateway。精确暂存候选前端38组179项、后端87组935项,覆盖率/构建/类型/lint/格式/样式/包体/diff门禁通过;遗留10条原有lint警告。并发覆盖率超时和浏览器脚本定位失败保留,降低并发及修正定位后复验通过。原工作区后端1003项含他轮未提交测试,不作为提交内数量。
证据及未验收项见[六项整改记录](operations-six-fixes-20260921.md)。本轮Git将包含28951b4未报备签名修复及本次提交,保护其他会话所有未提交内容;推送结果以最终远端精确SHA回读为准。本轮未部署测试或预生产,线上页面、目标历史量下曲线查询性能与迁移时是否新出现重名不冒充已验收。