Merge branch 'implement-cmd/saas-server-fiber-v3-queue-push' into HEAD
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# SaaS Server v0.1 本地验收
|
||||
|
||||
## 结论与范围
|
||||
|
||||
已按精简后的 [`../plan-saas-server-v0.1.md`](../plan-saas-server-v0.1.md) 完成 `cmd/saas-server`。使用见 [`../../cmd/saas-server/README.md`](../../cmd/saas-server/README.md)。
|
||||
|
||||
- 配置文件只读,五类配置接口、完整快照内存替换、单条外呼和必要通知、反馈保存/查询可用。
|
||||
- 源 `event_id` 原值保留;队列确认、未知、拒绝和最终结果分开处理,不自动重发。
|
||||
- 反馈可靠保存后 ACK,查询仅本次运行,重启不恢复历史或保存配置修改。
|
||||
- 无独立 CLI、批量、完整任务管理、发送记录持久化、历史索引或新增数据库。
|
||||
- 未修改 Dispatcher/Agent、共享业务代码、合同、现有数据库或部署配置。
|
||||
|
||||
源码提交:`61c1669`(配置服务)和 `d8f9e40`(推送、反馈、操作接口、测试及说明)。后续文档登记不改变业务源码。共享合同固定 `940d9224fd2270791bf2be8d28046f65f7a853f3`,`contracts-update` 校验通过,本次没有合同或子模块指针差异。
|
||||
|
||||
## 实际执行检查
|
||||
|
||||
| 检查 | 结果 |
|
||||
| --- | --- |
|
||||
| `go test -race ./cmd/saas-server` | 通过 |
|
||||
| `go test -cover ./cmd/saas-server` | 通过,新命令包覆盖率 **66.1%** |
|
||||
| `make check` | 最后一次完整执行通过;包括格式、合同/Proto、vet、全量 race、构建及既有隔离 Mock/MQ 检查 |
|
||||
| `make coverage` | 通过,业务单元覆盖率 **73.1%** |
|
||||
| `bash cmd/saas-server/check-integration.sh` | 两项实际隔离集成均通过,没有跳过 |
|
||||
| `make release-check-local` | 本地发布包及合同/队列检查通过,production approved=false;不是部署授权 |
|
||||
| `python3 -m unittest discover -s deploys/production -p 'test_*.py'` | **26** 项通过 |
|
||||
| 单独构建 `cmd/saas-server`,执行 `--help` | 通过 |
|
||||
| `git diff --check`、文档链接及最终变更范围 | 通过 |
|
||||
|
||||
既有 A01–A12/K01–K16 业务范围未改变:仍由现有合同和 Mock 验收门禁检查,新工具不增加旁路或覆盖其业务判断。以上不能代签其中需要真实 SaaS、线路、AI/OSS 或主机的验收项。
|
||||
|
||||
测试采用先失败再实现的方式,配置服务、启动参数、事件处理、确认状态、内存操作与私密诊断都有对应测试。发现的问题修复后重新执行检查,未用旧的成功日志替代最终结果。
|
||||
|
||||
## 新工具的端到端证据
|
||||
|
||||
`TestSaaSServerIsolatedHTTPSMQAgentMTLS`:
|
||||
|
||||
1. 新 Fiber 服务在实际 HTTPS 监听端口提供配置,现有 `configread.Client` 读取。
|
||||
2. 使用专用 vhost 的实际 RabbitMQ,不借用现有 SaaS/MQ。
|
||||
3. 现有 Dispatcher Runtime 接收测试外呼,经真实双向 TLS 调用 Mock Agent。
|
||||
4. Mock Agent 使用合成 PCM 和既有 Mock ASR,经过现有结束/结果反馈链路产生回执与最终结果;没有向反馈队列手工伪造成功消息。
|
||||
5. 两类反馈经 MQ 回到新工具,以带特殊字符的原源 ID `numberID-integration/Original:001` 关联并通过校验,原消息证据实际保存。
|
||||
6. 输入快照测试前后字节一致。
|
||||
|
||||
`TestStartupShutdownPreservesConfiguration`:实际启动与关闭新服务,五类配置中的 SIP 读取可用;退出后全部输入文件字节不变,没有自动产生反馈。
|
||||
|
||||
两项由脚本要求明确 PASS,未配置 broker 时的 SKIP 不算通过。脚本仅创建/移除自己的临时 RabbitMQ 容器,localhost 动态端口、临时存储和随机账号;不自动拉镜像。
|
||||
|
||||
## 关键回归
|
||||
|
||||
- 非法配置更新不部分生效,资源身份不可改变;并发读取/替换通过 race。
|
||||
- 重启重新加载文件,不恢复内存修改或历史在线查询。
|
||||
- 同身份相同请求只发一次,不同内容报错;确认超时/断线保留 unknown,不自动重发。
|
||||
- ACK 前实际写入、同步文件和目录;保存失败不 ACK。
|
||||
- 同源不同消息类型分别保留;重复消息统计,冲突不覆盖首条。
|
||||
- 校验异常明确显示;日志和查询不返回完整原正文或凭据。
|
||||
- 使用现有合同诊断保留字段位置,不输出私密值;移除了重复的结果枚举,合法 `answered` 不再被遗漏。
|
||||
|
||||
集成调试中发现的失败均在测试设置内:JSON map 复用残留任务字段、示例 SIP 缺执行参数、静音 PCM 无语音、反馈目录权限及结果测试数据不匹配。最终改用完整合成测试配置、有语音的合成 PCM 和私有输出目录;没有因此修改现有业务、降低校验或假造执行结果。
|
||||
|
||||
## 未执行与授权边界
|
||||
|
||||
没有合入 main、推送、部署、启动/重启现有业务服务、加载真实线路、拨号、抓包、访问真实 AI/OSS、清队列或删除现存业务数据。检查只覆盖本地隔离测试,不代表真实外呼或生产可用。
|
||||
@@ -0,0 +1,112 @@
|
||||
# SaaS Server v0.1 最小开发计划
|
||||
|
||||
## 1. 目标与边界
|
||||
|
||||
需求及精简范围已确认,最小实现和本地验收已完成。使用见 [`../cmd/saas-server/README.md`](../cmd/saas-server/README.md),检查记录见 [`evidence/saas-server-v0.1-local.md`](evidence/saas-server-v0.1-local.md)。本地通过不代表已部署或真实外呼验收。
|
||||
|
||||
使用 `Fiber/v3` 在 `cmd/saas-server` 实现独立测试服务,通过 HTTP 接口和 `curl` 替代 SaaS 浏览器/CDP 操作:
|
||||
|
||||
**指定文件加载配置 → Dispatcher 按现行接口读取 → 手动推送一条外呼 → 查看并校验反馈。**
|
||||
|
||||
硬性边界:
|
||||
|
||||
- 不修改 Dispatcher/Agent、共享业务代码、业务合同、数据库和现有部署配置;不为测试增加旁路、放宽校验或改变执行规则。
|
||||
- 只调用可直接复用的公共类型/函数,不提取或重构旧 Mock、Dispatcher/Agent 的代码。不能直接复用时,在新命令内补最小 SaaS 侧逻辑,不另造业务规则。
|
||||
- 不直接调用 Agent/Asterisk,不自行选线、判断业务额度、释放占用或编造结果。外呼及配置生效由现行 Dispatcher/Agent 决定。
|
||||
- 只使用明确隔离的测试 MQ vhost,不与现有 SaaS 争抢反馈、不改动现有服务。开发和本地验收不授权部署、真实拨号或 AI/OSS 调用。
|
||||
- 实现时新增源码、测试及说明限于 `cmd/saas-server/`;只允许为 Fiber 更新 `go.mod/go.sum`,并同步必要的项目文档。遇到需要改变现有业务才能接通的问题,停止并单独说明,不能顺手修改。
|
||||
|
||||
唯一业务依据为 [`../contracts/schema/`](../contracts/schema/README.md),不复制 Schema 或拓扑规范。调研/修改合同前遵循 [`contracts.md`](contracts.md);本功能不计划变更合同。
|
||||
|
||||
## 2. 只保留这些功能
|
||||
|
||||
### 2.1 从文件读取配置
|
||||
|
||||
启动形式:
|
||||
|
||||
```sh
|
||||
go run ./cmd/saas-server --config /absolute/path/server.json
|
||||
```
|
||||
|
||||
启动文件指定监听地址、Dispatcher 身份、MQ 连接参数、业务快照位置和独立反馈目录。监听 `0.0.0.0`,端口可配置;相对路径以启动文件目录为基准。
|
||||
|
||||
沿用现有快照组织:`sip.json`、`providers.json`、`quota.json`、`tasks/*.json`。任务列表从已加载任务生成,不再维护第二份列表。所有文件一次性读取并校验,缺失或无效即明确报错,不使用默认业务参数或旧配置兜底。
|
||||
|
||||
- 配置文件只读,不改写、补字段、格式化、监听变化或退出保存;不扫描真实私密配置。
|
||||
- 配置接口提供现行五类资源:SIP、任务详情、任务列表、租户额度和 AI providers;路径、响应及调用标识遵循现行合同。
|
||||
- 使用现有 `internal/contract`、`internal/configread` 可用的类型和校验;AMQP 使用已有依赖。参考 `deploys/test/saas-mock/` 的文件加载与拓扑行为,但不修改该工具。
|
||||
|
||||
### 2.2 仅在内存修改配置
|
||||
|
||||
按资源提交完整快照,校验成功后一次性替换内存;失败保留原值,并保证并发读取不会读到半份配置。任务列表与任务详情保持一致。
|
||||
|
||||
只修改已加载资源,不增删任务,不变更 Dispatcher/租户身份。重启重新读取原文件,临时修改消失。
|
||||
|
||||
修改配置不等于 Dispatcher 已采用:
|
||||
|
||||
- 任务及额度:通过显式 start/resume/edit 指令,按现行规则重新读取;不覆盖 Dispatcher 已有的暂停/停止状态。
|
||||
- SIP:通过显式 `sip.config` 通知触发现行加载流程。
|
||||
- AI providers:Dispatcher 只在启动读取,修改后需要由操作者另行安排重启;本工具不重启任何服务。
|
||||
|
||||
这些接口只发送标准指令,不在工具内另建任务状态机,不改变已发出通话的快照。
|
||||
|
||||
### 2.3 手动发送一条外呼
|
||||
|
||||
输入源 `event_id`、已加载的 `task_id` 和原始 `callee`;其余归属来自配置。按合同构造并校验消息,再向对应测试队列发布,不开放任意路由/原始消息投递。
|
||||
|
||||
- 源 `event_id` 原值保留,不哈希、清洗或在重试时另造 ID。
|
||||
- 本次进程内,相同消息身份重复请求不重复发布;内容不同则拒绝。只在内存记录,不保存发送日志或实现重启恢复。
|
||||
- 使用 persistent、mandatory、publisher confirm;未 return 且确认成功才报告队列已接收。断线或确认超时明确报告结果未知,不自动重发。
|
||||
- 重启后不承诺跨进程请求去重,操作者不能把重启当重试或换 ID 补拨;Dispatcher 原有重复消息处理规则不变。
|
||||
- 启动和退出不自动发指令。不做批量、循环、定时、重拨或换线。
|
||||
|
||||
测试拓扑由本工具在专用 vhost 中按现行规范预建;不 purge、删除队列或重置数据。MQ 故障明确报错并停止相关操作,不实现自动重连重发系统。
|
||||
|
||||
### 2.4 接收、查询和校验反馈
|
||||
|
||||
消费专用测试反馈队列,提供本次进程收到的反馈查询。仅校验合同、源身份、请求归属及反馈实际具备的关联字段,不复制 Dispatcher 的业务判断。
|
||||
|
||||
- 使用 `(dispatcher_id, event_type, event_id)` 区分派发回执、控制回执和最终结果;重复/冲突消息不覆盖原记录,校验失败明确显示原因。
|
||||
- 原消息写入独立反馈目录并确认保存成功后才 ACK;写入失败报错并停止消费,不 ACK、不丢弃。无效消息也保存并标明错误,避免无限重投。
|
||||
- 反馈文件仅用于人工检查,不扫描恢复历史、不建立持久索引。重启后在线查询从空集合开始,原文件保留且不覆盖;历史请求关联不在本次查询范围。
|
||||
- 队列已接收、已派发、被拒绝、最终结果分别展示。等待超时只是尚未收到,不能推断通话失败、接通或 AI 成功;未发起的拒绝不强求通话最终结果。
|
||||
- 反馈目录与配置来源分离,不能覆盖配置文件。日志与查询返回必要摘要,不输出凭据、完整对话、音频、签名 URL 或原始 SIP;原消息仅保存在受控文件。
|
||||
|
||||
## 3. 最小接口
|
||||
|
||||
以下为测试操作接口,不修改 SaaS↔Dispatcher 合同:
|
||||
|
||||
| 接口 | 用途 |
|
||||
| --- | --- |
|
||||
| `PUT /test/config/sip` | 替换内存 SIP 完整快照 |
|
||||
| `PUT /test/config/providers` | 替换内存 AI providers 完整快照 |
|
||||
| `PUT /test/config/quota` | 替换内存额度完整快照 |
|
||||
| `PUT /test/config/tasks/:task_id` | 替换已加载任务完整快照 |
|
||||
| `POST /test/calls` | 手动发送一条外呼 |
|
||||
| `POST /test/task-controls` | 仅发送 start/resume/edit,满足测试启动及配置读取需要 |
|
||||
| `POST /test/sip-refresh` | 显式发送 SIP 配置更新通知 |
|
||||
| `GET /test/events?event_id=...` | 查询本次运行收到的同源反馈和校验结论 |
|
||||
|
||||
源 ID 通过查询参数传递并正确 URL 编码,不改变原值。只提供 `curl` 示例,不开发独立 CLI、页面、实时推送或自动等待脚本。
|
||||
|
||||
## 4. 开发顺序与验证
|
||||
|
||||
单个命令包内按启动、配置、HTTP、MQ/反馈分文件即可,不新增服务层、仓储接口、插件或数据库。新增依赖只需 Fiber/v3;异步处理和内存状态不能引用已被 Fiber 回收的请求缓冲。
|
||||
|
||||
按 TDD 分三步实现:
|
||||
|
||||
1. **配置服务**:只读加载和五类配置接口;用现有配置客户端验证读取,覆盖错误文件、归属和任务列表一致性。
|
||||
2. **外呼与反馈**:单条发布、简单反馈文件、当前运行查询;覆盖 confirm/return、结果未知、重复请求、身份关联、非法反馈及保存失败不 ACK。
|
||||
3. **内存修改与使用说明**:完整快照替换、必要通知及 `curl` 示例;覆盖更新失败不改变当前值、重启恢复原配置、反馈查询不恢复历史。
|
||||
|
||||
完成条件:
|
||||
|
||||
- 用未修改的 Dispatcher/Agent 在隔离 Mock 模式和真实 RabbitMQ 中完成「读取配置 → 推送 → 收到回执/结果」测试,不仅手工伪造反馈。
|
||||
- 测试前后比对所有输入配置文件,启动、修改、失败和退出均不改变文件;并发操作通过 race 检查。
|
||||
- 格式、合同/Proto、`go vet ./...`、`go test -race ./...`、构建及项目既有检查通过,业务单元覆盖率 ≥65%;现有集成检查不因精简而跳过。
|
||||
- 检查最终变更范围:Dispatcher/Agent、共享业务代码、合同和现有部署配置无改动。
|
||||
- 本地检查与真实服务验收分别记录;未部署、未拨号,不声称真实通话已验证。
|
||||
|
||||
## 5. 明确不做
|
||||
|
||||
发送记录持久化、重启恢复、历史在线查询、持久索引、完整任务管理(pause/stop 等)、任务增删、独立 CLI、管理页面、批量/压测、自动重试、配置保存/导出、服务重启、业务代码重构、数据库、多租户/多 Dispatcher、生产部署。
|
||||
Reference in New Issue
Block a user