820 lines
58 KiB
Markdown
820 lines
58 KiB
Markdown
# 第一版系统化测试进度
|
||
|
||
## 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 priority,SubmitCommand 契约、示例和 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 Jest:5 个 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 TPS;Prisma 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 连接状态模型/API,Gateway 或本地 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 Jest:7 个 test suite 通过,34 个测试通过。
|
||
- 最终回归通过:
|
||
- `npm run verify:phase8` 通过,BullMQ 15000 条消息、并发 500、端到端 TPS 608.93,满足 500 TPS;Prisma 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 Jest:8 个 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 被占用后切换到 5174,Vite 首次依赖 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 被占用后切到 5174,Vite 依赖 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-004:submit 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 Jest:10 个 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 Jest:8 个 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 Jest:10 个 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 Jest:10 个 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-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 Jest:12 个 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 Jest:12 个 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 提示。
|