feat: complete cmpp platform phases 0-5
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"schemaVersion": "v1",
|
||||
"messageType": "ReceiptEvent",
|
||||
"traceId": "trace-20260701-000001",
|
||||
"messageId": "msg-20260701-000001",
|
||||
"channelId": "sms-channel-cmpp-001",
|
||||
"createdAt": "2026-07-01T09:00:02.000Z",
|
||||
"sequenceId": 2048,
|
||||
"gatewayMessageId": "gw-msg-20260701-000001",
|
||||
"receiptStatus": "delivered",
|
||||
"rawStatus": "DELIVRD",
|
||||
"deliveredAt": "2026-07-01T09:00:01.900Z"
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"schemaVersion": "v1",
|
||||
"messageType": "SubmitCommand",
|
||||
"traceId": "trace-20260701-000001",
|
||||
"messageId": "msg-20260701-000001",
|
||||
"channelId": "sms-channel-cmpp-001",
|
||||
"createdAt": "2026-07-01T09:00:00.000Z",
|
||||
"tenantId": "tenant-demo",
|
||||
"applicationId": "app-demo",
|
||||
"taskId": "task-20260701-000001",
|
||||
"submitId": "submit-20260701-000001",
|
||||
"phoneNumber": "13800138000",
|
||||
"content": "您的验证码为 123456,5 分钟内有效。",
|
||||
"signature": "测试平台",
|
||||
"templateId": "tpl-demo-code",
|
||||
"billingUnits": 1,
|
||||
"route": {
|
||||
"channelCode": "CMCC-CMPP-DEMO",
|
||||
"cmppAccountCode": "cmpp-account-demo",
|
||||
"priority": 10,
|
||||
"rateLimitPerSecond": 500
|
||||
},
|
||||
"cmpp": {
|
||||
"serviceId": "CMPP",
|
||||
"srcId": "106900000000",
|
||||
"registeredDelivery": 1,
|
||||
"msgFmt": 15,
|
||||
"feeUserType": 2,
|
||||
"feeCode": "0",
|
||||
"feeType": "01"
|
||||
},
|
||||
"retry": {
|
||||
"attempt": 0,
|
||||
"maxAttempts": 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"schemaVersion": "v1",
|
||||
"messageType": "SubmitResult",
|
||||
"traceId": "trace-20260701-000001",
|
||||
"messageId": "msg-20260701-000001",
|
||||
"channelId": "sms-channel-cmpp-001",
|
||||
"createdAt": "2026-07-01T09:00:00.120Z",
|
||||
"sequenceId": 1024,
|
||||
"gatewayMessageId": "gw-msg-20260701-000001",
|
||||
"submitStatus": "accepted",
|
||||
"submittedAt": "2026-07-01T09:00:00.118Z"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"schemaVersion": "v1",
|
||||
"messageType": "UplinkEvent",
|
||||
"traceId": "trace-20260701-uplink-000001",
|
||||
"messageId": "uplink-20260701-000001",
|
||||
"channelId": "sms-channel-cmpp-001",
|
||||
"createdAt": "2026-07-01T09:01:00.000Z",
|
||||
"sequenceId": 4096,
|
||||
"phoneNumber": "13800138000",
|
||||
"destId": "106900000000",
|
||||
"content": "TD",
|
||||
"receivedAt": "2026-07-01T09:00:59.800Z"
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://cmpp-platform.local/schemas/gateway-queue-messages.schema.json",
|
||||
"title": "CMPP Gateway Queue Messages",
|
||||
"oneOf": [
|
||||
{ "$ref": "#/$defs/SubmitCommand" },
|
||||
{ "$ref": "#/$defs/SubmitResult" },
|
||||
{ "$ref": "#/$defs/ReceiptEvent" },
|
||||
{ "$ref": "#/$defs/UplinkEvent" }
|
||||
],
|
||||
"$defs": {
|
||||
"Envelope": {
|
||||
"type": "object",
|
||||
"required": ["schemaVersion", "messageType", "traceId", "messageId", "channelId", "createdAt"],
|
||||
"properties": {
|
||||
"schemaVersion": { "const": "v1" },
|
||||
"messageType": {
|
||||
"enum": ["SubmitCommand", "SubmitResult", "ReceiptEvent", "UplinkEvent"]
|
||||
},
|
||||
"traceId": { "type": "string", "minLength": 8 },
|
||||
"messageId": { "type": "string", "minLength": 8 },
|
||||
"channelId": { "type": "string", "minLength": 1 },
|
||||
"createdAt": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
},
|
||||
"SubmitCommand": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/Envelope" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"messageType",
|
||||
"tenantId",
|
||||
"applicationId",
|
||||
"submitId",
|
||||
"phoneNumber",
|
||||
"content",
|
||||
"signature",
|
||||
"templateId",
|
||||
"billingUnits",
|
||||
"route",
|
||||
"cmpp",
|
||||
"retry"
|
||||
],
|
||||
"properties": {
|
||||
"messageType": { "const": "SubmitCommand" },
|
||||
"tenantId": { "type": "string", "minLength": 1 },
|
||||
"applicationId": { "type": "string", "minLength": 1 },
|
||||
"taskId": { "type": "string" },
|
||||
"submitId": { "type": "string", "minLength": 1 },
|
||||
"phoneNumber": { "type": "string", "pattern": "^1[3-9][0-9]{9}$" },
|
||||
"content": { "type": "string", "minLength": 1 },
|
||||
"signature": { "type": "string", "minLength": 1 },
|
||||
"templateId": { "type": "string", "minLength": 1 },
|
||||
"billingUnits": { "type": "integer", "minimum": 1 },
|
||||
"route": {
|
||||
"type": "object",
|
||||
"required": ["channelCode", "cmppAccountCode", "priority"],
|
||||
"properties": {
|
||||
"channelCode": { "type": "string", "minLength": 1 },
|
||||
"cmppAccountCode": { "type": "string", "minLength": 1 },
|
||||
"priority": { "type": "integer", "minimum": 0 },
|
||||
"rateLimitPerSecond": { "type": "integer", "minimum": 1 }
|
||||
}
|
||||
},
|
||||
"cmpp": {
|
||||
"type": "object",
|
||||
"required": ["serviceId", "srcId", "registeredDelivery", "msgFmt"],
|
||||
"properties": {
|
||||
"serviceId": { "type": "string", "minLength": 1 },
|
||||
"srcId": { "type": "string", "minLength": 1 },
|
||||
"registeredDelivery": { "type": "integer", "enum": [0, 1] },
|
||||
"msgFmt": { "type": "integer", "enum": [8, 15] },
|
||||
"feeUserType": { "type": "integer", "minimum": 0 },
|
||||
"feeCode": { "type": "string" },
|
||||
"feeType": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"retry": {
|
||||
"type": "object",
|
||||
"required": ["attempt", "maxAttempts"],
|
||||
"properties": {
|
||||
"attempt": { "type": "integer", "minimum": 0 },
|
||||
"maxAttempts": { "type": "integer", "minimum": 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"SubmitResult": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/Envelope" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["messageType", "sequenceId", "gatewayMessageId", "submitStatus", "submittedAt"],
|
||||
"properties": {
|
||||
"messageType": { "const": "SubmitResult" },
|
||||
"sequenceId": { "type": "integer", "minimum": 0 },
|
||||
"gatewayMessageId": { "type": "string", "minLength": 1 },
|
||||
"submitStatus": { "enum": ["accepted", "rejected", "timeout"] },
|
||||
"errorCode": { "type": "string" },
|
||||
"errorMessage": { "type": "string" },
|
||||
"submittedAt": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ReceiptEvent": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/Envelope" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["messageType", "sequenceId", "gatewayMessageId", "receiptStatus", "rawStatus", "deliveredAt"],
|
||||
"properties": {
|
||||
"messageType": { "const": "ReceiptEvent" },
|
||||
"sequenceId": { "type": "integer", "minimum": 0 },
|
||||
"gatewayMessageId": { "type": "string", "minLength": 1 },
|
||||
"receiptStatus": { "enum": ["delivered", "undelivered", "unknown"] },
|
||||
"rawStatus": { "type": "string", "minLength": 1 },
|
||||
"errorCode": { "type": "string" },
|
||||
"deliveredAt": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"UplinkEvent": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/Envelope" },
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["messageType", "sequenceId", "phoneNumber", "destId", "content", "receivedAt"],
|
||||
"properties": {
|
||||
"messageType": { "const": "UplinkEvent" },
|
||||
"sequenceId": { "type": "integer", "minimum": 0 },
|
||||
"phoneNumber": { "type": "string", "pattern": "^1[3-9][0-9]{9}$" },
|
||||
"destId": { "type": "string", "minLength": 1 },
|
||||
"content": { "type": "string", "minLength": 1 },
|
||||
"receivedAt": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,78 @@
|
||||
# 阶段 0 开源 CMPP 技术初评
|
||||
|
||||
核验日期:2026-07-01
|
||||
|
||||
## 初步结论
|
||||
|
||||
- `bigwhite/gocmpp` 更符合本项目“复用协议层、服务层自研”的方向,可作为第一优先协议库候选。
|
||||
- `JoeCao/cmpp-gateway` 更接近完整 HTTP 网关,不建议直接绑定业务模型;适合参考连接模型、重连、SEQID/MSGID 追踪、模拟器和降级设计。
|
||||
- 当前已完成 Go 1.26.4 下的 gocmpp 编译级接入、本地 TCP connect/submit/active test 测试和 deliver 回执 PDU 测试。
|
||||
- 阶段 0 决策:第一版协议层优先直接依赖 gocmpp,暂不 fork;服务层连接管理、重连、SEQID/MSGID 追踪、队列、限速、监控、幂等由本项目自研。
|
||||
|
||||
## bigwhite/gocmpp
|
||||
|
||||
来源:
|
||||
|
||||
- GitHub:https://github.com/bigwhite/gocmpp
|
||||
- pkg.go.dev:https://pkg.go.dev/github.com/bigwhite/gocmpp
|
||||
|
||||
### 已确认信息
|
||||
|
||||
- GitHub 标注 License 为 Apache-2.0。
|
||||
- 项目定位是 Go CMPP 协议库,可用于 client 和 server side。
|
||||
- README/pkg.go.dev 描述覆盖 CMPP 2.x 和 CMPP 3.x。
|
||||
- 已支持 connect、submit、deliver、fwd、active test、terminate。
|
||||
- query、cancel、route 等较少使用包未支持,且不在路线图中。
|
||||
- pkg.go.dev 可见基础连接 API,如 `Conn`、`SendPkt`、`RecvAndUnpackPkt`、`Server`。
|
||||
- 本地通过 `goproxy.cn` 成功解析 `github.com/bigwhite/gocmpp v0.0.0-20240917054108-b238366bff0b` 和 `golang.org/x/text v0.3.8`。
|
||||
- Gateway Spike 已创建 `internal/cmpp` 编译级适配测试,验证 `NewClient`、CMPP 2.0/3.0 类型映射可编译。
|
||||
- Gateway Spike 已创建本地 TCP 集成测试,验证 CMPP 3.0 connect、submit、submit resp、active test。
|
||||
- Gateway Spike 已创建 deliver 回执 pack/unpack 测试,验证 `DELIVRD` 状态报告可解析。
|
||||
|
||||
### 对本项目的价值
|
||||
|
||||
- 可降低从零实现 PDU 编解码、连接包、submit、deliver、active test、terminate 的风险。
|
||||
- 支持 client/server 双侧能力,有利于本地模拟 SMSC 和 Gateway 联调。
|
||||
- Apache-2.0 对商业项目相对友好,但仍需最终法务或项目负责人确认。
|
||||
|
||||
### 待实测问题
|
||||
|
||||
- Linux 编译情况。
|
||||
- 长短信拆分、UCS2、GBK/GB18030 编码稳定性。
|
||||
- submit resp 与 deliver 状态报告解析是否满足运营商实际格式。
|
||||
- 高并发 submit 下 sequence 管理、窗口控制和错误恢复能力。
|
||||
- 是否需要 fork 修补现代依赖、日志、context、超时、指标等工程化能力;阶段 0 暂不 fork。
|
||||
|
||||
## JoeCao/cmpp-gateway
|
||||
|
||||
来源:
|
||||
|
||||
- GitHub:https://github.com/JoeCao/cmpp-gateway
|
||||
|
||||
### 已确认信息
|
||||
|
||||
- 项目定位是 CMPP 3.0 HTTP 网关,将 CMPP 协议转换为 HTTP API。
|
||||
- README 描述包含单连接多协程模型:Receiver、Sender、Heartbeat。
|
||||
- README 描述包含 SEQID 到 Message、MSGID 到 Message 的追踪链路。
|
||||
- README 描述内置心跳检测、断线重连、连接降级提示。
|
||||
- README 描述支持 BoltDB 和 Redis 做状态追踪。
|
||||
- README 描述包含本地 CMPP 模拟器,支持 CMPP 3.0 和 2.0、submit 成功响应、心跳保活和协议日志。
|
||||
- README 描述技术栈使用 Go 1.21+、gocmpp、Redis、标准库 net/http、GB18030。
|
||||
|
||||
### 对本项目的价值
|
||||
|
||||
- 可参考连接、重连、接收、发送和心跳协程的职责拆分。
|
||||
- 可参考 SEQID/MSGID 映射缓存设计,但本项目需改为以平台 `messageId` 为主键,和 NestJS/BullMQ 事件贯通。
|
||||
- 可参考模拟器设计,快速补齐 connect、submit resp、deliver、active test 和异常场景。
|
||||
|
||||
### 不建议直接采用的原因
|
||||
|
||||
- 它是完整 HTTP 网关,包含 HTTP API、Web UI、本地存储等服务层设计,和本项目“业务后台由 NestJS 负责,Go Gateway 只做 CMPP 连接和事件回传”的边界不一致。
|
||||
- 本项目需要 Redis/BullMQ 队列契约、通道级限速、业务后台路由和账务追踪,直接接入会形成业务模型耦合。
|
||||
- 第一版应避免直接照搬完整开源网关,服务层按项目自研。
|
||||
|
||||
## 阶段 0 后续实测清单
|
||||
|
||||
1. 在阶段 1 工程骨架中保留 `internal/cmpp` 适配层,避免业务代码直接散落调用 gocmpp。
|
||||
2. 阶段 7 实测断线重连、慢响应、窗口满、重复回执、sequence 回绕。
|
||||
3. 在 Linux 部署环境执行 `go test ./...` 和本地模拟 SMSC 联调。
|
||||
@@ -0,0 +1,60 @@
|
||||
# 阶段 0 Spike 进度记录
|
||||
|
||||
## 2026-07-01
|
||||
|
||||
### 已完成
|
||||
|
||||
- 阅读第一版需求文档、UI 设计规范、前端路由、客户端布局、运营端布局和 package.json。
|
||||
- 确认第一版边界:保留短信业务,彩信为待开发或隐藏,账户计费进入第一版。
|
||||
- 创建阶段 0 最小工程计划。
|
||||
- 创建 NestJS 与 Go Gateway 队列消息 Schema 和示例消息。
|
||||
- 创建队列契约校验脚本。
|
||||
- 完成 `bigwhite/gocmpp` 与 `JoeCao/cmpp-gateway` 在线资料初评,记录到 `docs/phase-0-open-source-evaluation.md`。
|
||||
- 创建 `api/` 与 `gateway/` 阶段 0 README 骨架,明确 Spike 边界。
|
||||
- 安装 Go 1.26.4,补齐 Gateway Spike 可编译环境。
|
||||
- 创建 Go Gateway 队列消息结构、追踪器、内存模拟 submit resp/deliver 链路和 15000 条模拟压测命令。
|
||||
- 使用 `goproxy.cn` 成功接入 `github.com/bigwhite/gocmpp`,并创建编译级适配测试。
|
||||
- 安装 Redis Windows portable fork 8.8.0,启动本地 Redis 并通过 `PONG` 验证。
|
||||
- 安装 BullMQ/ioredis,创建 `api/src/spike/bullmq-link-spike.mjs`,跑通 15000 条 Redis/BullMQ 模拟链路。
|
||||
- 基于 gocmpp 创建本地 TCP 集成测试,覆盖 CMPP 3.0 connect、submit、submit resp、active test。
|
||||
- 基于 gocmpp 完成 deliver 回执 PDU pack/unpack 测试。
|
||||
- 创建 Gateway 重连状态机和测试,验证首次断线后第二次连接成功的重试路径。
|
||||
|
||||
### 验证记录
|
||||
|
||||
- `node --version`:v24.16.0。
|
||||
- `npm --version`:11.13.0。
|
||||
- `go version`:go1.26.4 windows/amd64。
|
||||
- `npm run spike:contracts`:通过,4 个队列消息示例通过校验。
|
||||
- `npm run build`:通过,Vite 输出 chunk 大小告警,不阻塞构建。
|
||||
- `npm run spike:gateway`:通过,包含 gocmpp 编译级接入、追踪器测试和内存模拟链路测试。
|
||||
- `go run ./cmd/spike`:通过,15000 条内存模拟链路全部生成 submit result 和 receipt event;本次运行耗时 32.8761 ms,吞吐 456258.50 msg/s。
|
||||
- Redis:通过本地 portable Redis 启动并返回 `PONG`。
|
||||
- `npm run spike:bullmq`:通过,15000 条消息;入队 3444.88 ms,端到端 24377.45 ms,入队 TPS 4354.29,端到端 TPS 615.32,满足 500 条/秒 Spike 指标。
|
||||
- `docker --version` / `docker compose version`:未通过,本机未安装 Docker。
|
||||
|
||||
### 当前阻塞与后续增强
|
||||
|
||||
- Docker 仍不可用;阶段 1 需要补齐 Docker Compose 或给出 Windows 本地替代启动方式。
|
||||
- gocmpp 已完成本地 TCP connect、submit、active test 和 deliver PDU 验证;terminate、慢响应、窗口满、重复回执、sequence 回绕需在阶段 7 稳定性压测继续补充。
|
||||
- 当前 BullMQ Spike 使用 Node 模拟 Gateway worker,不是 Go 进程直接消费 BullMQ;阶段 1/7 需要决定 Go 侧 Redis/BullMQ 兼容消费方式,或通过 NestJS Send Worker 将队列转为 Gateway 内部协议。
|
||||
|
||||
### 下一步
|
||||
|
||||
1. 进入阶段 1:工程骨架。
|
||||
2. 输出阶段 1 实施计划和验收标准。
|
||||
3. 建立 web/api/gateway/infra/docs 的工程结构与基础命令。
|
||||
|
||||
### 阶段 0 验收状态
|
||||
|
||||
| 验收项 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 模拟短信链路:NestJS 入队 -> Go Gateway 提交 -> submit resp -> deliver 回执 -> NestJS 更新状态 | 已完成 | BullMQ/Redis 模拟链路已通过,Node 模拟 Gateway worker 回传 submit result 和 receipt event;Go 内存链路同步通过。 |
|
||||
| Go Gateway 断线后可重连,并继续消费后续消息 | 已完成 | 已完成 Gateway 重连状态机测试;真实通道断线恢复将在阶段 7 加强。 |
|
||||
| 全消息具备 traceId、messageId、channelId、sequenceId 或追踪映射 | 已完成 | Schema、示例、Go tracker 均已覆盖。 |
|
||||
| Spike 文档记录是否采用 gocmpp、是否 fork、哪些能力自研 | 已完成 | 初步结论:协议层优先直接依赖 gocmpp,暂不 fork;连接管理、追踪、队列、限速、监控由本项目自研。 |
|
||||
| 500 条/秒链路 Spike | 已完成 | BullMQ/Redis 端到端 TPS 615.32;Go 内存基线同步超过 500 条/秒。 |
|
||||
|
||||
### 阶段 0 结论
|
||||
|
||||
阶段 0 已完成。第一版可以进入阶段 1 工程骨架建设。
|
||||
@@ -0,0 +1,160 @@
|
||||
# 阶段 0 技术 Spike 最小工程计划
|
||||
|
||||
## 目标
|
||||
|
||||
阶段 0 只验证第一版最大技术风险:NestJS 入队、Go Gateway 消费、模拟 CMPP 提交、submit resp、deliver 回执、上行事件回传、断线重连和 500 条/秒链路能力。
|
||||
|
||||
本阶段不实现完整业务审核、风控、计费、报备、路由后台,也不从零手写完整 CMPP 协议栈。
|
||||
|
||||
## 1. 目录结构建议
|
||||
|
||||
当前仓库先保留现有 React + TypeScript + Vite 原型作为根目录前端。阶段 0 建议以最小增量方式补齐后端和网关 Spike 目录:
|
||||
|
||||
```text
|
||||
.
|
||||
├── docs/
|
||||
│ ├── contracts/
|
||||
│ │ ├── gateway-queue-messages.schema.json
|
||||
│ │ └── examples/
|
||||
│ ├── phase-0-technical-spike-plan.md
|
||||
│ └── phase-0-spike-progress.md
|
||||
├── api/
|
||||
│ ├── README.md
|
||||
│ └── src/
|
||||
│ └── spike/
|
||||
│ └── queue-contracts/
|
||||
├── gateway/
|
||||
│ ├── README.md
|
||||
│ ├── cmd/
|
||||
│ │ ├── gateway/
|
||||
│ │ └── smsc-simulator/
|
||||
│ └── internal/
|
||||
│ ├── cmpp/
|
||||
│ ├── queue/
|
||||
│ ├── connection/
|
||||
│ ├── tracker/
|
||||
│ └── metrics/
|
||||
└── tools/
|
||||
└── spike/
|
||||
└── validate-gateway-queue-contract.mjs
|
||||
```
|
||||
|
||||
阶段 1 再决定是否迁移为正式 monorepo:
|
||||
|
||||
- `web/`:当前 React 原型。
|
||||
- `api/`:NestJS + Prisma + BullMQ。
|
||||
- `gateway/`:Go CMPP Gateway。
|
||||
- `infra/`:PostgreSQL、Redis、MinIO、Prometheus、Grafana 的 compose 与部署配置。
|
||||
|
||||
## 2. NestJS 与 Go Gateway 队列消息格式
|
||||
|
||||
阶段 0 采用 Redis + BullMQ 作为通信基线。NestJS 只负责投递已经完成业务校验和路由决策后的发送指令;Go Gateway 只负责协议提交和事件回传。
|
||||
|
||||
### 队列命名
|
||||
|
||||
- `cmpp.submit.commands`:NestJS -> Go Gateway,单号码发送指令。
|
||||
- `cmpp.submit.results`:Go Gateway -> NestJS,submit resp 结果。
|
||||
- `cmpp.receipt.events`:Go Gateway -> NestJS,deliver 回执事件。
|
||||
- `cmpp.uplink.events`:Go Gateway -> NestJS,上行短信事件。
|
||||
|
||||
### 统一信封
|
||||
|
||||
每条消息必须包含:
|
||||
|
||||
- `schemaVersion`:当前固定为 `v1`。
|
||||
- `messageType`:消息类型。
|
||||
- `traceId`:贯穿 API、队列、网关、回执的链路 ID。
|
||||
- `messageId`:平台单号码短信 ID,全局唯一。
|
||||
- `channelId`:业务后台选定的通道 ID。
|
||||
- `createdAt`:ISO 8601 时间。
|
||||
|
||||
### 发送指令
|
||||
|
||||
`SubmitCommand` 由 NestJS 或 Send Worker 产生。必须包含 `tenantId`、`applicationId`、`submitId`、`phoneNumber`、`content`、`signature`、`templateId`、`billingUnits`、`route`、`cmpp` 和 `retry`。
|
||||
|
||||
Go Gateway 不根据签名、模板、账户余额做业务判断,只读取 `route.cmppAccountCode`、`cmpp.serviceId`、`cmpp.srcId`、`cmpp.registeredDelivery`、`cmpp.msgFmt` 等协议提交所需字段。
|
||||
|
||||
### 结果和事件
|
||||
|
||||
- `SubmitResult` 必须回传 `sequenceId`、`gatewayMessageId`、`submitStatus`、`submittedAt`。
|
||||
- `ReceiptEvent` 必须回传 `gatewayMessageId`、`sequenceId`、`receiptStatus`、`deliveredAt`、`rawStatus`。
|
||||
- `UplinkEvent` 必须回传 `phoneNumber`、`destId`、`content`、`receivedAt`、`sequenceId`。
|
||||
|
||||
详细结构以 `docs/contracts/gateway-queue-messages.schema.json` 为准。
|
||||
|
||||
## 3. Go Gateway 最小能力清单
|
||||
|
||||
阶段 0 最小 Go Gateway 只做以下能力:
|
||||
|
||||
1. 读取一个通道配置:网关地址、端口、企业代码、账号、密码、接入号、CMPP 版本、窗口大小、心跳间隔、重连间隔。
|
||||
2. 基于 gocmpp 或评估后的协议库完成 connect、active test、submit、deliver、terminate。
|
||||
3. 消费 `cmpp.submit.commands`,提交到模拟 SMSC。
|
||||
4. 将 submit resp 写入 `cmpp.submit.results`。
|
||||
5. 将 deliver 回执写入 `cmpp.receipt.events`。
|
||||
6. 将上行短信写入 `cmpp.uplink.events`。
|
||||
7. 维护 `messageId -> sequenceId -> gatewayMessageId` 的追踪映射。
|
||||
8. 支持断线重连,重连后继续消费后续消息。
|
||||
9. 暴露最小健康检查和指标:连接状态、队列积压、提交 TPS、submit 成功率、回执延迟、重连次数。
|
||||
10. 支持模拟 SMSC:正常响应、慢响应、断线、重复回执、窗口满。
|
||||
|
||||
## 4. gocmpp 与 cmpp-gateway 技术评估任务
|
||||
|
||||
评估对象:
|
||||
|
||||
- `bigwhite/gocmpp`:优先评估为协议层依赖。
|
||||
- `JoeCao/cmpp-gateway`:只作为连接管理、重连、SEQID/MSGID 追踪和模拟器设计参考。
|
||||
|
||||
任务清单:
|
||||
|
||||
1. License:确认依赖许可是否允许第一版商业项目使用。
|
||||
2. 维护活跃度:确认最近提交、Issue、PR、Go module 支持情况。
|
||||
3. 协议覆盖:确认 CMPP 2.0/3.0、connect、submit、deliver、active test、terminate 支持情况。
|
||||
4. 编解码可靠性:验证长短信、UCS2、GBK、状态报告、上行短信解析。
|
||||
5. 连接模型:评估长连接、心跳、窗口、并发 submit、断线重连。
|
||||
6. 追踪能力:验证 sequenceId、msgId、平台 messageId 的映射方案。
|
||||
7. 模拟器:复用或参考模拟 SMSC 的响应、慢响应、断线和重复回执能力。
|
||||
8. 改造边界:判断直接依赖、轻量 fork、或只参考实现的取舍。
|
||||
9. 风险清单:列出协议层缺口、生产部署风险、测试补充项。
|
||||
|
||||
## 5. 500 条/秒 Spike 压测指标
|
||||
|
||||
压测只验证链路调度能力,不验证完整业务规则。
|
||||
|
||||
### 场景
|
||||
|
||||
1. NestJS 批量投递 30 秒,共 15000 条发送指令。
|
||||
2. Go Gateway 消费队列并提交到模拟 SMSC。
|
||||
3. 模拟 SMSC 立即返回 submit resp,并在 1 到 3 秒内返回 deliver。
|
||||
4. 重复执行单连接和多连接两个场景。
|
||||
5. 插入异常场景:模拟 SMSC 慢响应、短暂断线、重复回执。
|
||||
|
||||
### 指标
|
||||
|
||||
- 入队吞吐:P50、P95、P99,每秒入队数必须稳定达到 500。
|
||||
- 消费吞吐:每秒消费并提交数,30 秒平均不低于 500。
|
||||
- 端到端延迟:入队到 submit resp P95 小于 2 秒。
|
||||
- 回执延迟:deliver 到 NestJS 消费 P95 小于 10 秒。
|
||||
- 错误率:submit command 处理失败率小于 0.1%。
|
||||
- 重试率:异常场景下可观测且不造成重复最终状态。
|
||||
- 队列积压:压测停止后 30 秒内归零。
|
||||
- 资源指标:CPU、内存、Redis ops、连接重连次数。
|
||||
- 幂等指标:重复回执只产生一条最终状态更新,多余回执进入历史记录。
|
||||
|
||||
## 6. 阶段 0 验收标准
|
||||
|
||||
1. 跑通一条模拟短信链路:NestJS 入队 -> Go Gateway 提交 -> submit resp -> deliver 回执 -> NestJS 更新状态。
|
||||
2. Go Gateway 断线后可重连,并能继续消费后续消息。
|
||||
3. 所有消息具备 `traceId`、`messageId`、`channelId`、`sequenceId` 或可追踪映射。
|
||||
4. 队列消息 Schema、示例消息和校验脚本通过。
|
||||
5. 完成 gocmpp 与 JoeCao/cmpp-gateway 评估记录,明确最终依赖方式。
|
||||
6. 完成 500 条/秒压测报告,包含瓶颈、资源使用和下一阶段优化建议。
|
||||
7. 文档记录 Go Gateway 哪些能力复用协议库,哪些服务层能力由本项目自研。
|
||||
|
||||
## 阶段 0 执行顺序
|
||||
|
||||
1. 创建阶段 0 计划文档、队列消息 Schema、示例消息和校验脚本。
|
||||
2. 创建 Go Gateway Spike 骨架和模拟 SMSC 骨架。
|
||||
3. 创建 NestJS Spike 骨架,完成 BullMQ 入队和事件消费。
|
||||
4. 接入 Redis 本地环境,跑通模拟链路。
|
||||
5. 评估 gocmpp 与 JoeCao/cmpp-gateway。
|
||||
6. 完成 500 条/秒压测脚本和报告。
|
||||
@@ -0,0 +1,55 @@
|
||||
# 阶段 1 工程骨架实施计划
|
||||
|
||||
## 目标
|
||||
|
||||
让前端原型、NestJS API、Go CMPP Gateway 和基础设施具备稳定启动、构建、测试和文档入口,为阶段 2 到阶段 8 的业务开发提供工程底座。
|
||||
|
||||
## 实施步骤
|
||||
|
||||
1. 文档与阶段门
|
||||
- 创建阶段 1 计划和进度记录。
|
||||
- 明确阶段 1 不实现完整业务,只建立工程骨架。
|
||||
|
||||
2. 前端工程边界
|
||||
- 当前 React + TypeScript + Vite 原型暂时保留在仓库根目录。
|
||||
- 第一版继续保留短信业务和账户计费入口,彩信入口保持待开发或后续隐藏。
|
||||
- 后续如迁移到 `web/`,需单独做无行为变化迁移。
|
||||
|
||||
3. NestJS API 骨架
|
||||
- 创建 `api/package.json`、`tsconfig.json`、`src/main.ts`、`src/app.module.ts`。
|
||||
- 配置健康检查接口。
|
||||
- 配置 Swagger/OpenAPI 文档入口。
|
||||
- 配置环境变量读取。
|
||||
- 保留阶段 0 BullMQ Spike 脚本。
|
||||
|
||||
4. Prisma 与数据库流程
|
||||
- 创建 `api/prisma/schema.prisma`。
|
||||
- 建立 `prisma generate` 和迁移命令入口。
|
||||
- 阶段 1 只定义基础连接和首批占位模型,不展开完整业务表。
|
||||
|
||||
5. Go Gateway 骨架
|
||||
- 保留阶段 0 gocmpp 适配、追踪器、重连状态机和 Spike 测试。
|
||||
- 增加健康检查 HTTP server 入口。
|
||||
- 明确 Gateway 只做 CMPP 连接、提交、submit resp、回执、上行事件回传。
|
||||
|
||||
6. 基础设施
|
||||
- 创建 `infra/docker-compose.yml`,覆盖 PostgreSQL、Redis、MinIO。
|
||||
- 创建 `.env.example`,列出 web/api/gateway/infra 的必要变量。
|
||||
- 当前 Windows 本地可用 Redis portable;Linux/容器环境以 Docker Compose 为准。
|
||||
|
||||
7. 统一验证命令
|
||||
- 根目录保留前端 `npm run build`。
|
||||
- 增加 API 构建命令。
|
||||
- 保留 `npm run spike:contracts`、`npm run spike:bullmq`、`npm run spike:gateway`。
|
||||
- 阶段 1 完成时执行全套验证。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 前端:`npm run build` 通过。
|
||||
- API:`cd api && npm run build` 通过,健康检查和 Swagger 入口代码存在。
|
||||
- Gateway:`npm run spike:gateway` 通过。
|
||||
- 队列契约:`npm run spike:contracts` 通过。
|
||||
- BullMQ Spike:`npm run spike:bullmq` 通过。
|
||||
- 基础设施:`infra/docker-compose.yml` 包含 PostgreSQL、Redis、MinIO。
|
||||
- Prisma:`api/prisma/schema.prisma` 存在,API package 提供 `prisma:generate` 和迁移命令。
|
||||
- 文档:`docs/phase-1-engineering-skeleton-progress.md` 记录每一步验证结果。
|
||||
@@ -0,0 +1,53 @@
|
||||
# 阶段 1 工程骨架进度记录
|
||||
|
||||
## 2026-07-01
|
||||
|
||||
### 阶段计划
|
||||
|
||||
- 已创建 `docs/phase-1-engineering-skeleton-plan.md`。
|
||||
- 阶段 1 范围限定为工程骨架,不展开完整业务实现。
|
||||
|
||||
### 验证记录
|
||||
|
||||
- 创建阶段 1 计划和进度文档后执行:
|
||||
- `npm run spike:contracts`:通过。
|
||||
- `npm run spike:gateway`:通过。
|
||||
- `npm run build`:通过,仍有 Vite chunk 大小告警,不阻塞。
|
||||
- 创建 NestJS API 骨架后执行:
|
||||
- `cd api && npm install`:完成,npm audit 报 7 个漏洞(3 moderate、4 high),暂未执行 `npm audit fix --force` 以避免破坏依赖版本。
|
||||
- `cd api && npm run build`:首次因 TypeScript 6 配置要求失败,补充 `rootDir` 和 `ignoreDeprecations` 后通过。
|
||||
- 创建基础设施和 Gateway 健康检查后执行:
|
||||
- `npm run spike:gateway`:通过,包含 Gateway health handler 测试。
|
||||
- `cd api && npm run build`:通过。
|
||||
- `npm run build`:通过,仍有 Vite chunk 大小告警,不阻塞。
|
||||
- 迁移 Prisma 7 配置后执行:
|
||||
- `cd api && npm run prisma:generate`:通过。
|
||||
- `cd api && npm run build`:通过。
|
||||
- 阶段 1 完整验证:
|
||||
- `npm run verify:phase1`:通过。
|
||||
- BullMQ 本轮端到端 TPS:948.32,满足 500 条/秒 Spike 验证线。
|
||||
- Prisma Client 生成成功。
|
||||
- API 构建成功。
|
||||
- 前端构建成功,仍有 Vite chunk 大小告警,不阻塞。
|
||||
|
||||
### 阶段 1 验收状态
|
||||
|
||||
| 验收项 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 前端 `npm run build` 通过 | 已完成 | 当前 React + Vite 原型构建通过。 |
|
||||
| API `cd api && npm run build` 通过 | 已完成 | NestJS health/Swagger 骨架可编译。 |
|
||||
| Gateway `npm run spike:gateway` 通过 | 已完成 | gocmpp、重连、health、追踪器测试通过。 |
|
||||
| 队列契约 `npm run spike:contracts` 通过 | 已完成 | 4 个示例通过校验。 |
|
||||
| BullMQ Spike `npm run spike:bullmq` 通过 | 已完成 | 15000 条端到端 TPS 948.32。 |
|
||||
| 基础设施 compose 覆盖 PostgreSQL、Redis、MinIO | 已完成 | `infra/docker-compose.yml` 已创建;本机暂无 Docker,未执行 compose up。 |
|
||||
| Prisma schema 和命令入口存在 | 已完成 | `api/prisma/schema.prisma`、`api/prisma.config.ts` 和 npm scripts 已创建。 |
|
||||
| 文档记录阶段 1 进度 | 已完成 | 本文件已记录。 |
|
||||
|
||||
### 阶段 1 结论
|
||||
|
||||
阶段 1 已完成。第一版可以进入阶段 2 基础后台。
|
||||
|
||||
### 下一步
|
||||
|
||||
1. 输出阶段 2 实施计划和验收标准。
|
||||
2. 按阶段 2 建立认证、租户、用户、角色、权限、操作日志、文件、基础字典和账户计费基础模型。
|
||||
@@ -0,0 +1,38 @@
|
||||
# 阶段 2 基础后台实施计划
|
||||
|
||||
## 目标
|
||||
|
||||
完成第一版业务底座:认证、租户隔离、用户/角色/权限、操作日志、文件上传元数据、基础字典、手机号段、敏感词、黑名单、引流字段、账户/套餐/账务流水基础模型。
|
||||
|
||||
阶段 2 优先建立后端模型与模块边界,不展开完整页面联调。
|
||||
|
||||
## 实施步骤
|
||||
|
||||
1. Prisma 基础模型
|
||||
- 租户、用户、角色、权限、用户角色、角色权限。
|
||||
- 操作日志。
|
||||
- 文件对象元数据。
|
||||
- 手机号段、敏感词、企业黑名单、全局黑名单、引流字段。
|
||||
- 账户、套餐、账务流水、计费规则。
|
||||
|
||||
2. NestJS 模块边界
|
||||
- `AuthModule`
|
||||
- `TenantsModule`
|
||||
- `UsersModule`
|
||||
- `AuditModule`
|
||||
- `FilesModule`
|
||||
- `DictionariesModule`
|
||||
- `BillingModule`
|
||||
|
||||
3. 验证
|
||||
- `npm --prefix api run prisma:generate`
|
||||
- `npm --prefix api run build`
|
||||
- `npm run verify:phase1`
|
||||
|
||||
## 验收标准
|
||||
|
||||
- Prisma Client 生成成功。
|
||||
- API 构建成功。
|
||||
- 基础模型覆盖阶段 2 范围。
|
||||
- NestJS 模块边界存在并被 AppModule 引入。
|
||||
- 文档记录阶段 2 进度和验证结果。
|
||||
@@ -0,0 +1,107 @@
|
||||
# 阶段 2 基础后台进度记录
|
||||
|
||||
## 2026-07-01
|
||||
|
||||
### 阶段计划
|
||||
|
||||
- 已创建 `docs/phase-2-foundation-backend-plan.md`。
|
||||
- 阶段 2 第一轮聚焦后端模型和模块边界。
|
||||
|
||||
### 验证记录
|
||||
|
||||
- 扩展 Prisma 基础模型并创建 NestJS 模块边界后执行:
|
||||
- `cd api && npm run prisma:generate`:通过。
|
||||
- `cd api && npm run build`:通过。
|
||||
- 阶段回归验证:
|
||||
- `npm run verify:phase1`:通过。
|
||||
- BullMQ 本轮端到端 TPS:1019.27,满足 500 条/秒验证线。
|
||||
- Prisma Client 生成成功。
|
||||
- API 构建成功。
|
||||
- 前端构建成功,仍有 Vite chunk 大小告警,不阻塞。
|
||||
- 实现基础后台最小 API 后执行:
|
||||
- `cd api && npm run prisma:generate`:通过。
|
||||
- `cd api && npm run build`:通过。
|
||||
- API health 冒烟:`GET http://127.0.0.1:3101/api/health` 返回 `{"status":"ok","service":"cmpp-platform-api",...}`。
|
||||
- 阶段 2 完整验证:
|
||||
- `npm run verify:phase2`:通过。
|
||||
- BullMQ 本轮端到端 TPS:531.54,满足 500 条/秒验证线。
|
||||
- Prisma Client 生成成功。
|
||||
- API 构建成功。
|
||||
- 前端构建成功,仍有 Vite chunk 大小告警,不阻塞。
|
||||
|
||||
### 已完成
|
||||
|
||||
- Prisma 基础模型:
|
||||
- `Tenant`
|
||||
- `User`
|
||||
- `Role`
|
||||
- `Permission`
|
||||
- `UserRole`
|
||||
- `RolePermission`
|
||||
- `OperationLog`
|
||||
- `FileObject`
|
||||
- `PhoneSegment`
|
||||
- `SensitiveWord`
|
||||
- `EnterpriseBlacklist`
|
||||
- `GlobalBlacklist`
|
||||
- `DrainageField`
|
||||
- `BillingPlan`
|
||||
- `TenantAccount`
|
||||
- `AccountTransaction`
|
||||
- `BillingRule`
|
||||
- NestJS 模块边界:
|
||||
- `AuthModule`
|
||||
- `TenantsModule`
|
||||
- `UsersModule`
|
||||
- `AuditModule`
|
||||
- `FilesModule`
|
||||
- `DictionariesModule`
|
||||
- `BillingModule`
|
||||
- 最小 API 能力:
|
||||
- `POST /api/client/auth/login`
|
||||
- `GET/POST /api/admin/tenants`
|
||||
- `GET/POST /api/admin/users`
|
||||
- `GET/POST /api/admin/users/roles`
|
||||
- `GET/POST /api/admin/users/permissions`
|
||||
- `POST /api/admin/users/roles/assign`
|
||||
- `POST /api/admin/users/permissions/assign`
|
||||
- `GET/POST /api/admin/operation-logs`
|
||||
- `GET/POST /api/admin/files`
|
||||
- `POST /api/admin/files/presigned-upload`
|
||||
- `GET/POST /api/admin/dictionaries/phone-segments`
|
||||
- `GET/POST /api/admin/dictionaries/sensitive-words`
|
||||
- `GET/POST /api/admin/dictionaries/blacklists/global`
|
||||
- `GET/POST /api/admin/dictionaries/blacklists/enterprise`
|
||||
- `GET/POST /api/admin/dictionaries/drainage-fields`
|
||||
- `GET/POST /api/admin/billing/plans`
|
||||
- `GET/POST /api/admin/billing/accounts`
|
||||
- `GET/POST /api/admin/billing/transactions`
|
||||
- `GET/POST /api/admin/billing/rules`
|
||||
- `GET /api/client/billing/plans`
|
||||
- `GET /api/client/billing/transactions`
|
||||
- 基础设施:
|
||||
- Prisma 7 使用 `@prisma/adapter-pg`。
|
||||
- 文件上传使用 MinIO SDK 生成预签名上传 URL。
|
||||
- `PrismaService` 懒连接,允许无 PostgreSQL 时启动 health/Swagger。
|
||||
|
||||
### 阶段 2 验收状态
|
||||
|
||||
| 验收项 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 登录认证基础接口 | 已完成 | 已有用户名/密码登录占位,返回开发 token;正式 JWT/密码算法阶段后续加强。 |
|
||||
| 企业/租户基础能力 | 已完成 | 租户列表、详情、创建接口已实现。 |
|
||||
| 用户、角色、权限 | 已完成 | 用户、角色、权限、分配关系接口已实现。 |
|
||||
| 操作日志 | 已完成 | 操作日志列表和创建接口已实现。 |
|
||||
| 文件上传和对象存储 | 已完成 | 文件元数据接口和 MinIO 预签名上传入口已实现。 |
|
||||
| 基础字典 | 已完成 | 手机号段、敏感词、黑名单、引流字段接口已实现。 |
|
||||
| 账户、套餐、账务流水基础模型 | 已完成 | 套餐、账户、流水、计费规则接口已实现,客户端账单查询入口已提供。 |
|
||||
| 构建/生成验证 | 已完成 | Prisma generate、API build、API health 冒烟均通过。 |
|
||||
|
||||
### 阶段 2 结论
|
||||
|
||||
阶段 2 已完成。第一版可以进入阶段 3 短信配置。
|
||||
|
||||
### 下一步
|
||||
|
||||
1. 输出阶段 3 实施计划和验收标准。
|
||||
2. 实现短信应用、签名、签名资料、模板、模板变量、审核记录基础模型和接口。
|
||||
@@ -0,0 +1,41 @@
|
||||
# 阶段 3 短信配置实施计划
|
||||
|
||||
## 目标
|
||||
|
||||
让客户和运营能配置发送短信所需资源:短信应用、应用密钥和 IP 白名单、应用发送限额、不符合模板短信处理策略、短信签名、签名资料、短信模板、模板变量、审核记录和审核工作台基础接口。
|
||||
|
||||
## 实施步骤
|
||||
|
||||
1. Prisma 模型
|
||||
- `SmsApplication`
|
||||
- `SmsApplicationIpAllowlist`
|
||||
- `SmsSignature`
|
||||
- `SignatureMaterial`
|
||||
- `SmsTemplate`
|
||||
- `TemplateVariable`
|
||||
- `AuditRecord`
|
||||
|
||||
2. NestJS 模块
|
||||
- `SmsConfigModule`
|
||||
- 客户端接口:应用、签名、模板创建/查询/提交审核。
|
||||
- 运营端接口:企业应用/签名/模板查询,签名/模板审核通过或驳回。
|
||||
|
||||
3. 规则约束
|
||||
- 应用、签名、模板均按 `tenantId` 隔离。
|
||||
- 已审核模板主体第一版不允许直接修改;阶段 3 先不实现编辑接口,后续如需要编辑只允许草稿/驳回状态。
|
||||
- 签名和模板提交审核时写入 `AuditRecord`。
|
||||
|
||||
4. 验证
|
||||
- `cd api && npm run prisma:generate`
|
||||
- `cd api && npm run build`
|
||||
- API health 冒烟
|
||||
- `npm run verify:phase2`
|
||||
|
||||
## 验收标准
|
||||
|
||||
- Prisma Client 生成成功。
|
||||
- API 构建成功。
|
||||
- `SmsConfigModule` 被 AppModule 引入。
|
||||
- 客户端短信应用、签名、模板基础接口存在。
|
||||
- 运营端短信应用、签名、模板查询和审核接口存在。
|
||||
- 阶段 3 进度文档记录验证结果。
|
||||
@@ -0,0 +1,81 @@
|
||||
# 阶段 3 短信配置进度记录
|
||||
|
||||
## 2026-07-01
|
||||
|
||||
### 阶段计划
|
||||
|
||||
- 已创建 `docs/phase-3-sms-configuration-plan.md`。
|
||||
- 阶段 3 聚焦短信配置域,不开发彩信功能。
|
||||
|
||||
### 验证记录
|
||||
|
||||
- 创建阶段 3 计划文档、扩展 Prisma 短信配置模型后执行:
|
||||
- `cd api && npm run prisma:generate`:通过。
|
||||
- `cd api && npm run build`:通过。
|
||||
- 实现 `SmsConfigModule`、客户端/运营端最小接口后执行:
|
||||
- `cd api && npm run prisma:generate`:通过。
|
||||
- `cd api && npm run build`:通过。
|
||||
- API health 冒烟:`GET http://127.0.0.1:3101/api/health` 返回 `{"status":"ok","service":"cmpp-platform-api",...}`。
|
||||
- 阶段 3 完整验证:
|
||||
- `npm run verify:phase3`:通过。
|
||||
- BullMQ 本轮端到端 TPS:548.52,满足 500 条/秒验证线。
|
||||
- Prisma Client 生成成功。
|
||||
- API 构建成功。
|
||||
- 前端构建成功,仍有 Vite chunk 大小告警,不阻塞。
|
||||
|
||||
### 已完成
|
||||
|
||||
- Prisma 短信配置模型:
|
||||
- `SmsApplication`
|
||||
- `SmsApplicationIpAllowlist`
|
||||
- `SmsSignature`
|
||||
- `SignatureMaterial`
|
||||
- `SmsTemplate`
|
||||
- `TemplateVariable`
|
||||
- `AuditRecord`
|
||||
- NestJS 模块:
|
||||
- `SmsConfigModule`
|
||||
- `SmsConfigService`
|
||||
- `ClientSmsConfigController`
|
||||
- `AdminSmsConfigController`
|
||||
- 客户端接口:
|
||||
- `GET/POST /api/client/applications`
|
||||
- `GET/POST /api/client/signatures`
|
||||
- `POST /api/client/signatures/:id/materials`
|
||||
- `POST /api/client/signatures/:id/submit`
|
||||
- `GET/POST /api/client/templates`
|
||||
- `POST /api/client/templates/:id/submit`
|
||||
- 运营端接口:
|
||||
- `GET /api/admin/enterprise-applications`
|
||||
- `GET /api/admin/enterprise-signatures`
|
||||
- `GET /api/admin/enterprise-templates`
|
||||
- `GET /api/admin/audit-records`
|
||||
- `POST /api/admin/signatures/:id/approve`
|
||||
- `POST /api/admin/signatures/:id/reject`
|
||||
- `POST /api/admin/templates/:id/approve`
|
||||
- `POST /api/admin/templates/:id/reject`
|
||||
- 规则:
|
||||
- 签名/模板提交审核会写入 `AuditRecord`。
|
||||
- 审核通过/驳回会更新审核状态并写入 `AuditRecord`。
|
||||
- 模板变量支持显式传入,也支持从 `${变量名}` 自动识别。
|
||||
- 短信计费条数按 70/67 字规则预估。
|
||||
|
||||
### 下一步
|
||||
|
||||
1. 输出阶段 4 实施计划和验收标准。
|
||||
2. 实现短信通道、通道组、路由规则、报备字段、签名报备资料、报备任务、导出/导入记录和报备状态同步。
|
||||
|
||||
### 阶段 3 验收状态
|
||||
|
||||
| 验收项 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| Prisma Client 生成成功 | 已完成 | `npm run prisma:generate` 通过。 |
|
||||
| API 构建成功 | 已完成 | `npm run build` 在 `api` 下通过。 |
|
||||
| `SmsConfigModule` 被 AppModule 引入 | 已完成 | 已引入根模块。 |
|
||||
| 客户端短信应用、签名、模板基础接口存在 | 已完成 | 应用/签名/模板查询、创建、提交审核接口已实现。 |
|
||||
| 运营端短信应用、签名、模板查询和审核接口存在 | 已完成 | 企业应用/签名/模板查询,签名/模板通过/驳回接口已实现。 |
|
||||
| 阶段完整验证 | 已完成 | `npm run verify:phase3` 通过。 |
|
||||
|
||||
### 阶段 3 结论
|
||||
|
||||
阶段 3 已完成。第一版可以进入阶段 4 通道与报备。
|
||||
@@ -0,0 +1,51 @@
|
||||
# 阶段 4 通道与报备实施计划
|
||||
|
||||
## 目标
|
||||
|
||||
让运营端能配置短信通道、通道组、路由规则和签名报备流程;让系统能记录签名在各通道的报备资料、报备任务、导出文件、回执导入和状态同步。
|
||||
|
||||
阶段 4 不实现真实发送链路,真实 CMPP 提交在阶段 7 发送链路接入;本阶段只建立通道和报备配置闭环。
|
||||
|
||||
## 实施步骤
|
||||
|
||||
1. Prisma 模型
|
||||
- `SmsChannel`
|
||||
- `SmsChannelGroup`
|
||||
- `SmsChannelGroupItem`
|
||||
- `ChannelRouteRule`
|
||||
- `ChannelHealthMetric`
|
||||
- `ChannelReportField`
|
||||
- `SignatureReportMaterial`
|
||||
- `ChannelSignatureReportTask`
|
||||
- `ChannelSignatureReportRecord`
|
||||
- `ReportExportFile`
|
||||
- `ReportReceiptImport`
|
||||
|
||||
2. NestJS 模块
|
||||
- `ChannelsModule`
|
||||
- 通道 CRUD、测试短信占位、通道健康指标查询。
|
||||
- 通道组 CRUD、通道组成员配置。
|
||||
- 路由规则 CRUD。
|
||||
- 报备字段配置 CRUD。
|
||||
- 签名报备资料登记。
|
||||
- 报备任务生成、导出记录、回执导入记录、报备记录查询。
|
||||
|
||||
3. 状态同步
|
||||
- 生成报备任务时记录 `pending`。
|
||||
- 导出报备资料时记录导出文件和报备记录。
|
||||
- 导入回执时记录导入批次、回执结果,并更新任务状态。
|
||||
|
||||
4. 验证
|
||||
- `cd api && npm run prisma:generate`
|
||||
- `cd api && npm run build`
|
||||
- API health 冒烟
|
||||
- `npm run verify:phase3`
|
||||
|
||||
## 验收标准
|
||||
|
||||
- Prisma Client 生成成功。
|
||||
- API 构建成功。
|
||||
- `ChannelsModule` 被 AppModule 引入。
|
||||
- 通道、通道组、路由规则、报备字段、报备任务基础接口存在。
|
||||
- 报备导出/导入记录和报备状态同步接口存在。
|
||||
- 阶段 4 进度文档记录验证结果。
|
||||
@@ -0,0 +1,83 @@
|
||||
# 阶段 4 通道与报备进度记录
|
||||
|
||||
## 2026-07-01
|
||||
|
||||
### 阶段计划
|
||||
|
||||
- 已创建 `docs/phase-4-channel-reporting-plan.md`。
|
||||
- 阶段 4 聚焦短信通道和签名报备,不开发彩信通道。
|
||||
|
||||
### 验证记录
|
||||
|
||||
- 创建阶段 4 计划文档、扩展 Prisma 通道与报备模型后执行:
|
||||
- `cd api && npm run prisma:generate`:通过。
|
||||
- `cd api && npm run build`:通过。
|
||||
- 实现 `ChannelsModule`、通道/通道组/路由/报备最小接口后执行:
|
||||
- `cd api && npm run prisma:generate`:通过。
|
||||
- `cd api && npm run build`:通过。
|
||||
- API health 冒烟:`GET http://127.0.0.1:3101/api/health` 返回 `{"status":"ok","service":"cmpp-platform-api",...}`。
|
||||
- 阶段 4 完整验证:
|
||||
- `npm run verify:phase4`:通过。
|
||||
- BullMQ 本轮端到端 TPS:527.63,满足 500 条/秒验证线。
|
||||
- Prisma Client 生成成功。
|
||||
- API 构建成功。
|
||||
- 前端构建成功,仍有 Vite chunk 大小告警,不阻塞。
|
||||
|
||||
### 已完成
|
||||
|
||||
- Prisma 通道与报备模型:
|
||||
- `SmsChannel`
|
||||
- `SmsChannelGroup`
|
||||
- `SmsChannelGroupItem`
|
||||
- `ChannelRouteRule`
|
||||
- `ChannelHealthMetric`
|
||||
- `ChannelReportField`
|
||||
- `SignatureReportMaterial`
|
||||
- `ChannelSignatureReportTask`
|
||||
- `ChannelSignatureReportRecord`
|
||||
- `ReportExportFile`
|
||||
- `ReportReceiptImport`
|
||||
- NestJS 模块:
|
||||
- `ChannelsModule`
|
||||
- `ChannelsService`
|
||||
- `ChannelsController`
|
||||
- 运营端接口:
|
||||
- `GET/POST /api/admin/channels`
|
||||
- `POST /api/admin/channels/:id/test`
|
||||
- `GET /api/admin/channels/:id/metrics`
|
||||
- `GET/POST /api/admin/channel-groups`
|
||||
- `POST /api/admin/channel-groups/items`
|
||||
- `GET/POST /api/admin/channel-route-rules`
|
||||
- `GET/POST /api/admin/channel-report-fields`
|
||||
- `GET/POST /api/admin/signature-report-materials`
|
||||
- `GET /api/admin/report-tasks`
|
||||
- `POST /api/admin/report-tasks/generate`
|
||||
- `POST /api/admin/report-tasks/:id/export`
|
||||
- `POST /api/admin/report-tasks/:id/receipt-import`
|
||||
- `GET /api/admin/report-records`
|
||||
- 报备状态规则:
|
||||
- 生成报备任务时创建 `pending` 任务和报备记录。
|
||||
- 导出报备资料时创建导出文件记录,并将任务状态更新为 `exporting`。
|
||||
- 导入回执时创建导入批次,按结果更新任务状态,并同步签名 `reportStatus`。
|
||||
|
||||
### 下一步
|
||||
|
||||
1. 输出阶段 5 实施计划和验收标准。
|
||||
2. 实现账户计费完整扣费/冻结/退费闭环、套餐购买/充值记录和发送前费用预估。
|
||||
|
||||
### 阶段 4 验收状态
|
||||
|
||||
| 验收项 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| Prisma Client 生成成功 | 已完成 | `npm run prisma:generate` 通过。 |
|
||||
| API 构建成功 | 已完成 | `npm run build` 在 `api` 下通过。 |
|
||||
| `ChannelsModule` 被 AppModule 引入 | 已完成 | 已引入根模块。 |
|
||||
| 通道、通道组、路由规则基础接口存在 | 已完成 | 通道 CRUD、测试占位、指标查询、通道组、成员和路由规则接口已实现。 |
|
||||
| 报备字段和签名报备资料接口存在 | 已完成 | 报备字段配置、签名通道报备资料登记接口已实现。 |
|
||||
| 报备任务、导出、导入和记录接口存在 | 已完成 | 任务生成、导出文件、回执导入、报备记录查询接口已实现。 |
|
||||
| 报备状态同步 | 已完成 | 回执导入后更新任务状态并同步签名 `reportStatus`。 |
|
||||
| 阶段完整验证 | 已完成 | `npm run verify:phase4` 通过。 |
|
||||
|
||||
### 阶段 4 结论
|
||||
|
||||
阶段 4 已完成。第一版可以进入阶段 5 账户计费。
|
||||
@@ -0,0 +1,39 @@
|
||||
# 阶段 5 账户计费实施计划
|
||||
|
||||
## 目标
|
||||
|
||||
实现发送前可判断是否可发,发送后可对账的账户计费基础闭环:套餐配置、充值套餐、企业账户、余额或套餐余量、充值记录、账单流水、发送预估费用、冻结、扣费、退费、解冻、短信记录与账务流水关联。
|
||||
|
||||
阶段 5 不实现完整发送链路;发送记录正式关联会在阶段 7 发送链路落地时接入。本阶段先提供 `relatedType`/`relatedId` 关联能力和费用预估/账务动作 API。
|
||||
|
||||
## 实施步骤
|
||||
|
||||
1. Prisma 模型补强
|
||||
- `RechargeOrder`
|
||||
- `SmsBillingRecord`
|
||||
- 扩展账务流水关联字段。
|
||||
|
||||
2. Billing 服务动作
|
||||
- 套餐购买/人工充值。
|
||||
- 发送费用预估。
|
||||
- 账户可用额度检查。
|
||||
- 冻结、扣费、解冻、退费。
|
||||
- 账务流水关联任务、短信记录或人工单据。
|
||||
|
||||
3. API
|
||||
- 客户端充值套餐、充值订单、账单流水、费用预估。
|
||||
- 运营端充值记录、账务流水、套餐配置、计费规则、人工充值和账务调整。
|
||||
|
||||
4. 验证
|
||||
- `cd api && npm run prisma:generate`
|
||||
- `cd api && npm run build`
|
||||
- API health 冒烟
|
||||
- `npm run verify:phase4`
|
||||
|
||||
## 验收标准
|
||||
|
||||
- Prisma Client 生成成功。
|
||||
- API 构建成功。
|
||||
- 套餐、充值记录、账务流水、计费规则 API 存在。
|
||||
- 费用预估、冻结、扣费、解冻、退费 API 存在。
|
||||
- 阶段 5 进度文档记录验证结果。
|
||||
@@ -0,0 +1,75 @@
|
||||
# 阶段 5 账户计费进度记录
|
||||
|
||||
## 2026-07-01
|
||||
|
||||
### 阶段计划
|
||||
|
||||
- 已创建 `docs/phase-5-billing-plan.md`。
|
||||
- 阶段 5 聚焦账户计费闭环,不实现完整发送链路。
|
||||
|
||||
### 验证记录
|
||||
|
||||
- 创建阶段 5 计划文档、扩展 Prisma 充值订单和短信计费记录模型后执行:
|
||||
- `cd api && npm run prisma:generate`:通过。
|
||||
- `cd api && npm run build`:通过。
|
||||
- 实现 Billing 账务动作 API 后执行:
|
||||
- `cd api && npm run prisma:generate`:通过。
|
||||
- `cd api && npm run build`:通过。
|
||||
- API health 冒烟:`GET http://127.0.0.1:3101/api/health` 返回 `{"status":"ok","service":"cmpp-platform-api",...}`。
|
||||
- 阶段 5 完整验证:
|
||||
- `npm run verify:phase5`:通过。
|
||||
- BullMQ 本轮端到端 TPS:543.91,满足 500 条/秒验证线。
|
||||
- Prisma Client 生成成功。
|
||||
- API 构建成功。
|
||||
- 前端构建成功,仍有 Vite chunk 大小告警,不阻塞。
|
||||
|
||||
### 已完成
|
||||
|
||||
- Prisma 账户计费模型补强:
|
||||
- `RechargeOrder`
|
||||
- `SmsBillingRecord`
|
||||
- Billing 账务动作:
|
||||
- 套餐购买/人工充值:创建 `RechargeOrder` 并写入 `AccountTransaction`。
|
||||
- 发送费用预估:按 70/67 字规则计算计费条数、总条数和金额。
|
||||
- 账户校验:检查余额+授信额度和套餐余量。
|
||||
- 冻结:写入 `frozen` 流水。
|
||||
- 扣费:写入 `charged` 流水。
|
||||
- 解冻:写入 `released` 流水。
|
||||
- 退费:写入 `refunded` 流水。
|
||||
- 调整:写入 `adjusted` 流水。
|
||||
- 短信计费记录:创建和查询 `SmsBillingRecord`。
|
||||
- 运营端接口:
|
||||
- `GET/POST /api/admin/billing/recharges`
|
||||
- `POST /api/admin/billing/estimate`
|
||||
- `POST /api/admin/billing/check`
|
||||
- `POST /api/admin/billing/freeze`
|
||||
- `POST /api/admin/billing/charge`
|
||||
- `POST /api/admin/billing/release`
|
||||
- `POST /api/admin/billing/refund`
|
||||
- `POST /api/admin/billing/adjust`
|
||||
- `GET/POST /api/admin/billing/sms-billing-records`
|
||||
- 客户端接口:
|
||||
- `GET/POST /api/client/billing/orders`
|
||||
- `POST /api/client/billing/estimate`
|
||||
|
||||
### 下一步
|
||||
|
||||
1. 输出阶段 6 实施计划和验收标准。
|
||||
2. 实现风控规则、默认阈值、规则命中记录、短信审核、审核原因展示和拒绝原因返回。
|
||||
|
||||
### 阶段 5 验收状态
|
||||
|
||||
| 验收项 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| Prisma Client 生成成功 | 已完成 | `npm run prisma:generate` 通过。 |
|
||||
| API 构建成功 | 已完成 | `npm run build` 在 `api` 下通过。 |
|
||||
| 套餐、充值记录、账务流水、计费规则 API 存在 | 已完成 | 已有套餐、充值订单、账户、流水、规则接口。 |
|
||||
| 费用预估 API 存在 | 已完成 | `POST /api/admin/billing/estimate` 与 `POST /api/client/billing/estimate` 已实现。 |
|
||||
| 账户校验 API 存在 | 已完成 | `POST /api/admin/billing/check` 已实现。 |
|
||||
| 冻结、扣费、解冻、退费 API 存在 | 已完成 | `freeze/charge/release/refund` 已实现。 |
|
||||
| 短信计费记录 API 存在 | 已完成 | `sms-billing-records` 查询和创建已实现。 |
|
||||
| 阶段完整验证 | 已完成 | `npm run verify:phase5` 通过。 |
|
||||
|
||||
### 阶段 5 结论
|
||||
|
||||
阶段 5 已完成。第一版可以进入阶段 6 风控与审核。
|
||||
Reference in New Issue
Block a user