feat(agent): implement #91 controlled recollection

This commit is contained in:
QiuSW
2026-08-26 10:17:45 +08:00
parent 77fdbebc2d
commit 7b6cc00503
11 changed files with 349 additions and 8 deletions
+8 -2
View File
@@ -2,8 +2,8 @@
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
wiki_page: Architecture-and-Code-Map
wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Architecture-and-Code-Map.-
wiki_revision: 3b7a0cad581f615124aeeee8f8d3baf83e1dca28
synchronized_at: 2026-08-26T01:17:16Z
wiki_revision: 9a52b45dc154e741ee2abcd9e74b947fa3745a28
synchronized_at: 2026-08-26T02:11:15Z
<!-- gitea-wiki-mirror:end -->
# 架构与代码地图
@@ -173,3 +173,9 @@ Android Portal/Agent
- `AgentApiClient` 调用服务端当前设备历史接口;任务编号规范化由客户端先处理,服务端再次校验。
- 服务端采集与采购模块各自使用 `agent_history.go` 负责 Device Token 设备隔离、最近 30 天过滤、分页和最小化 DTO。
- `purchase_task.actual_unit_price_cent` 是可空字段,只记录 Agent 实际观察到的采购单价;旧任务不回填。
## Agent 受控重新采集(#91)
- 服务端 `task/lifecycle_service.go` 的同一 Reset 事务同时服务管理端和设备端;设备端入口使用显式 Device Token 模式,不能用空 Token 退化为管理端路径。
- `POST /api/agent/v1/collection-tasks/{taskId}/reset` 只返回最小状态,设备归属、忙碌和商品冲突在事务内检查。
- Android `TaskHistoryFragment` 只在采集终态详情显示“重新采集”,确认成功后调用 `AgentForegroundService.start` 唤醒现有轮询,任务执行仍由 `next/claim/start` 完成。
+10 -2
View File
@@ -2,8 +2,8 @@
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
wiki_page: Business-Rules-and-Glossary
wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Business-Rules-and-Glossary.-
wiki_revision: c956def096806541d5060c771504928d121eb127
synchronized_at: 2026-08-26T01:17:27Z
wiki_revision: e83a27ca331f23a9219fbf4bde9020104192762a
synchronized_at: 2026-08-26T02:11:24Z
<!-- gitea-wiki-mirror:end -->
# 业务规则与术语
@@ -231,3 +231,11 @@ synchronized_at: 2026-08-26T01:17:27Z
- 采集历史可以查看结构化采集结果和错误;采购历史可以查看结构化采购数据和错误,但全部为只读。
- 历史接口遵循数据最小化:不下发 Device Token、规则快照、PDD URL、收货地址、原始控件树或截图。
- 实际采购单价只在 Agent 确实观察到时保存;旧任务或未观察到价格时显示“未记录”,不推算、不回填。
## Agent 受控重新采集
- 当前设备可以从自身采集任务详情重新采集已完成、部分完成或失败任务;采购任务始终只读,不能在 Agent 重新采购。
- 重新采集属于破坏性状态操作,必须先显示确认框并明确提示会清除当前结构化结果和错误;用户取消时不得请求服务端。
- 服务端是最终事实来源:校验 Device Token、设备归属、在线/空闲、任务终态和同商品活动任务冲突,Android 不得本地绕过。
- 重置成功后复用原任务,保留 URL、goods_id、设备与规则快照,清除旧结果后恢复 `pending`;执行仍走正常租约和串行调度。
- 不支持离线排队、跨设备重置、自动换机、重新采购、创建订单或支付。
+19 -2
View File
@@ -2,8 +2,8 @@
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
wiki_page: Android-Agent-API-Contract
wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Android-Agent-API-Contract.-
wiki_revision: 0f83e8f7333f2bec36f7b42f9ab558ec3b1e265e
synchronized_at: 2026-08-26T01:18:14Z
wiki_revision: 7f48742d36b23e7d2c01d83f714812b810bfc34f
synchronized_at: 2026-08-26T02:12:04Z
<!-- gitea-wiki-mirror:end -->
# MVP 共享 API 契约
@@ -550,3 +550,20 @@ GET /api/agent/v1/purchase-tasks/{taskId}
- 采集详情返回标题、店铺、销量、评价数、规格维度、颜色价格、SKU、缺失项和结构化错误。
- 采购详情返回蝦皮订单号、PDD 商品、已匹配颜色/尺码、数量、实际单价、PDD 订单号、下单时间和结构化错误。
- Agent 提交采购结果时可携带 `actualUnitPriceCent`(人民币分,非负)。服务端只保存 Agent 实际观察到的值;历史任务或未观察到价格的结果保持 `null`,客户端显示“未记录”。
## Agent 受控重新采集(#91)
```http
POST /api/agent/v1/collection-tasks/{taskId}/reset
Authorization: Bearer <device-token>
Content-Type: application/json
{"requestId":"<uuid>"}
```
- 只允许任务原关联设备使用自身 Device Token 重置 `completed`、`completed_partial` 或 `failed` 采集任务;跨设备统一返回 `TASK_NOT_FOUND`。
- `requestId` 必须为 UUID。同一请求重复提交不会再次清空结果,响应中的 `replayed` 为 `true`。
- 服务端在事务内锁定设备和任务,重新校验设备在线、同商品无其他 `pending/running` 采集任务,并确认该设备没有正在执行或持有有效租约的其他采集/采购任务。
- 成功后保留 URL、goods_id、设备和规则快照,事务删除旧结构化结果及错误,把原任务恢复为 `pending`;Agent 随后只能通过既有 `next → claim → start` 调度执行。
- 响应只返回 `taskId`、`status` 和可选的 `replayed`,不返回规则快照、URL、Token、控件树或截图。
- 设备离线、任务非终态、设备忙或同商品存在活动任务时返回明确冲突,不支持离线排队。