T32 服务端采购任务、租约、幂等与状态机 #34

Closed
opened 2026-08-17 10:00:47 +08:00 by ila · 3 comments
Owner

基本信息

  • 类型:需求 / 服务端 / 状态机 / 并发
  • 所属总体设计:#32
  • 阶段:待验收(#33 已验收;#34 已实施并完成服务端验证)

依赖与并行

  • 前置工单:#33
  • 是否允许并行:共享契约确认后,可与Admin和Android实现并行
  • 原因:所有客户端必须遵循同一采购任务状态机、执行模式、能力门禁和幂等契约

子项目影响

  • 交付单元:server / shared-docs
  • 是否跨子项目:否(共享契约只做同步维护)
  • 验证:Go单元、并发、事务、接口和MySQL集成测试

做什么

  • 实现人工输入的rehearsal采购演练任务和从单条syb_product创建的正式采购任务。
  • 演练任务可指定PDD商品、颜色、尺码、数量、总价上限、设备和规则,且规则权限明确禁止地址修改与创建订单。
  • 正式采购一次只处理一个明确颜色、尺码和数量;校验虾皮到PDD商品及规格映射。
  • 映射缺失、PDD 商品无规格数据(含 pending 状态),或 Agent 定位不到派发时下发的目标规格时,进入服务端 AI 匹配分支;AI 无匹配结果才明确失败。
  • 慢路径采用两趟执行:第一趟采集规格后正常结束并释放设备,服务端离线完成 AI 匹配,第二趟重新派发下单。需要一个「已采集、待重新派发」的普通可派发状态,不引入需要保活的等待态,不延长设备租约等待远程决策。
  • 同一 task_attempt_id 的 AI 匹配结果必须固化,重试不得产生不同答案。
  • 创建、下一任务、领取和开始四个边界均校验Agent的required_capabilities。
  • 实现设备租约与PDD账号级互斥:一台设备和一个PDD账号同一时刻各只能运行一个采购任务。
  • 实现pending、running、rehearsal_completed、order_submit_started、order_created、order_result_unknown、failed、cancelled等服务端状态约束。
  • 以task_id + task_attempt_id幂等接收Agent演练、订单和失败结果。
  • 实现管理员和采购人员“一次性允许重新采购”,创建新任务后自动消耗;保留旧任务和旧订单。
  • 实现人工确认支付、人工选择回填候选及允许后选订单覆盖原回填结果。
  • 地址后缀由任务自增ID确定为_cg{task.id}并进入任务快照。

不做什么

  • 不实现Admin页面、Android页面操作、物流采集、货运宝回填或自动支付。
  • 不对order_submit_started和order_result_unknown自动重新下单。

验收标准

  • 演练规则无法获得地址修改、创建订单和支付能力。
  • 指定设备不满足规则能力时拒绝创建或领取;未指定任务跳过不兼容Agent。
  • 同一设备或同一PDD账号的并发领取只有一个成功。
  • 重复提交相同尝试结果不会产生重复结果或订单记录。
  • 已成功任务默认不能再次创建;一次性授权可创建一条新任务且自动消耗。
  • 订单结果未知必须人工解除,不能进入自动重试。
  • 所有状态变化事务化并保留审计字段,不记录敏感信息。

风险和回退

真实订单属于高风险;本工单只验证服务端状态和接口,不触发真机下单。演练和真实能力必须在服务端强制隔离,不能只依赖Android自觉停止。


2026-08-18 规则修订:本工单的规格匹配相关条款已按 #46 T44 采购规格 AI 匹配与实时规格回传(决策变更) 修订,以上文正文为准。#46 是该决策的唯一事实来源。

## 基本信息 - 类型:需求 / 服务端 / 状态机 / 并发 - 所属总体设计:#32 - 阶段:待验收(#33 已验收;#34 已实施并完成服务端验证) ## 依赖与并行 - 前置工单:#33 - 是否允许并行:共享契约确认后,可与Admin和Android实现并行 - 原因:所有客户端必须遵循同一采购任务状态机、执行模式、能力门禁和幂等契约 ## 子项目影响 - 交付单元:server / shared-docs - 是否跨子项目:否(共享契约只做同步维护) - 验证:Go单元、并发、事务、接口和MySQL集成测试 ## 做什么 - 实现人工输入的`rehearsal`采购演练任务和从单条`syb_product`创建的正式采购任务。 - 演练任务可指定PDD商品、颜色、尺码、数量、总价上限、设备和规则,且规则权限明确禁止地址修改与创建订单。 - 正式采购一次只处理一个明确颜色、尺码和数量;校验虾皮到PDD商品及规格映射。 - 映射缺失、PDD 商品无规格数据(含 `pending` 状态),或 Agent 定位不到派发时下发的目标规格时,进入服务端 AI 匹配分支;AI 无匹配结果才明确失败。 - 慢路径采用两趟执行:第一趟采集规格后正常结束并释放设备,服务端离线完成 AI 匹配,第二趟重新派发下单。需要一个「已采集、待重新派发」的**普通可派发状态**,不引入需要保活的等待态,不延长设备租约等待远程决策。 - 同一 `task_attempt_id` 的 AI 匹配结果必须固化,重试不得产生不同答案。 - 创建、下一任务、领取和开始四个边界均校验Agent的`required_capabilities`。 - 实现设备租约与PDD账号级互斥:一台设备和一个PDD账号同一时刻各只能运行一个采购任务。 - 实现`pending`、`running`、`rehearsal_completed`、`order_submit_started`、`order_created`、`order_result_unknown`、`failed`、`cancelled`等服务端状态约束。 - 以`task_id + task_attempt_id`幂等接收Agent演练、订单和失败结果。 - 实现管理员和采购人员“一次性允许重新采购”,创建新任务后自动消耗;保留旧任务和旧订单。 - 实现人工确认支付、人工选择回填候选及允许后选订单覆盖原回填结果。 - 地址后缀由任务自增ID确定为`_cg{task.id}`并进入任务快照。 ## 不做什么 - 不实现Admin页面、Android页面操作、物流采集、货运宝回填或自动支付。 - 不对`order_submit_started`和`order_result_unknown`自动重新下单。 ## 验收标准 - [x] 演练规则无法获得地址修改、创建订单和支付能力。 - [x] 指定设备不满足规则能力时拒绝创建或领取;未指定任务跳过不兼容Agent。 - [x] 同一设备或同一PDD账号的并发领取只有一个成功。 - [x] 重复提交相同尝试结果不会产生重复结果或订单记录。 - [x] 已成功任务默认不能再次创建;一次性授权可创建一条新任务且自动消耗。 - [x] 订单结果未知必须人工解除,不能进入自动重试。 - [x] 所有状态变化事务化并保留审计字段,不记录敏感信息。 ## 风险和回退 真实订单属于高风险;本工单只验证服务端状态和接口,不触发真机下单。演练和真实能力必须在服务端强制隔离,不能只依赖Android自觉停止。 --- > **2026-08-18 规则修订**:本工单的规格匹配相关条款已按 [#46 T44 采购规格 AI 匹配与实时规格回传(决策变更)](https://git.ilapage.cn/OPC/goauto/issues/46) 修订,以上文正文为准。#46 是该决策的唯一事实来源。
Author
Owner

#33 已验收,#34 前置依赖解除,开始实施。范围严格限定为服务端采购任务创建、能力校验、租约、幂等、状态机与人工处理接口;不实现 Admin 页面、Android 操作、物流回填,不触发真实下单或支付。

#33 已验收,#34 前置依赖解除,开始实施。范围严格限定为服务端采购任务创建、能力校验、租约、幂等、状态机与人工处理接口;不实现 Admin 页面、Android 操作、物流回填,不触发真实下单或支付。
Author
Owner

#34 已实施完成,现停在待验收,未关闭。

实现:

  • 服务端支持 rehearsal 与单条 SYB 正式采购任务创建,事务固化 _cg{taskId}、商品/规格/价格/规则快照。
  • 创建、next、claim、start 四个边界校验能力;设备租约与可选 PDD 账号租约串行,并与采集任务互斥。
  • 支持规格探测两趟执行、同 attempt 决策固化、结果内容哈希幂等、order_submit_started 不可逆门禁、order_result_unknown 人工解除。
  • 支持一次性重新采购授权、人工支付复核、取消和回填候选覆盖;保留旧任务和旧订单。
  • 演练拒绝改地址/创建订单,所有模式禁止支付。

验证:

  • go test ./... 通过。
  • go vet ./app/goauto/purchase ./app/goauto/models ./app/admin/router 通过。
  • scripts/verify.ps1 -Component server 测试与构建通过。
  • dev_scripts/harness.py check --strict 通过。
  • 本地 MySQL 8.4 迁移 1786701200000 成功登记并确认新增字段。

未验证:Admin 页面、Android 动作、真实改地址/创建订单、支付、物流和 SYB 回填均不属于本单;本次没有执行真实下单或支付。

源码提交:65ae41fd6fdd9a0ee31b3c7a3fab1d0fec58db6e
Wiki 归档:Task-34-purchase-task-state-machine(Wiki revision 880afaf1b30ac9567142f0cc94aef645914ff7e3)。

#34 已实施完成,现停在待验收,未关闭。 实现: - 服务端支持 rehearsal 与单条 SYB 正式采购任务创建,事务固化 `_cg{taskId}`、商品/规格/价格/规则快照。 - 创建、next、claim、start 四个边界校验能力;设备租约与可选 PDD 账号租约串行,并与采集任务互斥。 - 支持规格探测两趟执行、同 attempt 决策固化、结果内容哈希幂等、`order_submit_started` 不可逆门禁、`order_result_unknown` 人工解除。 - 支持一次性重新采购授权、人工支付复核、取消和回填候选覆盖;保留旧任务和旧订单。 - 演练拒绝改地址/创建订单,所有模式禁止支付。 验证: - `go test ./...` 通过。 - `go vet ./app/goauto/purchase ./app/goauto/models ./app/admin/router` 通过。 - `scripts/verify.ps1 -Component server` 测试与构建通过。 - `dev_scripts/harness.py check --strict` 通过。 - 本地 MySQL 8.4 迁移 `1786701200000` 成功登记并确认新增字段。 未验证:Admin 页面、Android 动作、真实改地址/创建订单、支付、物流和 SYB 回填均不属于本单;本次没有执行真实下单或支付。 源码提交:`65ae41fd6fdd9a0ee31b3c7a3fab1d0fec58db6e` Wiki 归档:`Task-34-purchase-task-state-machine`(Wiki revision `880afaf1b30ac9567142f0cc94aef645914ff7e3`)。
Author
Owner

用户已于 2026-08-20 明确验收 #34。

  • Wiki 任务归档已更新为“已完成”,并记录用户验收。
  • 核心文档镜像已同步至 Wiki revision e80a0564cf94d2feb3c068d0bf24419d36e21e67。
  • 验收记录提交:dfa425ba5f8d730db49cc4832665bf3231a2c4c6。
  • 本单未执行任何真实下单或支付动作。
用户已于 2026-08-20 明确验收 #34。 - Wiki 任务归档已更新为“已完成”,并记录用户验收。 - 核心文档镜像已同步至 Wiki revision `e80a0564cf94d2feb3c068d0bf24419d36e21e67`。 - 验收记录提交:`dfa425ba5f8d730db49cc4832665bf3231a2c4c6`。 - 本单未执行任何真实下单或支付动作。
ila closed this issue 2026-08-20 17:31:46 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#34