安全领取并分派 Admin 采购任务 #72

Closed
opened 2026-08-09 23:24:58 +08:00 by ila · 3 comments
Owner

基本信息

  • 类型:需求
  • 父级大工单:#1
  • 所属 MVP / 版本:#2 Client 可运行任务闭环(MVP)
  • 阶段:5. 采购演练与恢复
  • 依赖:#69、#71
  • 状态:待实施

要解决什么

Client 的数据模型认识 purchase,但真实 HTTP 领取请求仍强制只声明 collect,自动获取流程也只分派给 CollectTaskService。在 #71 的采购演练执行器完成前不能放开;完成后需要让 Client 仅在演练能力真实可用时安全领取 Admin 指定的采购任务,并在领取后先可靠保存,再按任务类型分派。

做什么 / 不做什么

做

  • 增加统一任务分派器,按 task_type 把本地任务交给采集或采购应用服务。
  • 只有采购演练执行器、Android 设备和本地持久化准备完成时,HTTP 领取请求才声明支持 purchase。
  • purchase_mode 固定上报 dry_run;真实下单能力不声明、不开放。
  • 领取响应先完整校验采购字段:PDD 链接/商品 ID、动态 options、数量、人民币价格上限。
  • 领取成功后先写入本地 SQLite,再允许执行;保存失败时停止新的领取并明确提示,不能丢失已被 Admin 标记 claimed 的任务。
  • 自动获取保持串行:先补交 Outbox,再处理本地待执行任务,最后才领取新任务。
  • 页面继续使用“获取任务/停止获取”唯一外部命令,显示领取、保存、分派和演练状态。
  • Mock 与 HTTP Gateway 使用同一能力契约,增加真实 Admin 领取采购任务的契约回归。

