定义 Admin Gateway 并实现 Mock 契约 #10

Closed
opened 2026-08-06 16:35:15 +08:00 by ila · 5 comments
Owner

基本信息

  • 类型:需求
  • 父级大工单:#1
  • 所属 MVP / 版本:#2 / MVP
  • 阶段:3. Admin Mock/Gateway 闭环
  • 依赖:#8、#9

要解决什么

Admin 尚未完成,Client 需要先有稳定的 Admin 边界和可测试 Mock,供后续任务协调器开发。当前不能让业务代码直接依赖 HTTP 字典,也不能臆造状态查询、租约或心跳接口。

做什么 / 不做什么

  • 做:
    • 定义 Client、Android 设备、领取能力、Admin 任务和提交确认等简单数据对象;
    • 定义 AdminGateway 抽象,只有领取、提交结果、提交失败三个方法;
    • 实现 MockAdminGateway;
    • Mock 支持无任务、采集任务、采购任务和按指定 Client 分配;
    • Mock 支持一次性超时、暂时故障和结果校验失败;
    • Mock 支持相同幂等键同内容返回同一结果、不同内容返回冲突;
    • Mock 支持 Admin 侧已取消任务仍接受结果或失败提交;
    • 使用标准库 unittest 编写契约测试。
  • 不做:
    • 不实现 HTTP Gateway;
    • 不接入 PDD 页面按钮、轮询线程或 Android;
    • 不写 SQLite、Outbox 或任务状态转换;
    • 不增加状态查询、心跳、租约、全局任务池接口;
    • 不保存或打印真实 token;
    • 不新增第三方依赖。

怎么做

  1. 保持 client/src 扁平结构,数据对象使用 dataclass,Gateway 使用 ABC。
  2. claim_next(client, capabilities) 返回一个 AdminTask 或 None。
  3. submit_result(task_id, idempotency_key, result) 与 submit_failure(...) 返回提交确认对象。
  4. Mock 只领取分配给当前 Client 且能力支持的任务,一条任务只能领取一次。
  5. 提交内容用稳定 JSON 指纹比较;重复键和相同内容复用原确认,不生成第二份结果。
  6. 业务错误使用包含稳定 code 和 retryable 的 Gateway 异常。
  7. 未知任务、空幂等键和结构错误明确拒绝;取消状态不作为拒绝理由。
  8. Mock 测试使用固定输入,不依赖网络、Qt 或真实 Admin。

预计修改:

  • client/src/admin_gateway.py
  • client/src/mock_admin_gateway.py
  • client/test/test_admin_gateway_contract.py

验收标准

  • Gateway 只有领取、提交结果、提交失败三个业务方法;
  • 无任务时领取返回 None;
  • 能领取指定 Client 的采集和采购任务;
  • 不领取分配给其他 Client 或能力不支持的任务;
  • 同一任务不会被重复领取;
  • 能模拟超时、暂时故障和校验失败;
  • 相同幂等键及相同内容返回同一确认;
  • 相同幂等键但不同内容返回 IDEMPOTENCY_CONFLICT;
  • 已取消任务的结果和失败提交仍返回接受;
  • 未领取/未派发任务提交被明确拒绝;
  • 不存在状态查询、心跳或租约接口;
  • 全量 unittest、语法检查和 git diff --check 通过。

怎么验证

从 client/ 执行:

