Files
cmautobuy/docs/task/10-定义-admin-gateway-并实现-mock-契约.md
T
2026-08-06 16:39:00 +08:00

74 lines
3.5 KiB
Markdown

# 10 定义 Admin Gateway 并实现 Mock 契约
- 类型:需求
- 父级大工单:#1
- 所属 MVP / 版本:#2 / MVP
- 状态:已实现,待验收
- 日期:2026-08-06
- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/10
## 背景与目标
Admin 尚未完成,Client 需要先有稳定、可测试的 Admin 边界。本任务定义三个允许的业务调用,并提供不访问网络的 Mock,让后续任务协调器可以先完成开发和测试。
## 最终方案
- `AdminGateway` 只定义领取任务、提交成功结果、提交失败结果三个抽象方法。
- 使用简单数据类表达 Client、Android 设备、领取能力、Admin 任务和提交确认。
- `AdminGatewayError` 提供稳定错误代码、是否可重试、请求编号和错误详情。
- `MockAdminGateway` 按指定 Client 派发任务,并按 Client 声明的任务类型能力过滤。
- 一条任务只能领取一次;无可领取任务时返回 `None`。
- Mock 可让下一次调用模拟超时或暂时故障,也可让下一次提交模拟结果校验失败。
- 提交使用稳定 JSON 指纹实现幂等:同键同内容复用确认,同键不同内容返回 `IDEMPOTENCY_CONFLICT`。
- 未领取任务不能提交;已经领取后即使 Admin 侧取消,结果和失败报告仍会接受。
- 没有增加状态查询、心跳、租约、HTTP、SQLite 或 UI 行为。
## 改了哪些
- `client/src/admin_gateway.py`:新增 Gateway 抽象、请求相关数据对象、提交确认和统一异常。
- `client/src/mock_admin_gateway.py`:新增任务队列、能力过滤、故障模拟、提交校验和幂等处理。
- `client/test/test_admin_gateway_contract.py`:新增三个方法边界、领取、故障、幂等、取消后提交和校验测试。
## 验收结果
| 验收标准 | 结果 |
|---|---|
| Gateway 只有三个业务方法 | 通过 |
| 无任务时返回 `None` | 通过 |
| 能领取指定 Client 的采集和采购任务 | 通过 |
| 能过滤其他 Client 和不支持类型 | 通过 |
| 同一任务不会重复领取 | 通过 |
| 能模拟超时、暂时故障和校验失败 | 通过 |
| 同一幂等键和内容复用确认 | 通过 |
| 同键不同内容返回幂等冲突 | 通过 |
| 已取消任务仍接受结果和失败提交 | 通过 |
| 未领取任务提交被拒绝 | 通过 |
| 不存在状态查询、心跳或租约接口 | 通过 |
| 全量测试、语法和差异检查通过 | 通过 |
## 测试
- 执行的命令:
```powershell
C:/Python310/python.exe -m py_compile src/admin_gateway.py src/mock_admin_gateway.py test/test_admin_gateway_contract.py
$env:QT_QPA_PLATFORM="offscreen"
C:/Python310/python.exe -m unittest discover -s test -p "test_*.py" -v
Remove-Item Env:QT_QPA_PLATFORM
git diff --check
```
- 结果:新增契约测试与已有测试合计 33 项全部通过,输出 `Ran 33 tests ... OK`;语法检查和差异检查通过。
- 环境提示:离屏 Qt 继续输出本机 PyQt5 字体目录缺失警告,不影响测试结果。
- **没验证到的部分**:没有连接真实 Admin,没有进行 HTTP 契约测试,没有接入 Qt 后台线程、领取循环、SQLite 或 Outbox,也没有操作 Android 设备。
## 遗留问题
- 下一阶段应把 Admin 任务对象转换为 `NewClaimedTask`,并与 SQLite 写入组成领取闭环。
- HTTP Gateway 等 Admin 接口稳定后再按独立工单实现,并复用同一套契约测试。
- Outbox 可靠提交、退避和崩溃恢复需要后续独立工单。
## 相关提交
- `c412e8a` 定义 Admin Gateway 并实现 Mock 契约