fix: simplify balance billing and govern operation logs
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
本文基于当前前端设计原型整理,用于交给 Codex 或开发团队执行第一版落地开发。
|
||||
|
||||
当前确认:第一版保留短信业务,排除彩信功能;账户计费、充值套餐、充值记录进入第一版开发范围,账单流水页面和公开交易查询 API 暂不进入第一版。彩信服务、彩信应用/签名/模板 Tab,以及运营端彩信相关菜单标记为“待开发”;业务性能指标为“平台可稳定入队并调度 500 条短信/秒,实际向通道 submit 受通道限速配置控制”。
|
||||
当前确认:第一版保留短信业务,排除彩信功能;账户按现金余额计费,人工充值和充值记录进入第一版开发范围,套餐、短信余量、授信额度、账单流水页面和公开交易查询 API 不进入第一版。彩信服务、彩信应用/签名/模板 Tab,以及运营端彩信相关菜单标记为“待开发”;业务性能指标为“平台可稳定入队并调度 500 条短信/秒,实际向通道 submit 受通道限速配置控制”。
|
||||
|
||||
## 1. 项目目标
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
- 支持通道级限速、失败重试、回执同步和发送记录追踪。
|
||||
- 支持企业、应用、签名、模板、通道、通道组、报备任务等核心配置数据的后台维护。
|
||||
- 彩信功能仅保留菜单占位或隐藏,不进入第一版开发范围。
|
||||
- 账户计费、充值套餐、充值记录进入第一版范围,并与发送记录形成可对账闭环;账单流水页面暂不验收。
|
||||
- 账户现金余额计费、人工充值、充值记录进入第一版范围,并与发送记录形成可对账闭环;不提供套餐、短信余量和授信额度。
|
||||
|
||||
## 2. 角色与权限
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
- 短信应用
|
||||
- 模板管理
|
||||
- 签名与引流信息
|
||||
- 充值套餐
|
||||
- 账户余额与充值记录
|
||||
- 账单流水
|
||||
- 企业认证
|
||||
- 用户管理
|
||||
@@ -73,7 +73,7 @@
|
||||
- 短信通道管理、短信通道组管理
|
||||
- 报备任务、报备记录
|
||||
- 短信任务进度、短信记录、短信上行记录
|
||||
- 充值记录、账单流水、套餐配置、计费规则
|
||||
- 充值记录、账单流水、计费规则
|
||||
- 企业黑名单、全局黑名单、敏感词管理
|
||||
- 用户管理、手机号段库、引流信息字段库
|
||||
|
||||
@@ -327,21 +327,21 @@
|
||||
|
||||
### 4.10 账户计费
|
||||
|
||||
1. 客户端可查看充值套餐、购买或申请充值套餐、查看账单流水。
|
||||
2. 发送创建时按短信内容计费条数、企业应用客户单价或套餐规则生成预估费用,计费条数只按 70/67 字规则拆分;不按移动、联通、电信配置不同客户价。
|
||||
3. 平台需在发送前检查企业账户余额、套餐余量或授信额度。
|
||||
1. 客户端可查看现金余额和充值记录;充值由运营端人工入账。
|
||||
2. 发送创建时按短信内容计费条数和企业应用客户单价生成预估费用,计费条数只按 70/67 字规则拆分;不按移动、联通、电信配置不同客户价。
|
||||
3. 平台发送前只检查企业现金余额,余额大于等于预估费用即可发送。
|
||||
4. 发送链路需记录计费条数、计费单价、计费金额、账务状态。
|
||||
5. 账单流水与短信记录可追溯关联,支持按企业、应用、任务、手机号、时间对账。
|
||||
6. 最终失败、超时失败需要退费。
|
||||
7. 三网通道成本只用于平台内部成本核算,不影响客户扣费金额。
|
||||
8. 当前版本计费口径固定为提交 accepted 扣费、最终 failed receipt/timeout 退款。
|
||||
9. 所有面向用户展示的金额、余额、充值金额、套餐价格和单价统一以人民币元展示并固定保留三位小数;内部仍使用分或最小计费单位持久化,不以展示精度改变账务计算。
|
||||
9. 所有面向用户展示的金额、余额、充值金额和单价统一以人民币元展示并固定保留三位小数;内部仍使用分或最小计费单位持久化,不以展示精度改变账务计算。
|
||||
|
||||
## 5. 功能需求
|
||||
|
||||
### 5.1 客户端工作台
|
||||
|
||||
- 展示短信余量或可发送额度、今日发送量、成功率、待审核事项、快捷入口。
|
||||
- 展示现金余额、今日发送量、成功率、待审核事项、快捷入口。
|
||||
- 展示最近发送批次、发送趋势、签名/模板状态。
|
||||
- 数据范围限定为当前企业。
|
||||
|
||||
@@ -400,7 +400,7 @@
|
||||
|
||||
### 5.9 客户端账户计费
|
||||
|
||||
- 充值套餐:展示可购买套餐、套餐价格、短信条数、有效期、适用范围。
|
||||
- 账户余额:展示当前现金余额和人工充值记录,不提供客户端购买套餐或创建充值订单入口。
|
||||
- 账单流水:展示充值、冻结、扣费、退费、调整等流水。
|
||||
- 账单流水需关联短信任务、短信记录或人工调整单据。
|
||||
- 客户端账号设置属于系统管理,不允许客户自行配置通道或通道组。
|
||||
@@ -501,10 +501,9 @@
|
||||
|
||||
### 5.19 运营端账户计费
|
||||
|
||||
- 套餐配置:支持配置套餐名称、价格、短信条数、有效期、适用企业范围、启停状态。
|
||||
- 充值记录:支持人工充值、套餐购买记录、授信额度调整。
|
||||
- 充值记录:支持运营人员人工充值和负数冲正。
|
||||
- 账单流水:支持冻结、扣费、退费、解冻、人工调整、失败返还。
|
||||
- 计费规则:支持按短信计费条数、企业单价、套餐余量、授信额度计算费用。
|
||||
- 计费规则:支持按短信计费条数和企业应用单价计算费用,发送额度仅取现金余额。
|
||||
- 账务流水必须与短信记录形成可追溯关系,支持对账导出。
|
||||
- 最终失败、超时失败需要退费。
|
||||
- 计费口径可配置为按提交成功计费或按回执成功计费。
|
||||
@@ -522,6 +521,9 @@
|
||||
- 客户端和运营端右上角用户头像提供下拉菜单,支持退出登录、修改密码;账号设置独立菜单第一版不展示。
|
||||
- 客户端和运营端系统日志均支持分页、搜索和详情展示;详情列内容较长时使用详情卡/弹窗展示,不能被表格窄列截断。
|
||||
- 系统日志记录登录、退出、配置变更、审核、发送、导入导出、密钥重置、通道复制、通道启停、通道删除、连接状态变化、安全控制变更等操作。
|
||||
- CMPP 心跳、Submit、Deliver 和 Gateway 周期状态同步属于运行指标或当前状态更新,不得每次追加永久系统日志;连接建立、断开、超时、认证失败,以及恢复状态、实例、锁持有者或失败原因发生真实变化时才写系统日志。
|
||||
- 系统日志列表必须在数据库侧完成级别、租户、模块、时间和关键词筛选后再分页;所有新旧日志查询接口均限制每页最多 100 条,不允许无界返回全表。
|
||||
- `OperationLog` 在线保留期默认 180 天;到期日志以小批量事务搬入 `OperationLogArchive`,按 `archiveMonth=YYYY-MM` 形成逻辑月度归档。归档记录不自动删除,归档失败不得删除源记录;归档表达到千万级或维护窗口不满足要求时再评估 PostgreSQL 月度分区。
|
||||
|
||||
## 6. 非功能需求
|
||||
|
||||
@@ -677,6 +679,7 @@
|
||||
- user:用户。
|
||||
- role、permission、user_role:权限。
|
||||
- operation_log:操作日志。
|
||||
- operation_log_archive:超过在线保留期的操作日志归档,保留原始日志 id、租户、操作者、动作、资源、详情、发生时间和归档月份。
|
||||
|
||||
### 9.2 短信配置
|
||||
|
||||
@@ -728,9 +731,8 @@
|
||||
|
||||
### 9.7 账户计费
|
||||
|
||||
- billing_plan:充值套餐。
|
||||
- tenant_account:企业账户。
|
||||
- account_balance:余额或套餐余量。
|
||||
- account_balance:企业现金余额。
|
||||
- account_transaction:账户流水。
|
||||
- billing_rule:计费规则。
|
||||
- sms_billing_record:短信计费记录。
|
||||
@@ -937,7 +939,7 @@
|
||||
3. 实现文件上传和对象存储。
|
||||
4. 实现操作日志。
|
||||
5. 实现基础字典:手机号段、敏感词、黑名单、引流字段。
|
||||
6. 实现账户、套餐、账务流水基础模型。
|
||||
6. 实现现金余额账户和账务流水基础模型。
|
||||
|
||||
### 阶段 3:企业与配置
|
||||
|
||||
@@ -974,8 +976,8 @@
|
||||
|
||||
1. 实现客户端批量任务、发送详情、上行短信。
|
||||
2. 实现运营端任务进度、短信记录、上行记录。
|
||||
3. 实现客户端充值套餐、账单流水。
|
||||
4. 实现运营端充值记录、账务流水、套餐配置。
|
||||
3. 实现客户端账户余额和充值记录。
|
||||
4. 实现运营端充值记录和账务流水。
|
||||
5. 实现运营看板、发送监控、数据统计。
|
||||
6. 实现导出权限和导出日志。
|
||||
|
||||
@@ -1007,7 +1009,7 @@
|
||||
1. 根据本文创建数据库迁移脚本和实体模型。
|
||||
2. 实现认证、租户、权限基础模块。
|
||||
3. 实现企业、应用、签名、模板 CRUD 与审核。
|
||||
4. 实现账户计费、套餐、账务流水。
|
||||
4. 实现现金余额计费和账务流水。
|
||||
5. 实现通道、通道组、报备任务。
|
||||
6. 实现风控规则、审核原因、规则命中记录。
|
||||
7. 实现 NestJS Send Worker、BullMQ 队列和 Redis 限速。
|
||||
@@ -1075,7 +1077,7 @@
|
||||
|
||||
### 14.7 待确认问题
|
||||
|
||||
暂无阻塞性待确认问题。后续进入详细设计或开发时,如遇具体运营商协议参数、生产部署资源规格、默认套餐价格等执行细节,再按模块补充确认。
|
||||
暂无阻塞性待确认问题。后续进入详细设计或开发时,如遇具体运营商协议参数、生产部署资源规格等执行细节,再按模块补充确认。
|
||||
|
||||
## 15. 第一版落地执行路线
|
||||
|
||||
@@ -1210,10 +1212,10 @@
|
||||
|
||||
任务:
|
||||
|
||||
1. 套餐配置。
|
||||
2. 充值套餐。
|
||||
3. 企业账户。
|
||||
4. 余额或套餐余量。
|
||||
1. 企业现金账户。
|
||||
2. 人工充值记录。
|
||||
3. 现金余额。
|
||||
4. 发送费用预估。
|
||||
5. 充值记录。
|
||||
6. 账单流水。
|
||||
7. 发送预估费用。
|
||||
@@ -1222,8 +1224,8 @@
|
||||
|
||||
验收标准:
|
||||
|
||||
- 客户端充值套餐和账单流水进入第一版。
|
||||
- 发送前校验账户余额、套餐余量或授信额度。
|
||||
- 客户端账户余额和充值记录进入第一版。
|
||||
- 发送前仅校验企业现金余额。
|
||||
- 每条短信记录可追溯到账务流水。
|
||||
|
||||
### 阶段 6:风控与审核
|
||||
@@ -1324,7 +1326,7 @@
|
||||
- 运营端可针对指定企业录入人工充值金额、操作人和备注。
|
||||
- 人工充值金额支持负数,用于余额冲正或调减;0 金额不得提交。
|
||||
- 人工充值必须写入充值订单和账务流水。
|
||||
- 运营端充值记录需区分人工充值和套餐充值。
|
||||
- 运营端充值记录均为人工充值或负数冲正。
|
||||
2. 客户端概览指标调整。
|
||||
- 原“剩余条数”改为“剩余余额”。
|
||||
- 原“近24小时成功率”改为“今日发送条数和今日成功率”。
|
||||
@@ -1349,7 +1351,7 @@
|
||||
|
||||
重要前提:
|
||||
- 第一版保留短信业务,排除彩信功能。
|
||||
- 账户计费、充值套餐、账单流水进入第一版。
|
||||
- 现金余额计费、人工充值、账单流水进入第一版。
|
||||
- 前端使用 React + TypeScript + Vite。
|
||||
- 后端 API 使用 NestJS + TypeScript。
|
||||
- DB 使用 PostgreSQL。
|
||||
@@ -1407,7 +1409,7 @@
|
||||
|
||||
除文档或菜单明确标注为待开发的彩信能力外,第一版所有可进入菜单不得以 mock/static/localStorage 作为系统功能完成标准:
|
||||
|
||||
1. 客户端充值套餐、账单流水、批量任务、短信发送、短信签名、短信模板必须调用真实 API;签名/模板新增后进入真实审核状态,发送任务调用真实发送链路。
|
||||
1. 客户端账户余额、充值记录、批量任务、短信发送、短信签名、短信模板必须调用真实 API;签名/模板新增后进入真实审核状态,发送任务调用真实发送链路。
|
||||
2. 运营端数据统计、账务账户、发送监控、短信审核、短信记录、安全控制、手机号段库、报备字段库、通道组、通道报备字段、报备任务和报备记录必须调用真实 API。
|
||||
3. 运营端企业管理使用真实租户、账户、应用、签名、模板接口;企业新增、编辑、启用/禁用、删除必须写真实租户表,删除采用软删除或归档,不允许纯前端删除。
|
||||
4. 企业签名和企业模板运营端列表只展示真实短信配置数据;彩信签名、彩信模板、彩信通道、彩信记录、彩信任务进度等仍归入待开发,不得用静态样例作为第一版短信验收结果。
|
||||
|
||||
@@ -35,6 +35,11 @@ SESSION_LOCK_RECOVERY_MS=14400000
|
||||
SESSION_ABSOLUTE_TIMEOUT_MS=43200000
|
||||
SESSION_RECENT_AUTH_MS=1800000
|
||||
SESSION_COOKIE_SECURE=true
|
||||
OPERATION_LOG_ARCHIVE_ENABLED=true
|
||||
OPERATION_LOG_RETENTION_DAYS=180
|
||||
OPERATION_LOG_ARCHIVE_BATCH_SIZE=1000
|
||||
OPERATION_LOG_ARCHIVE_MAX_BATCHES=20
|
||||
OPERATION_LOG_ARCHIVE_INTERVAL_MS=86400000
|
||||
CMPP_DOWNSTREAM_ACK_TIMEOUT_SECONDS=30
|
||||
GATEWAY_CMPP_ADDR=0.0.0.0:17890
|
||||
OBJECT_STORAGE_DRIVER=minio
|
||||
@@ -46,6 +51,8 @@ PROD_ADMIN_PASSWORD='change-me'
|
||||
|
||||
安全会话使用 HttpOnly Cookie,正式生产必须先为页面和 `/api` 配置 HTTPS,并保持 `SESSION_COOKIE_SECURE=true`。仅在用户明确授权的 HTTP 生产验证环境中,允许临时显式设置 `SESSION_COOKIE_SECURE=false` 维持验证可用性;该例外必须记录在发布验收中,不能替代正式环境 TLS。
|
||||
|
||||
系统操作日志默认在线保留 180 天。API 每日以最多 20 个、每批 1000 条的小事务将过期记录搬入 `OperationLogArchive`,并用 `archiveMonth=YYYY-MM` 标记归档月份;归档记录不会自动删除。调整保留期或批量参数前,应先评估数据库、备份窗口和审计要求。归档表达到千万级或清理窗口不能满足要求时,再实施按 `createdAt` 的月度 PostgreSQL 分区,不在当前数据规模下提前改造主表分区。
|
||||
|
||||
脚本会安装 Node.js、Go、PostgreSQL、Redis、MinIO、Nginx,创建 systemd 服务,执行 Prisma migrate,构建前端/API/Gateway,并创建平台管理员。Node.js、Go 和 MinIO 下载会按服务器架构自动选择 x64/amd64 或 arm64。
|
||||
|
||||
如生产验证服务器临时无法稳定下载 MinIO,可显式传入 `OBJECT_STORAGE_DRIVER=local`,文件会通过真实 API 保存到服务器本地目录 `OBJECT_STORAGE_LOCAL_ROOT`,`cmpp-minio` 服务会跳过安装和启动。该模式只建议用于验证环境;正式生产建议恢复 `OBJECT_STORAGE_DRIVER=minio`。
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
| 模板 | 验证码模板 `验证码为 ${code}`,营销模板 `尊敬的${name},优惠活动开始`,分别准备草稿、待审核、通过、驳回。 |
|
||||
| 通道 | active CMPP 通道、disabled 通道、备用通道;通道组包含主备优先级。 |
|
||||
| 号码 | 合法号码、重复号码、非法号码、企业黑名单号码、全局黑名单号码。 |
|
||||
| 账户 | 余额充足、余额不足、套餐余量充足、套餐余量不足、授信额度可用。 |
|
||||
| 账户 | 现金余额充足、现金余额不足;不配置套餐余量或授信额度。 |
|
||||
| 企业认证 | 未认证、待审核、已通过、已驳回四类企业认证资料。 |
|
||||
| 客户 | 正常客户、停用客户、欠费客户、未认证客户、跨租户客户、客户联系人和开票资料。 |
|
||||
| 导入文件 | UTF-8 CSV、GBK CSV、TXT、超 20 MB 文件、含空行/重复/非法号码/非法字符文件。 |
|
||||
@@ -54,7 +54,7 @@
|
||||
- 前置条件:存在 `tenant-a` 和 `tenant-b`,两个租户各有发送任务和充值/计费记录。
|
||||
- 步骤:
|
||||
1. 使用 `tenant-a` 企业管理员登录客户端。
|
||||
2. 打开工作台、批量任务、发送详情、上行短信、充值套餐。
|
||||
2. 打开工作台、批量任务、发送详情、上行短信、账户余额。
|
||||
3. 使用查询条件搜索 `tenant-b` 的任务编号或手机号。
|
||||
- 预期结果:
|
||||
- 登录成功,返回当前租户上下文。
|
||||
@@ -138,7 +138,7 @@
|
||||
### TC-CLIENT-007 账户余额不足禁止发送
|
||||
|
||||
- 优先级:P0
|
||||
- 前置条件:账户余额、套餐余量和授信额度不足。
|
||||
- 前置条件:企业现金余额小于预估发送费用。
|
||||
- 步骤:
|
||||
1. 使用长内容和多个手机号生成较高预估费用。
|
||||
2. 提交发送。
|
||||
@@ -749,7 +749,7 @@
|
||||
- 步骤:创建发送任务并进入待发送。
|
||||
- 预期结果:
|
||||
- 生成 frozen 流水。
|
||||
- 账户余额或套餐余量减少。
|
||||
- 企业现金余额减少。
|
||||
- 流水关联 taskId。
|
||||
|
||||
### TC-BILLING-003 submit 成功扣费
|
||||
@@ -2322,16 +2322,16 @@
|
||||
### TC-DASHBOARD-002 客户端 Dashboard 余额和可发送额度准确
|
||||
|
||||
- 优先级:P0
|
||||
- 前置条件:客户 A 账户余额 10000 分,套餐余量 200 条,授信额度 5000 分;存在冻结、扣费、退款、释放流水。
|
||||
- 前置条件:客户 A 现金余额 10000 分;存在冻结、扣费、退款、释放流水。
|
||||
- 步骤:
|
||||
1. 打开客户端 Dashboard。
|
||||
2. 查看余额、套餐余量、授信额度、可发送额度。
|
||||
2. 查看现金余额和可发送额度。
|
||||
3. 打开账单流水。
|
||||
4. 按交易类型核对充值、冻结、扣费、退款、释放后的余额。
|
||||
- 预期结果:
|
||||
- Dashboard 余额与账户表和流水计算结果一致。
|
||||
- 冻结金额不应被当作可用余额重复计算。
|
||||
- 套餐余量和金额余额分别展示,口径不混淆。
|
||||
- 可发送额度等于现金余额,不叠加其他额度。
|
||||
- 跳转账单流水后可核对组成明细。
|
||||
|
||||
### TC-DASHBOARD-003 客户端 Dashboard 待处理事项准确
|
||||
@@ -2414,11 +2414,11 @@
|
||||
5. 运营端查看账户余额、账单流水和系统日志。
|
||||
- 预期结果:
|
||||
- 生成 RechargeOrder,状态为 paid 或人工充值完成状态。
|
||||
- 账户余额和套餐余量同步增加。
|
||||
- 企业现金余额同步增加。
|
||||
- 生成 account_transaction,类型为 recharge,关联 recharge_order。
|
||||
- 客户端余额、账单流水即时可见。
|
||||
- 运营端充值记录、账单流水、系统日志三处可追溯。
|
||||
- 所有金额、余额、套餐价格和单价固定展示三位小数,例如 `¥1.000`。
|
||||
- 所有金额、余额和单价固定展示三位小数,例如 `¥1.000`。
|
||||
|
||||
### TC-BILLING-007 人工充值金额和短信条数只填其一
|
||||
|
||||
@@ -2429,7 +2429,7 @@
|
||||
2. 再发起一笔只填写短信条数,不填写充值金额。
|
||||
3. 查看账户和流水。
|
||||
- 预期结果:
|
||||
- 系统按填写项分别增加余额或套餐余量。
|
||||
- 系统按填写金额增加或冲正现金余额。
|
||||
- 未填写项按 0 处理,不产生脏数据。
|
||||
- 流水金额和短信条数字段方向正确。
|
||||
- 备注和操作人保留。
|
||||
@@ -2445,7 +2445,7 @@
|
||||
4. 客户端查看账单流水。
|
||||
- 预期结果:
|
||||
- 原充值记录状态变为 canceled/reversed,或生成一笔反向调整流水。
|
||||
- 账户余额和套餐余量正确回退。
|
||||
- 企业现金余额正确回退。
|
||||
- 若余额已消费导致不能全额撤销,应提示不可撤销或只允许人工调整。
|
||||
- 客户端和运营端均可看到冲正流水和原因。
|
||||
- 系统日志记录冲正操作者和原因。
|
||||
@@ -2552,6 +2552,35 @@
|
||||
- 失败原因可读且与前端提示一致。
|
||||
- 客户端只可见本客户失败日志,运营端可全平台查询。
|
||||
|
||||
### TC-LOG-010 高频运行事件不得放大系统日志
|
||||
|
||||
- 优先级:P0
|
||||
- 前置条件:客户 CMPP 连接在线,Gateway 正常发送心跳并周期同步下游恢复状态。
|
||||
- 步骤:
|
||||
1. 建立一条客户 CMPP 连接并记录当前 `OperationLog` 数量。
|
||||
2. 连续发送多次 heartbeat、Submit、Deliver 事件。
|
||||
3. 连续上报仅时间、尝试次数或锁过期时间变化、业务状态未变化的恢复状态。
|
||||
4. 触发连接断开,并将恢复状态从 waiting_connection 改为 running 或 failed。
|
||||
- 预期结果:
|
||||
- heartbeat、Submit、Deliver 仍更新连接表对应时间,但不新增系统日志。
|
||||
- 周期恢复状态只更新 `GatewayDownstreamRecoveryStatus`,未发生审计字段变化时不新增系统日志。
|
||||
- 连接建立/断开以及恢复状态、实例、锁持有者、失败分类或失败原因真实变化时各新增一条系统日志。
|
||||
|
||||
### TC-LOG-011 系统日志分页索引与归档安全
|
||||
|
||||
- 优先级:P0
|
||||
- 前置条件:准备超过两页、覆盖 info/success/warning/error 的系统日志,并准备超过在线保留期的日志。
|
||||
- 步骤:
|
||||
1. 分别按级别、租户、模块、时间和关键词查询第一页、第二页。
|
||||
2. 调用兼容审计接口并传入超大 pageSize。
|
||||
3. 执行一次归档任务,再查询 `OperationLog` 和 `OperationLogArchive`。
|
||||
4. 模拟归档插入失败并重新执行。
|
||||
- 预期结果:
|
||||
- 级别筛选在数据库分页前生效,total、页数和当前页记录准确且排序稳定。
|
||||
- 所有接口 pageSize 最大为 100,不存在无界全表返回。
|
||||
- 到期日志按 `archiveMonth=YYYY-MM` 进入归档表,在线表只删除已成功归档的记录,原始 id 和详情不丢失。
|
||||
- 归档使用有界小批量和 `SKIP LOCKED`;归档失败时源日志仍保留,不阻塞正常日志写入。
|
||||
|
||||
### TC-CUSTOMER-001 运营端创建客户并初始化租户
|
||||
|
||||
- 优先级:P0
|
||||
@@ -2631,7 +2660,7 @@
|
||||
### TC-CUSTOMER-006 客户欠费或额度不足状态联动发送
|
||||
|
||||
- 优先级:P0
|
||||
- 前置条件:客户余额、套餐余量、授信额度不足,或运营端标记欠费。
|
||||
- 前置条件:客户现金余额不足,或运营端标记欠费。
|
||||
- 步骤:
|
||||
1. 客户端创建发送任务。
|
||||
2. API 调用发送。
|
||||
@@ -2675,10 +2704,10 @@
|
||||
### TC-CUSTOMER-009 客户详情展示业务总览准确
|
||||
|
||||
- 优先级:P0
|
||||
- 前置条件:客户 A 下存在应用 3 个、签名 4 个、模板 5 个、通道绑定 2 个、今日发送 100 条、余额和套餐余量。
|
||||
- 前置条件:客户 A 下存在应用 3 个、签名 4 个、模板 5 个、通道绑定 2 个、今日发送 100 条和现金余额。
|
||||
- 步骤:
|
||||
1. 运营端打开客户详情。
|
||||
2. 查看客户业务总览:应用数、签名数、模板数、今日发送量、成功率、余额、套餐余量、待审核数。
|
||||
2. 查看客户业务总览:应用数、签名数、模板数、今日发送量、成功率、现金余额、待审核数。
|
||||
3. 点击每个指标进入对应明细列表。
|
||||
- 预期结果:
|
||||
- 客户详情总览只统计客户 A。
|
||||
@@ -3005,7 +3034,7 @@
|
||||
3. 初始化 active/disabled 客户、未认证/待审核/已认证/驳回企业认证资料。
|
||||
4. 初始化可用应用、停用应用、待删除应用。
|
||||
5. 初始化签名、引流信息、模板、多变量模板、通道、通道组、路由规则。
|
||||
6. 初始化账户余额、套餐余量、欠费/不足余额场景。
|
||||
6. 初始化现金余额、欠费/不足余额场景。
|
||||
7. 准备 CSV/TXT/GBK/大文件/非法字符/黑名单号码测试文件。
|
||||
8. 确认 Gateway 模拟器可切换 online、auth_failed、heartbeat_timeout、disconnected、slow_response。
|
||||
- 产出物:
|
||||
@@ -3164,7 +3193,7 @@ npm run verify:phase8
|
||||
| 用例 | 数据准备 | 指标断言 |
|
||||
| --- | --- | --- |
|
||||
| TC-DASHBOARD-001 | 客户 A 当天 delivered=10、failed=3、unknown=2、timeout=1;客户 B 有干扰数据。 | 客户端总量=16;成功=10;失败按 failed+timeout 为 4;unknown=2;成功率若按 delivered/total 为 62.5%;点击卡片后的明细筛选一致。 |
|
||||
| TC-DASHBOARD-002 | 账户余额 10000 分、套餐 200 条、授信 5000 分,另有冻结、扣费、释放、退款流水。 | 可用余额不重复计算冻结;金额余额和套餐余量分开展示;账单流水余额 after 与 Dashboard 一致。 |
|
||||
| TC-DASHBOARD-002 | 现金余额 10000 分,另有冻结、扣费、释放、退款流水。 | 可用额度仅为现金余额且不重复计算冻结;账单流水 balanceAfter 与 Dashboard 一致。 |
|
||||
| TC-DASHBOARD-003 | 待审核签名 2、模板 3、待报备 1、pending_review 发送任务 4。 | 待处理总数和分类数准确;点击跳转后列表筛选数量一致;只包含当前租户。 |
|
||||
| TC-DASHBOARD-004 | 多客户、多通道、多状态发送和账务流水。 | 运营端统计全平台;活跃客户、今日发送、成功率、待审核、收入均可在明细页复核。 |
|
||||
| TC-DASHBOARD-005 | 客户 A/B 均有发送、账务、审核数据。 | 切换客户后所有卡片、趋势、状态分布、账务汇总同步刷新;跳转明细继承客户筛选。 |
|
||||
@@ -3175,11 +3204,13 @@ npm run verify:phase8
|
||||
|
||||
| 用例 | 细化执行点 | 必查断言 |
|
||||
| --- | --- | --- |
|
||||
| TC-BILLING-006 | 运营端人工充值金额和短信条数,客户端查看 Dashboard 和账单流水。 | RechargeOrder 状态为 paid/manual_topup;TenantAccount 同步增加;AccountTransaction 类型 recharge;充值记录“充值后余额”必须等于该订单关联 AccountTransaction.balanceAfter,不能用当前账户余额替代;运营日志和客户端流水均可追溯。 |
|
||||
| TC-BILLING-007 | 分别只填金额、只填短信条数;金额填写负数执行冲正。 | 未填项按 0;正负金额和条数字段方向正确;允许有业务含义的负数调整,不产生 null、NaN 或零变更脏数据。 |
|
||||
| TC-BILLING-006 | 运营端人工充值现金金额,客户端查看 Dashboard 和充值记录。 | RechargeOrder 状态为 paid/manual_topup;TenantAccount 现金余额同步增加;AccountTransaction 类型 recharge;充值记录“充值后余额”必须等于该订单关联 AccountTransaction.balanceAfter,不能用当前账户余额替代;运营日志可追溯。 |
|
||||
| TC-BILLING-007 | 分别填写正数金额和负数金额执行充值、冲正;提交 0 或非法金额。 | 正负金额方向正确;0 和非法金额被拒绝;数据模型和接口不存在短信条数、套餐或授信字段。 |
|
||||
| TC-BILLING-008 | 对已充值记录执行撤销/冲正,分别覆盖未消费和已部分消费。 | 未消费可全额回退;已消费按规则拒绝或生成人工调整;原订单状态和反向流水清晰;日志记录原因。 |
|
||||
| TC-BILLING-009 | 无权限用户、审核员、管理员分别执行充值;大额人工充值不走审批。 | 权限不足被拒绝并写失败日志;有权限用户确认后立即入账;不产生 pending 审批态;充值订单、账户余额、流水和日志同步完成。 |
|
||||
| TC-BILLING-010 | 余额不足发送失败,人工充值后重试发送并模拟 delivered。 | 充值前不扣费;充值后发送成功;冻结、扣费、短信计费记录完整;reconciliation diff 为 0。 |
|
||||
| TC-BILLING-011 | 账户现金余额 100 分,预估费用 5 分,且数据库不存在套餐和授信数据;再将余额改为 4 分重试。 | 100 分时可发送,4 分时提示“企业账户余额不足”;判断只依赖 TenantAccount.balanceCents。 |
|
||||
| TC-BILLING-012 | 已扣费短信收到最终失败回执;另一个未提交成功任务只释放冻结。 | 前者只生成一条 refunded 流水并计入“今日返还”;重复回执不重复退款;后者的 released 流水不计入“今日返还”。 |
|
||||
|
||||
### 17.6 系统日志细化
|
||||
|
||||
@@ -3188,8 +3219,10 @@ npm run verify:phase8
|
||||
| TC-LOG-005 | 客户 A 查看日志并尝试查询客户 B 日志。 | 客户端只返回本租户日志;越权查询失败;日志包含 IP、User-Agent、result、resourceId。 |
|
||||
| TC-LOG-006 | 客户端导入号码、立即发送、创建并取消定时任务。 | 导入日志含文件名、行数、成功/失败数;发送日志含任务编号、号码数、发送类型;取消日志含取消人。 |
|
||||
| TC-LOG-007 | 运营端按客户、动作、资源、结果、时间查询并导出。 | 查询准确;导出内容与筛选一致;导出动作本身写日志。 |
|
||||
| TC-LOG-008 | 人工充值、冲正、账户调整。 | 日志含客户、金额、短信条数、订单号、流水号、操作者;敏感字段脱敏。 |
|
||||
| TC-LOG-008 | 人工充值、冲正、账户调整。 | 日志含客户、金额、订单号、流水号、操作者;敏感字段脱敏。 |
|
||||
| TC-LOG-009 | 触发无权限充值、余额不足发送、无在线通道发送。 | 失败动作也写日志;result/status 标记失败;失败原因与前端提示一致。 |
|
||||
| TC-LOG-010 | 保持 CMPP 在线并连续发送 heartbeat/Submit/Deliver、重复恢复状态,再触发断开和状态变化。 | 高频事件只更新状态表;连接和恢复状态关键变化才新增日志;日志量不随心跳线性增长。 |
|
||||
| TC-LOG-011 | 准备多级别、多页和过期日志,验证查询上限与归档重试。 | 数据库侧筛选后分页;每页最多 100;归档成功才删除源记录;archiveMonth、原始 id 和详情完整。 |
|
||||
|
||||
### 17.7 客户管理细化
|
||||
|
||||
@@ -3200,7 +3233,7 @@ npm run verify:phase8
|
||||
| TC-CUSTOMER-003 | 停用客户后分别通过客户端、API、CMPP 接入尝试发送。 | 全部阻断;不入队、不扣费;失败原因是客户停用;历史任务可查。 |
|
||||
| TC-CUSTOMER-004 | 客户 active 时创建 scheduled,到点前停用。 | 到点重校验失败;任务 rejected/canceled/failed;冻结费用释放;日志指向客户停用。 |
|
||||
| TC-CUSTOMER-005 | 重新启用客户后发送。 | 客户状态 active;新发送成功进入链路;账务和日志完整。 |
|
||||
| TC-CUSTOMER-006 | 余额不足、套餐不足、授信不足、欠费标记。 | 发送前账户校验失败;不投递 Gateway;客户详情展示欠费或不足状态。 |
|
||||
| TC-CUSTOMER-006 | 现金余额不足或欠费标记。 | 发送前账户校验失败;不投递 Gateway;客户详情展示欠费或不足状态。 |
|
||||
| TC-CUSTOMER-007 | 客户 A 使用 URL/API 参数访问客户 B 资源。 | 不泄露 B 数据;返回无权限或空结果;失败访问写安全日志。 |
|
||||
| TC-CUSTOMER-008 | 删除/归档有历史数据的客户。 | 不允许硬删除或执行归档;新发送和未执行 scheduled 阻断;历史 trace/对账可查。 |
|
||||
| TC-CUSTOMER-009 | 客户详情总览应用、签名、模板、今日发送、余额。 | 各指标与明细列表聚合一致;跳转带客户筛选;异常状态有标识。 |
|
||||
@@ -3268,7 +3301,7 @@ npm run verify:phase8
|
||||
|
||||
| 用例编号 | 操作 | 预期结果 |
|
||||
| --- | --- | --- |
|
||||
| TC-MOCK-CLEAN-001 | 断开 API 或让 API 返回 500,访问客户端充值套餐、账单流水、批量任务、短信发送、签名、模板页面。 | 页面展示错误态或空态;不得出现前端静态套餐、任务、模板、签名或最近发送记录。 |
|
||||
| TC-MOCK-CLEAN-001 | 断开 API 或让 API 返回 500,访问客户端账户余额、充值记录、批量任务、短信发送、签名、模板页面。 | 页面展示错误态或空态;不得出现前端静态余额、任务、模板、签名或最近发送记录。 |
|
||||
| TC-MOCK-CLEAN-002 | 访问运营端数据统计、账务账户、发送监控、安全控制、手机号段库、报备字段库、通道组、报备任务、报备记录。 | 所有列表和卡片来自真实 API;新增动作写入数据库;后端缺失的编辑/删除能力不得用本地状态伪造。 |
|
||||
| TC-UI-ENTERPRISE-SELECT-001 | 逐一打开包含企业或企业应用选择的表单和筛选项,输入部分企业/应用名称。 | 下拉面板提供搜索框并实时缩小真实 API 选项范围;清空后恢复全部选项。 |
|
||||
| TC-UI-TEMPLATE-RESPONSIVE-001 | 在 1024px、1366px 和宽屏视口打开企业短信模板页。 | 模板卡片自适应换列,页面不出现水平滚动,每张卡片的编辑和删除按钮直接可见。 |
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# 第一版系统化测试进度
|
||||
|
||||
## 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;待部署阶段完成生产备份、迁移和线上验证。
|
||||
|
||||
## 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,因此短信记录页面无记录。
|
||||
|
||||
Reference in New Issue
Block a user