C:/Python310/python.exe -m py_compile src/admin_gateway.py src/mock_admin_gateway.py test/test_admin_gateway_contract.py
C:/Python310/python.exe -m unittest discover -s test -p "test_*.py" -v
## 基本信息 - 类型:需求 - 父级大工单:#1 - 所属 MVP / 版本:#2 / MVP - 阶段:3. Admin Mock/Gateway 闭环 - 依赖:#8、#9 ## 要解决什么 Admin 尚未完成,Client 需要先有稳定的 Admin 边界和可测试 Mock,供后续任务协调器开发。当前不能让业务代码直接依赖 HTTP 字典,也不能臆造状态查询、租约或心跳接口。 ## 做什么 / 不做什么 - 做: - 定义 Client、Android 设备、领取能力、Admin 任务和提交确认等简单数据对象; - 定义 `AdminGateway` 抽象,只有领取、提交结果、提交失败三个方法; - 实现 `MockAdminGateway`; - Mock 支持无任务、采集任务、采购任务和按指定 Client 分配; - Mock 支持一次性超时、暂时故障和结果校验失败; - Mock 支持相同幂等键同内容返回同一结果、不同内容返回冲突; - Mock 支持 Admin 侧已取消任务仍接受结果或失败提交; - 使用标准库 `unittest` 编写契约测试。 - 不做: - 不实现 HTTP Gateway; - 不接入 PDD 页面按钮、轮询线程或 Android; - 不写 SQLite、Outbox 或任务状态转换; - 不增加状态查询、心跳、租约、全局任务池接口; - 不保存或打印真实 token; - 不新增第三方依赖。 ## 怎么做 1. 保持 `client/src` 扁平结构,数据对象使用 `dataclass`,Gateway 使用 `ABC`。 2. `claim_next(client, capabilities)` 返回一个 `AdminTask` 或 `None`。 3. `submit_result(task_id, idempotency_key, result)` 与 `submit_failure(...)` 返回提交确认对象。 4. Mock 只领取分配给当前 Client 且能力支持的任务,一条任务只能领取一次。 5. 提交内容用稳定 JSON 指纹比较;重复键和相同内容复用原确认,不生成第二份结果。 6. 业务错误使用包含稳定 `code` 和 `retryable` 的 Gateway 异常。 7. 未知任务、空幂等键和结构错误明确拒绝;取消状态不作为拒绝理由。 8. Mock 测试使用固定输入,不依赖网络、Qt 或真实 Admin。 预计修改: - `client/src/admin_gateway.py` - `client/src/mock_admin_gateway.py` - `client/test/test_admin_gateway_contract.py` ## 验收标准 - [x] Gateway 只有领取、提交结果、提交失败三个业务方法; - [x] 无任务时领取返回 `None`; - [x] 能领取指定 Client 的采集和采购任务; - [x] 不领取分配给其他 Client 或能力不支持的任务; - [x] 同一任务不会被重复领取; - [x] 能模拟超时、暂时故障和校验失败; - [x] 相同幂等键及相同内容返回同一确认; - [x] 相同幂等键但不同内容返回 `IDEMPOTENCY_CONFLICT`; - [x] 已取消任务的结果和失败提交仍返回接受; - [x] 未领取/未派发任务提交被明确拒绝; - [x] 不存在状态查询、心跳或租约接口; - [x] 全量 unittest、语法检查和 `git diff --check` 通过。 ## 怎么验证 从 `client/` 执行: ```powershell C:/Python310/python.exe -m py_compile src/admin_gateway.py src/mock_admin_gateway.py test/test_admin_gateway_contract.py C:/Python310/python.exe -m unittest discover -s test -p "test_*.py" -v ```
Author
Owner

状态:进行中。先实现无网络依赖的 Gateway 边界与 Mock 契约;HTTP、UI 轮询和 SQLite/Outbox 接入后续拆单。

状态:进行中。先实现无网络依赖的 Gateway 边界与 Mock 契约;HTTP、UI 轮询和 SQLite/Outbox 接入后续拆单。
Author
Owner

实施完成,等待用户验收

  • 新增仅包含领取、提交结果、提交失败三个业务方法的 AdminGateway;
  • 新增 Client、Android 设备、领取能力、Admin 任务、提交确认和统一错误对象;
  • Mock 支持指定 Client 派发、任务类型过滤、无任务、一次性超时/暂时故障/校验失败;
  • Mock 支持稳定 JSON 指纹幂等、冲突检测及取消任务仍接受提交;
  • 未接入 HTTP、UI、SQLite、Outbox 或 Android。

验证:全量 33 项 unittest 通过,语法检查和 git diff --check 通过。离屏 Qt 字体目录警告不影响结果。

实现提交:c412e8a。归档提交:11f9d91。本地归档:docs/task/10-定义-admin-gateway-并实现-mock-契约.md。

工单保持打开,等待用户验收。