不做

  • 不实现采购自动化细节(依赖 #71)。
  • 不打开 live,不真实下单、不付款。
  • 不允许“重新执行”入口启动采购任务。
  • 不增加第五个 Admin 接口,不查询 Admin 任务状态。
  • 不改变已领取任务中途不查 Admin 的契约。

已确认的实现方案

  • 移除 HTTP Gateway 中“永远只发 collect”的硬编码,改为序列化调用方经过安全判断后的 ClaimCapabilities。
  • 应用层集中构造能力声明,界面不能自行拼 supported_types。
  • 新增 TaskDispatcher 或等价的直白分派服务;采集与采购保持独立执行器。
  • 对采购领取响应做严格字段校验,校验失败不写本地执行任务,并把协议错误明确报告给操作员。
  • 本地保存与任务执行分离;只有 Repository 提交成功后才进入分派。
  • 保留现有 Outbox 优先和安全停止语义。

预计修改:admin_gateway.py、http_admin_gateway.py、自动获取/事件协调层、任务分派器、Repository/模型必要校验、Mock/HTTP/事件层测试和 Client 文档。

验收标准

  • #71 未就绪或采购能力不可用时,HTTP 请求仍只声明 collect。
  • 条件满足时请求声明 collect,purchase,且 purchase_mode=dry_run。
  • Admin 指定给当前 Client 的采购任务可以被领取并保存到本地。
  • 采购任务字段缺失、数量或价格上限不合法时拒绝进入执行并明确报告契约错误。
  • 任务只有在本地保存成功后才被分派;保存失败不会继续领取下一条。
  • 分派器将采集任务交给采集服务、采购任务交给采购演练服务。
  • 自动获取串行执行,不会同时控制同一 Android 设备。
  • 采购任务仍不能通过“重新执行”入口启动。
  • 不增加 Admin 接口,不打开真实下单,不自动付款。
  • Mock/HTTP 共用契约、全量 unittest、语法检查和离屏 UI 冒烟通过。

怎么验证

从 client/ 执行:

C:/Python310/python.exe -m py_compile src/admin_gateway.py src/http_admin_gateway.py
$env:QT_QPA_PLATFORM="offscreen"
C:/Python310/python.exe -m unittest discover -s test -p "test_admin_gateway_contract.py" -v
C:/Python310/python.exe -m unittest discover -s test -p "test_http_admin_gateway.py" -v
C:/Python310/python.exe -m unittest discover -s test -p "test_*task*.py" -v
C:/Python310/python.exe -m unittest discover -s test -p "test_*.py"
Remove-Item Env:QT_QPA_PLATFORM

联调 Admin:创建并指定一条 purchase 任务,确认 Client 领取后 Admin 为 claimed、本地存在同一稳定任务 ID,且执行模式为演练。不得执行真实下单。

风险和回退

  • 最大风险是“先领取、后发现不能执行”;因此能力声明必须由执行器与持久化准备状态共同决定。
  • Admin 已标记 claimed 后本地保存失败不能静默忽略,必须停止自动获取并提示人工处理。
  • purchase_mode 固定 dry_run,不得读取调试参数改成 live。
  • 可按本工单提交回退到只领取采集任务;已领取采购任务保留本地,不删除。
## 基本信息 - 类型:需求 - 父级大工单:#1 - 所属 MVP / 版本:#2 Client 可运行任务闭环(MVP) - 阶段:5. 采购演练与恢复 - 依赖:#69、#71 - 状态:待实施 ## 要解决什么 Client 的数据模型认识 `purchase`,但真实 HTTP 领取请求仍强制只声明 `collect`,自动获取流程也只分派给 `CollectTaskService`。在 #71 的采购演练执行器完成前不能放开;完成后需要让 Client 仅在演练能力真实可用时安全领取 Admin 指定的采购任务,并在领取后先可靠保存,再按任务类型分派。 ## 做什么 / 不做什么 ### 做 - 增加统一任务分派器,按 `task_type` 把本地任务交给采集或采购应用服务。 - 只有采购演练执行器、Android 设备和本地持久化准备完成时,HTTP 领取请求才声明支持 `purchase`。 - `purchase_mode` 固定上报 `dry_run`;真实下单能力不声明、不开放。 - 领取响应先完整校验采购字段:PDD 链接/商品 ID、动态 options、数量、人民币价格上限。 - 领取成功后先写入本地 SQLite,再允许执行;保存失败时停止新的领取并明确提示,不能丢失已被 Admin 标记 `claimed` 的任务。 - 自动获取保持串行:先补交 Outbox,再处理本地待执行任务,最后才领取新任务。 - 页面继续使用“获取任务/停止获取”唯一外部命令,显示领取、保存、分派和演练状态。 - Mock 与 HTTP Gateway 使用同一能力契约,增加真实 Admin 领取采购任务的契约回归。 ### 不做 - 不实现采购自动化细节(依赖 #71)。 - 不打开 `live`,不真实下单、不付款。 - 不允许“重新执行”入口启动采购任务。 - 不增加第五个 Admin 接口,不查询 Admin 任务状态。 - 不改变已领取任务中途不查 Admin 的契约。 ## 已确认的实现方案 - 移除 HTTP Gateway 中“永远只发 collect”的硬编码,改为序列化调用方经过安全判断后的 `ClaimCapabilities`。 - 应用层集中构造能力声明,界面不能自行拼 `supported_types`。 - 新增 `TaskDispatcher` 或等价的直白分派服务;采集与采购保持独立执行器。 - 对采购领取响应做严格字段校验,校验失败不写本地执行任务,并把协议错误明确报告给操作员。 - 本地保存与任务执行分离;只有 Repository 提交成功后才进入分派。 - 保留现有 Outbox 优先和安全停止语义。 预计修改:`admin_gateway.py`、`http_admin_gateway.py`、自动获取/事件协调层、任务分派器、Repository/模型必要校验、Mock/HTTP/事件层测试和 Client 文档。 ## 验收标准 - [ ] #71 未就绪或采购能力不可用时,HTTP 请求仍只声明 `collect`。 - [ ] 条件满足时请求声明 `collect,purchase`,且 `purchase_mode=dry_run`。 - [ ] Admin 指定给当前 Client 的采购任务可以被领取并保存到本地。 - [ ] 采购任务字段缺失、数量或价格上限不合法时拒绝进入执行并明确报告契约错误。 - [ ] 任务只有在本地保存成功后才被分派;保存失败不会继续领取下一条。 - [ ] 分派器将采集任务交给采集服务、采购任务交给采购演练服务。 - [ ] 自动获取串行执行,不会同时控制同一 Android 设备。 - [ ] 采购任务仍不能通过“重新执行”入口启动。 - [ ] 不增加 Admin 接口,不打开真实下单,不自动付款。 - [ ] Mock/HTTP 共用契约、全量 unittest、语法检查和离屏 UI 冒烟通过。 ## 怎么验证 从 `client/` 执行: ```powershell C:/Python310/python.exe -m py_compile src/admin_gateway.py src/http_admin_gateway.py $env:QT_QPA_PLATFORM="offscreen" C:/Python310/python.exe -m unittest discover -s test -p "test_admin_gateway_contract.py" -v C:/Python310/python.exe -m unittest discover -s test -p "test_http_admin_gateway.py" -v C:/Python310/python.exe -m unittest discover -s test -p "test_*task*.py" -v C:/Python310/python.exe -m unittest discover -s test -p "test_*.py" Remove-Item Env:QT_QPA_PLATFORM ``` 联调 Admin:创建并指定一条 `purchase` 任务,确认 Client 领取后 Admin 为 `claimed`、本地存在同一稳定任务 ID,且执行模式为演练。不得执行真实下单。 ## 风险和回退 - 最大风险是“先领取、后发现不能执行”;因此能力声明必须由执行器与持久化准备状态共同决定。 - Admin 已标记 `claimed` 后本地保存失败不能静默忽略,必须停止自动获取并提示人工处理。 - `purchase_mode` 固定 `dry_run`,不得读取调试参数改成 `live`。 - 可按本工单提交回退到只领取采集任务;已领取采购任务保留本地,不删除。
Author
Owner

实施进度:领取、持久化和按类型分派主链已完成,正在提交和归档。

  • TaskDispatcher 集中构造能力:默认只声明 collect;仅在设备和采购演练 Adapter 都就绪时声明 purchase
  • purchase_mode 固定为 dry_run
  • 采购任务的 goods_id、动态 options、quantity、max_price_cent 会在 HTTP 边界及本地映射处严格校验
  • 顺序固定为:补交 Outbox → 执行本地任务 → 领取新任务 → SQLite 落库 → 按类型分派
  • 本地有待执行采购任务但演练执行器未就绪时停止领取并明确报错
  • Client 全量测试:200 项通过
  • 未验证:真实 Admin/Android/PDD 联调;生产入口目前未注入具体手机采购 Adapter,因此默认应用仍只声明采集能力。
实施进度:领取、持久化和按类型分派主链已完成,正在提交和归档。 - `TaskDispatcher` 集中构造能力:默认只声明 `collect`;仅在设备和采购演练 Adapter 都就绪时声明 `purchase` - `purchase_mode` 固定为 `dry_run` - 采购任务的 goods_id、动态 options、quantity、max_price_cent 会在 HTTP 边界及本地映射处严格校验 - 顺序固定为:补交 Outbox → 执行本地任务 → 领取新任务 → SQLite 落库 → 按类型分派 - 本地有待执行采购任务但演练执行器未就绪时停止领取并明确报错 - Client 全量测试:200 项通过 - 未验证:真实 Admin/Android/PDD 联调;生产入口目前未注入具体手机采购 Adapter,因此默认应用仍只声明采集能力。
Author
Owner

实现与归档已完成,等待用户验收。

  • 实现提交:f201bcc feat: 安全领取并分派采购任务 (#72)
  • 归档提交:d6339a8 docs: 归档任务 #72
  • 归档文档:docs/task/72-安全领取并分派采购任务.md
  • Client 全量测试:200 项通过
  • 未验证边界及默认应用不注入具体手机采购 Adapter 的情况已如实写入归档。
实现与归档已完成,等待用户验收。 - 实现提交:`f201bcc feat: 安全领取并分派采购任务 (#72)` - 归档提交:`d6339a8 docs: 归档任务 #72` - 归档文档:`docs/task/72-安全领取并分派采购任务.md` - Client 全量测试:200 项通过 - 未验证边界及默认应用不注入具体手机采购 Adapter 的情况已如实写入归档。
Author
Owner

用户已于 2026-08-11 明确验收通过。

  • 本地归档状态已更新为“已完成,用户验收通过”
  • 验收记录提交:eca9289
  • 本工单按项目流程关闭
用户已于 2026-08-11 明确验收通过。 - 本地归档状态已更新为“已完成,用户验收通过” - 验收记录提交:`eca9289` - 本工单按项目流程关闭
ila closed this issue 2026-08-11 10:58:12 +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#72