# 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 契约