## 实施完成,等待用户验收 - 新增仅包含领取、提交结果、提交失败三个业务方法的 `AdminGateway`; - 新增 Client、Android 设备、领取能力、Admin 任务、提交确认和统一错误对象; - Mock 支持指定 Client 派发、任务类型过滤、无任务、一次性超时/暂时故障/校验失败; - Mock 支持稳定 JSON 指纹幂等、冲突检测及取消任务仍接受提交; - 未接入 HTTP、UI、SQLite、Outbox 或 Android。 验证:全量 33 项 unittest 通过,语法检查和 `git diff --check` 通过。离屏 Qt 字体目录警告不影响结果。 实现提交:`c412e8a`。归档提交:`11f9d91`。本地归档:`docs/task/10-定义-admin-gateway-并实现-mock-契约.md`。 工单保持打开,等待用户验收。
Author
Owner

需求变更记录:用户提出新增 Admin 心跳接口,用于保存当前设备后登记/更新 Client。该扩展已拆为 #11;待 Admin 接口文档确认后,再更新 Gateway 基线与实现。#10 当前仍等待用户验收。

需求变更记录:用户提出新增 Admin 心跳接口,用于保存当前设备后登记/更新 Client。该扩展已拆为 #11;待 Admin 接口文档确认后,再更新 Gateway 基线与实现。#10 当前仍等待用户验收。
Author
Owner

最终决策:不增加心跳;由 #12 新增无任务副作用的幂等登记接口,后续 #11 会把 AdminGateway 从三个任务方法扩展为“登记 + 三个任务方法”。#10 记录其完成时的三方法基线,扩展由后续工单负责。

最终决策:不增加心跳;由 #12 新增无任务副作用的幂等登记接口,后续 #11 会把 AdminGateway 从三个任务方法扩展为“登记 + 三个任务方法”。#10 记录其完成时的三方法基线,扩展由后续工单负责。
Author
Owner

验收核查(独立实跑,非采信勾选)

在 WSL + Python 3.10 下实际执行:

检查 结果
三个文件齐备 admin_gateway.py 164 行 / mock_admin_gateway.py 319 行 / 契约测试 252 行
语法检查 通过
契约测试 13 个全部 PASS
无第三方依赖 只用标准库(abc / dataclasses / hashlib / json / threading / uuid)
无 Qt 依赖 通过,符合“领域模型不导入 Qt”
无状态查询 / 心跳 / 租约 通过,仅在注释中出现“不得增加”字样
无 token 打印或保存 通过

关键测试与验收标准一一对应,包括三条最容易写错的:

  • test_cancelled_task_still_accepts_result_and_failure
  • test_same_idempotency_key_with_different_content_conflicts
  • test_unclaimed_task_submission_is_rejected

一处与工单正文不符(非缺陷)

工单正文写“AdminGateway 抽象,只有领取、提交结果、提交失败三个方法”,
实际为四个——多了 register_client。

该方法由 #11 / #12 引入的独立登记接口带来,是本工单之后的既定变更;
测试也已同步为 test_gateway_has_only_four_business_methods。

是工单正文过时,不是实现偏差。 据此关闭。

## 验收核查(独立实跑,非采信勾选) 在 WSL + Python 3.10 下实际执行: | 检查 | 结果 | |---|---| | 三个文件齐备 | `admin_gateway.py` 164 行 / `mock_admin_gateway.py` 319 行 / 契约测试 252 行 | | 语法检查 | 通过 | | **契约测试** | **13 个全部 PASS** | | 无第三方依赖 | 只用标准库(abc / dataclasses / hashlib / json / threading / uuid) | | 无 Qt 依赖 | 通过,符合“领域模型不导入 Qt” | | 无状态查询 / 心跳 / 租约 | 通过,仅在注释中出现“不得增加”字样 | | 无 token 打印或保存 | 通过 | 关键测试与验收标准一一对应,包括三条最容易写错的: - `test_cancelled_task_still_accepts_result_and_failure` - `test_same_idempotency_key_with_different_content_conflicts` - `test_unclaimed_task_submission_is_rejected` ## 一处与工单正文不符(非缺陷) 工单正文写“`AdminGateway` 抽象,**只有领取、提交结果、提交失败三个方法**”, 实际为**四个**——多了 `register_client`。 该方法由 #11 / #12 引入的独立登记接口带来,是本工单之后的既定变更; 测试也已同步为 `test_gateway_has_only_four_business_methods`。 **是工单正文过时,不是实现偏差。** 据此关闭。
ila closed this issue 2026-08-07 10:25:26 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chengma/cmautobuy#10