Files
lislgosms/docs/testing-progress.md
T

797 lines
56 KiB
Markdown
Raw 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-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 查询、创建、启停/软删除,并写操作日志。
- 模板审核补齐真实查询:运营端模板列表支持 keyword/status,并返回企业、应用、签名信息;前端模板审核页已改为调用真实 API。
- 企业认证审核补齐真实查询:列表支持 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-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 企业列表人工充值入口
### 本轮修复
- 运营端企业管理列表新增“充值”按钮。
- 点击“充值”打开企业人工充值弹窗,展示企业名称、当前余额,并支持录入充值金额、操作人和备注;企业列表入口不要求填写短信条数。
- 提交后调用现有真实接口 `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 提示。