feat(server): 图搜采集任务下发与身份回填 #278

Open
opened 2026-09-14 10:17:48 +08:00 by ila · 5 comments
Owner

所属 MVP:#275 | 来源:用户 2026-09-14 需求讨论(原话摘要见 #275)

目标

服务端支持创建、下发图搜类采集任务,并在 Agent 识别出商品后回填身份;对明显不合理的候选做价格兜底。

当前事实

  • models.CollectionTask.Source 的 check 约束现为 source IN ('admin','agent_current_page')。
  • task/current_page.go 的 IdentifyCurrentPage 已经实现"任务先建、PDDProductID 为 nil、Agent 回传分享链接后再回填身份并落 pdd_product"的完整路径。图搜可直接复用这一形态,无需新建任务表或新增任务类型。
  • models.SYBProduct.ImageURL 已存在(type:text;not null),是图片来源。

前置依赖

无。但契约需先定下来供 #277 使用,因此建议与 #276 并行最先启动。

方案

  1. collection_task.source 增加取值 image_search。check 约束变更属于数据库迁移,需新增 version-local 迁移文件;实施前必须人工确认。
  2. 任务创建:接收 shopee 商品维度的图搜请求,快照图片 URL 与校验信息。
  3. 任务下发:向 Agent 下发图片元数据(url / sizeBytes / sha256 / mediaType),由 Agent 自行下载并校验,服务端不下发图片字节。
  4. 身份回填:复用现有 IdentifyCurrentPage 形态,允许 image_search 来源调用。
  5. 价格兜底:候选商品价格与 syb_product.unit_price_cent 偏离超过可配阈值(建议默认 3 倍)时不建立关联,任务明确失败并记录错误码。此项只挡最离谱的错配,不构成"服务端判断商品是否正确"。
  6. 更新 docs/08-agent-api-contract.md。

设计证据

后端与接口改动,不强制 UI 原型。需先确认 API、数据与状态设计。

验收

  • 迁移在已有数据库上正确执行,既有 admin / agent_current_page 任务不受影响。
  • 图搜任务可创建、可被 Agent 领取、可回填身份。
  • 价格偏离超阈值时任务明确失败,错误码可读。
  • 阈值可配置。
  • 契约文档与实现一致。

验证

Go 单元测试 + .\scripts erify.ps1 -Component server。

风险

数据库迁移(check 约束变更)属高风险不可逆操作,实施前必须再次人工确认。

文档影响

必须更新 docs/08-agent-api-contract.md;数据结构与状态变化需同步架构与业务规则 Wiki 页面。

> 所属 MVP:#275 | 来源:用户 2026-09-14 需求讨论(原话摘要见 #275) ## 目标 服务端支持创建、下发图搜类采集任务,并在 Agent 识别出商品后回填身份;对明显不合理的候选做价格兜底。 ## 当前事实 - `models.CollectionTask.Source` 的 check 约束现为 `source IN ('admin','agent_current_page')`。 - `task/current_page.go` 的 `IdentifyCurrentPage` 已经实现"任务先建、`PDDProductID` 为 nil、Agent 回传分享链接后再回填身份并落 `pdd_product`"的完整路径。图搜可直接复用这一形态,**无需新建任务表或新增任务类型**。 - `models.SYBProduct.ImageURL` 已存在(`type:text;not null`),是图片来源。 ## 前置依赖 无。但契约需先定下来供 #277 使用,因此建议与 #276 并行最先启动。 ## 方案 1. `collection_task.source` 增加取值 `image_search`。**check 约束变更属于数据库迁移,需新增 version-local 迁移文件;实施前必须人工确认。** 2. 任务创建:接收 shopee 商品维度的图搜请求,快照图片 URL 与校验信息。 3. 任务下发:向 Agent 下发图片元数据(url / sizeBytes / sha256 / mediaType),由 Agent 自行下载并校验,服务端不下发图片字节。 4. 身份回填:复用现有 `IdentifyCurrentPage` 形态,允许 `image_search` 来源调用。 5. **价格兜底**:候选商品价格与 `syb_product.unit_price_cent` 偏离超过可配阈值(建议默认 3 倍)时**不建立关联**,任务明确失败并记录错误码。此项只挡最离谱的错配,不构成"服务端判断商品是否正确"。 6. 更新 `docs/08-agent-api-contract.md`。 ## 设计证据 后端与接口改动,不强制 UI 原型。需先确认 API、数据与状态设计。 ## 验收 - [ ] 迁移在已有数据库上正确执行,既有 `admin` / `agent_current_page` 任务不受影响。 - [ ] 图搜任务可创建、可被 Agent 领取、可回填身份。 - [ ] 价格偏离超阈值时任务明确失败,错误码可读。 - [ ] 阈值可配置。 - [ ] 契约文档与实现一致。 ## 验证 Go 单元测试 + `.\scripts erify.ps1 -Component server`。 ## 风险 **数据库迁移(check 约束变更)属高风险不可逆操作,实施前必须再次人工确认。** ## 文档影响 必须更新 `docs/08-agent-api-contract.md`;数据结构与状态变化需同步架构与业务规则 Wiki 页面。
Author
Owner

API 契约补充 v1(目标契约,不代表已实现)

来源:用户要求“在 #278 补定这组 API 契约,再继续 #277”。本轮仅本地实施和测试,不发布线上;#276 权限改动、#278/#279 本地迁移已获用户授权。

1. 批量创建

POST /api/admin/v1/collection-tasks/image-search/batch

{"requestId":"UUID","sybProductIds":[123,456],"ruleId":1,"deviceId":null,"overwriteLinked":false}
  • 输入为 SYB 明细 ID,原始条目上限 100;服务端按当前关联的 shopeeProductId 去重,一个蝦皮商品产生一个采集任务。
  • ruleId 必填,沿用现有采集规则快照;deviceId 可空,但只能由支持图搜能力的新 Agent 领取。
  • 默认跳过已关联 PDD 的商品;保留 #280 的显式覆盖能力(overwriteLinked=true),不能把上一版“仅未关联”摘要理解成取消覆盖需求。
  • 按输入顺序取首个有效参考图明细作为该组代表,冻结其图片和参考价依据。批量结果每个蝦皮商品一项,含 shopeeProductId、该组 sybProductIds、success、taskId、replayed 或 code/message;总计使用 successCount/failureCount/skippedCount。
  • 同一批次 UUID + 蝦皮商品 ID 派生稳定任务请求 ID;同一商品已有未结束图搜任务时复用/拒绝重复,不另建并发任务。

2. 图片与任务快照

  • 新增独立、可空的 collection_task.image_search_snapshot JSON,不复用 urlSnapshot 存图片 URL,不新增任务表。
  • 保存关联目标、原 PDD 关联、代表 SYB 明细、图片 URL/字节数/SHA-256/媒体类型、参考价依据和阈值快照。
  • 图片校验信息由服务端在创建阶段实际读取参考图后计算,不接受 Web 自报的摘要;有界下载、验证格式/大小后冻结元数据,不保存私人相册数据。下载失败则该项不创建任务。
  • 未识别商品时 pddProductId=null,urlSnapshot/goodsIdSnapshot 为空;图片信息独立保存。

3. Agent 下发

继续复用 next/claim/start,source=image_search 时新增:

{"imageSearch":{"imageUrl":"https://example.invalid/reference.jpg","mediaType":"image/jpeg","sizeBytes":12345,"sha256":"64位小写十六进制"}}
  • 普通任务省略 imageSearch;Agent 在解析任务时验证元数据,下载校验成功后才写入 MediaStore。
  • 不在下发 JSON 中传图片字节;转换 JPEG/放大属于设备准备步骤,必须先验证下载原始文件。
  • 旧 Agent 不得领取图搜任务;图搜排在普通采集后,采购优先级不变。优先执行指任务间调度,不抢占正在运行的任务或绕过租约。

4. 身份回填与重采

复用 POST /api/agent/v1/current-page-collection-tasks/:taskId/identify,请求仍为 requestId/shareUrl,响应保持现有身份结构。

  • 只对合法图搜来源扩展允许范围,设备归属、运行状态、租约、幂等和同商品活动任务限制不放宽。
  • 回填只绑定采集任务的 PDD 身份,不立即覆盖蝦皮商品关联。
  • 已识别任务重新采集时重采原商品,不再次图搜;未识别即失败的图搜任务不得声称能“重采同商品”,需显示明确原因,重新图搜仍不在本版范围。

5. 成功后关联边界

  • 采集结果通过规格完整性和价格兜底后,才在 #279 写关联及图搜标记;价格缺失或不可比较时不能默默绕过兜底。
  • 保留工单的可配置价格阈值(默认建议 3 倍)。实现时先核对现有参考价单位/币种,不能把跨币种整数直接相除。
  • 关联写入前核对任务冻结的原关联;采购员执行中手动修改过关联时不得覆盖其操作。
  • 不触发额外 AI 匹配,不创建采购任务/订单,不支付;#279 只展示来源标记。

实现状态与文档

现有提交只包含来源常量/CHECK 迁移骨架,尚无完整创建、图片下发、身份扩展与价格兜底实现,#278 仍未完成;不得据此宣称 #277 的依赖已满足。下一步先完成这些 Server 能力和契约测试,再接 #277。共享正式契约需按 Wiki-first 更新 Android-Agent-API-Contract、架构和业务规则镜像,不能以本评论替代永久 API 契约。

本会话无可用 Gitea MCP,采用 Gitea API 回退;先前 DNS 失败已恢复,本次读取工单与评论均返回 HTTP 200。

## API 契约补充 v1(目标契约,不代表已实现) 来源:用户要求“在 #278 补定这组 API 契约,再继续 #277”。本轮仅本地实施和测试,不发布线上;#276 权限改动、#278/#279 本地迁移已获用户授权。 ### 1. 批量创建 `POST /api/admin/v1/collection-tasks/image-search/batch` ```json {"requestId":"UUID","sybProductIds":[123,456],"ruleId":1,"deviceId":null,"overwriteLinked":false} ``` - 输入为 SYB 明细 ID,原始条目上限 100;服务端按当前关联的 `shopeeProductId` 去重,一个蝦皮商品产生一个采集任务。 - `ruleId` 必填,沿用现有采集规则快照;`deviceId` 可空,但只能由支持图搜能力的新 Agent 领取。 - 默认跳过已关联 PDD 的商品;保留 #280 的显式覆盖能力(`overwriteLinked=true`),不能把上一版“仅未关联”摘要理解成取消覆盖需求。 - 按输入顺序取首个有效参考图明细作为该组代表,冻结其图片和参考价依据。批量结果每个蝦皮商品一项,含 `shopeeProductId`、该组 `sybProductIds`、`success`、`taskId`、`replayed` 或 `code/message`;总计使用 `successCount/failureCount/skippedCount`。 - 同一批次 UUID + 蝦皮商品 ID 派生稳定任务请求 ID;同一商品已有未结束图搜任务时复用/拒绝重复,不另建并发任务。 ### 2. 图片与任务快照 - 新增独立、可空的 `collection_task.image_search_snapshot` JSON,不复用 `urlSnapshot` 存图片 URL,不新增任务表。 - 保存关联目标、原 PDD 关联、代表 SYB 明细、图片 URL/字节数/SHA-256/媒体类型、参考价依据和阈值快照。 - 图片校验信息由服务端在创建阶段实际读取参考图后计算,不接受 Web 自报的摘要;有界下载、验证格式/大小后冻结元数据,不保存私人相册数据。下载失败则该项不创建任务。 - 未识别商品时 `pddProductId=null`,`urlSnapshot/goodsIdSnapshot` 为空;图片信息独立保存。 ### 3. Agent 下发 继续复用 next/claim/start,`source=image_search` 时新增: ```json {"imageSearch":{"imageUrl":"https://example.invalid/reference.jpg","mediaType":"image/jpeg","sizeBytes":12345,"sha256":"64位小写十六进制"}} ``` - 普通任务省略 `imageSearch`;Agent 在解析任务时验证元数据,下载校验成功后才写入 MediaStore。 - 不在下发 JSON 中传图片字节;转换 JPEG/放大属于设备准备步骤,必须先验证下载原始文件。 - 旧 Agent 不得领取图搜任务;图搜排在普通采集后,采购优先级不变。优先执行指任务间调度,不抢占正在运行的任务或绕过租约。 ### 4. 身份回填与重采 复用 `POST /api/agent/v1/current-page-collection-tasks/:taskId/identify`,请求仍为 `requestId/shareUrl`,响应保持现有身份结构。 - 只对合法图搜来源扩展允许范围,设备归属、运行状态、租约、幂等和同商品活动任务限制不放宽。 - 回填只绑定采集任务的 PDD 身份,不立即覆盖蝦皮商品关联。 - 已识别任务重新采集时重采原商品,不再次图搜;未识别即失败的图搜任务不得声称能“重采同商品”,需显示明确原因,重新图搜仍不在本版范围。 ### 5. 成功后关联边界 - 采集结果通过规格完整性和价格兜底后,才在 #279 写关联及图搜标记;价格缺失或不可比较时不能默默绕过兜底。 - 保留工单的可配置价格阈值(默认建议 3 倍)。实现时先核对现有参考价单位/币种,不能把跨币种整数直接相除。 - 关联写入前核对任务冻结的原关联;采购员执行中手动修改过关联时不得覆盖其操作。 - 不触发额外 AI 匹配,不创建采购任务/订单,不支付;#279 只展示来源标记。 ### 实现状态与文档 现有提交只包含来源常量/CHECK 迁移骨架,尚无完整创建、图片下发、身份扩展与价格兜底实现,#278 仍未完成;不得据此宣称 #277 的依赖已满足。下一步先完成这些 Server 能力和契约测试,再接 #277。共享正式契约需按 Wiki-first 更新 Android-Agent-API-Contract、架构和业务规则镜像,不能以本评论替代永久 API 契约。 本会话无可用 Gitea MCP,采用 Gitea API 回退;先前 DNS 失败已恢复,本次读取工单与评论均返回 HTTP 200。
Author
Owner

实施开始记录(本地)

已确认继续实施 #278。当前先处理服务端基础契约:保留 image_search 来源约束,收窄迁移为目标字段的幂等变更,随后补充批量创建、图片元数据快照、Agent 能力校验、识别接口扩展、价格保护及契约测试。#277 暂不并行接入,待 #278 服务端契约和测试通过后继续。

本轮不发布线上;MCP 连接器不可用,使用 REST API 回退。

## 实施开始记录(本地) 已确认继续实施 #278。当前先处理服务端基础契约:保留 `image_search` 来源约束,收窄迁移为目标字段的幂等变更,随后补充批量创建、图片元数据快照、Agent 能力校验、识别接口扩展、价格保护及契约测试。#277 暂不并行接入,待 #278 服务端契约和测试通过后继续。 本轮不发布线上;MCP 连接器不可用,使用 REST API 回退。
Author
Owner

本地实施进展(待验收)

已完成:

  • 新增 POST /api/admin/v1/collection-tasks/image-search/batch,按 SYB 明细按 shopeeProductId 去重,支持 overwriteLinked、批次稳定 requestId、单商品活动任务防重。
  • 代表参考图有界下载(10 MiB)、JPEG/PNG 格式校验、SHA-256/字节数/媒体类型快照;未识别任务保持 PDD 身份为空。
  • source=image_search 任务下发图片元数据,服务端不会把图片字节放入载荷。
  • Agent 能力要求 pdd.image-search.v1;旧设备不能领取;图搜识别接口允许复用现有 current-page identify 的租约/归属/幂等保护。
  • 路由和采购员权限矩阵已补齐。

提交:7b540f3、42b5312。验证:go test -p 1 ./app/goauto/task ./app/goauto/clientapi ./app/goauto/access 通过。

SYB 默认币种按 TWD 处理;PDD 价格为人民币,尚未把跨币种金额直接比较,价格保护将在币种策略明确后完成。当前仅本地代码,未执行数据库迁移、未发布线上。

## 本地实施进展(待验收) 已完成: - 新增 `POST /api/admin/v1/collection-tasks/image-search/batch`,按 SYB 明细按 `shopeeProductId` 去重,支持 `overwriteLinked`、批次稳定 requestId、单商品活动任务防重。 - 代表参考图有界下载(10 MiB)、JPEG/PNG 格式校验、SHA-256/字节数/媒体类型快照;未识别任务保持 PDD 身份为空。 - `source=image_search` 任务下发图片元数据,服务端不会把图片字节放入载荷。 - Agent 能力要求 `pdd.image-search.v1`;旧设备不能领取;图搜识别接口允许复用现有 current-page identify 的租约/归属/幂等保护。 - 路由和采购员权限矩阵已补齐。 提交:`7b540f3`、`42b5312`。验证:`go test -p 1 ./app/goauto/task ./app/goauto/clientapi ./app/goauto/access` 通过。 SYB 默认币种按 TWD 处理;PDD 价格为人民币,尚未把跨币种金额直接比较,价格保护将在币种策略明确后完成。当前仅本地代码,未执行数据库迁移、未发布线上。
Author
Owner

核对范围与方法(2026-09-15)

  • 被核对分支:release/283 @ c80d0c9;基线 main @ c14f5f5。
  • 该分支是打包分支,同时含 #272 #273 #274 #276 #278 #279 #280 #282 #283,本次只就 #275~#280 的验收项作结论。
  • 执行内容:go build ./...、go test ./...(server)、npm run build:prod(web)、逐条对照工单验收项读取 diff。
  • 未执行:真机验证、Android 构建与单测(见 #277 结论,Android 侧无可验证的实现)。

结论:实现达标,文档未完成

已完成

  • 1789400000000_image_search_collection.go:MySQL 下先 DROP CHECK ck_collection_task_source 再 ADD CONSTRAINT 重建为三值枚举,并新增 ImageSearchSnapshot 列。处理方式稳妥。
  • task/image_search.go(373 行):参考图元数据 mediaType / sizeBytes / sha256 齐全,下载后校验哈希与大小,imageSearchMaxBytes = 10MB 上限。
  • 价格兜底已实现,并额外处理了跨币种:虾皮商品币种非 CNY 时记 PriceGuardSkipped + CROSS_CURRENCY_TWD_PDD_CNY,不自动关联而保留人工复核。此项超出工单要求,属合理补强,予以认可。
  • go build ./... 通过;app/goauto/task 包测试通过。

未完成

  • docs/08-agent-api-contract.md 未更新。 git diff --stat main..release/283 -- docs/ 返回空,整个 docs/ 零改动。

本工单「文档影响」写明"必须更新",且按仓库规则该文件是共享 API 的唯一事实来源。新增的图搜任务下发载荷(参考图元数据字段、image_search 来源、身份回填路径)目前只存在于代码中。

补齐该文档后本工单即可进入待验收。

## 核对范围与方法(2026-09-15) - 被核对分支:`release/283` @ `c80d0c9`;基线 `main` @ `c14f5f5`。 - 该分支是打包分支,同时含 #272 #273 #274 #276 #278 #279 #280 #282 #283,本次只就 #275~#280 的验收项作结论。 - 执行内容:`go build ./...`、`go test ./...`(server)、`npm run build:prod`(web)、逐条对照工单验收项读取 diff。 - **未执行**:真机验证、Android 构建与单测(见 #277 结论,Android 侧无可验证的实现)。 ## 结论:实现达标,文档未完成 ### 已完成 - `1789400000000_image_search_collection.go`:MySQL 下先 `DROP CHECK ck_collection_task_source` 再 `ADD CONSTRAINT` 重建为三值枚举,并新增 `ImageSearchSnapshot` 列。处理方式稳妥。 - `task/image_search.go`(373 行):参考图元数据 `mediaType / sizeBytes / sha256` 齐全,下载后校验哈希与大小,`imageSearchMaxBytes = 10MB` 上限。 - 价格兜底已实现,并额外处理了跨币种:虾皮商品币种非 CNY 时记 `PriceGuardSkipped` + `CROSS_CURRENCY_TWD_PDD_CNY`,不自动关联而保留人工复核。**此项超出工单要求,属合理补强,予以认可。** - `go build ./...` 通过;`app/goauto/task` 包测试通过。 ### 未完成 - [ ] **`docs/08-agent-api-contract.md` 未更新。** `git diff --stat main..release/283 -- docs/` 返回空,整个 `docs/` 零改动。 本工单「文档影响」写明"必须更新",且按仓库规则该文件是共享 API 的唯一事实来源。新增的图搜任务下发载荷(参考图元数据字段、`image_search` 来源、身份回填路径)目前只存在于代码中。 补齐该文档后本工单即可进入待验收。
Author
Owner

上线信息(共用)

  • 合并提交:1d01186,已推送 be03972..1d01186 到 main。
  • 发布目录:/home/goauto/releases/20260915-1d01186,二进制 SHA-256 前缀 65e404c4721d592a(本地与服务器一致)。
  • systemctl is-active goauto.service = active,监听 127.0.0.1:8010。
  • 数据库迁移:新执行 2 个,跳过 45 个已应用。迁移前已做全库逻辑备份(66 张表,gzip 校验通过),路径在运维备份目录,不在此列出。
  • 迁移前后 collection_task 222 行、shopee_product 26901 行,逐一相符。

外部入口验证:

检查 结果
GET / HTTP 200
GET /api/admin/v1/collection-tasks {"code":401,"msg":"cookie token is empty"}
POST /api/admin/v1/collection-tasks/image-search/batch {"code":401,...}
不存在路由对照 HTTP 404

最后两行是关键对照:图搜接口返回 401 而非 404,证明新路由已注册。

回退方式:把 current 软链切回 20260914-be03972-r2 后重启。两条迁移均为加列与放宽约束,不阻碍回退到旧二进制。

实施

提交:baa9408、35b69fc、66ab36c、ffa5fc0、7b540f3、42b5312、45437a9、cda1978、12e9aa8。

  • 迁移 1789400000000_image_search_collection:MySQL 下 DROP CHECK ck_collection_task_source 后重建为三值枚举,并新增 image_search_snapshot 列。
  • task/image_search.go:参考图 mediaType / sizeBytes / sha256 校验与下载,10MB 上限。
  • 价格兜底,并额外处理跨币种:蝦皮商品币种非 CNY 时记 PriceGuardSkipped + CROSS_CURRENCY_TWD_PDD_CNY,不自动关联而保留人工复核。
  • IdentifyCurrentPage 放行 image_search 来源。

线上迁移核对

sys_migration: 1789400000000, 1789400100000 均已写入
ck_collection_task_source -> in ('admin','agent_current_page','image_search')
collection_task.image_search_snapshot 已存在
shopee_product.image_search_linked 已存在

上一轮评论提出的文档缺口已补

docs/08-agent-api-contract.md 新增「SYB 商品 PDD 图搜采集(#275~#280)」章节共 160 行。按 Wiki-first 流程执行:先更新线上页面 Android-Agent-API-Contract 并在线回读,revision 4d1ba4423229;再运行一次 harness.py sync 与一次 sync --check(均通过),提交由 sync 生成的本地镜像。

文档中另记录了一条已核对事实:IdentifyCurrentPage 要求任务已绑定 device_id,而批量创建允许 deviceId 为空——Claim 在事务中写入 device_id,因此 Agent 调用 identify 时设备必定已绑定。这一条曾是实施中标注的最高风险假设,现已由代码核对确认成立。

验证

go build ./...、go test ./app/goauto/task/... 通过;线上迁移与约束已核对。

状态

服务端实现与文档均已完成并上线,保持待验收。

关于 sybimport 的 12 个失败用例

app/goauto/sybimport 有 12 个失败用例,先于本工单存在,来自 #272/#274 改变契约后未更新的旧断言,已单独记录为 #285。本次上线前后逐条比对失败集合完全一致,未新增。这批用例对应的代码自 be03972(2026-09-14)起已在线上运行。

## 上线信息(共用) - 合并提交:`1d01186`,已推送 `be03972..1d01186` 到 `main`。 - 发布目录:`/home/goauto/releases/20260915-1d01186`,二进制 SHA-256 前缀 `65e404c4721d592a`(本地与服务器一致)。 - `systemctl is-active goauto.service` = `active`,监听 `127.0.0.1:8010`。 - 数据库迁移:新执行 2 个,跳过 45 个已应用。迁移前已做全库逻辑备份(66 张表,gzip 校验通过),路径在运维备份目录,不在此列出。 - 迁移前后 `collection_task` 222 行、`shopee_product` 26901 行,逐一相符。 外部入口验证: | 检查 | 结果 | |---|---| | `GET /` | HTTP 200 | | `GET /api/admin/v1/collection-tasks` | `{"code":401,"msg":"cookie token is empty"}` | | `POST /api/admin/v1/collection-tasks/image-search/batch` | `{"code":401,...}` | | 不存在路由对照 | HTTP 404 | 最后两行是关键对照:图搜接口返回 401 而非 404,证明新路由已注册。 回退方式:把 `current` 软链切回 `20260914-be03972-r2` 后重启。两条迁移均为加列与放宽约束,不阻碍回退到旧二进制。 ## 实施 提交:`baa9408`、`35b69fc`、`66ab36c`、`ffa5fc0`、`7b540f3`、`42b5312`、`45437a9`、`cda1978`、`12e9aa8`。 - 迁移 `1789400000000_image_search_collection`:MySQL 下 `DROP CHECK ck_collection_task_source` 后重建为三值枚举,并新增 `image_search_snapshot` 列。 - `task/image_search.go`:参考图 `mediaType / sizeBytes / sha256` 校验与下载,10MB 上限。 - 价格兜底,并额外处理跨币种:蝦皮商品币种非 CNY 时记 `PriceGuardSkipped` + `CROSS_CURRENCY_TWD_PDD_CNY`,不自动关联而保留人工复核。 - `IdentifyCurrentPage` 放行 `image_search` 来源。 ### 线上迁移核对 ``` sys_migration: 1789400000000, 1789400100000 均已写入 ck_collection_task_source -> in ('admin','agent_current_page','image_search') collection_task.image_search_snapshot 已存在 shopee_product.image_search_linked 已存在 ``` ### 上一轮评论提出的文档缺口已补 `docs/08-agent-api-contract.md` 新增「SYB 商品 PDD 图搜采集(#275~#280)」章节共 160 行。按 Wiki-first 流程执行:先更新线上页面 `Android-Agent-API-Contract` 并在线回读,revision `4d1ba4423229`;再运行一次 `harness.py sync` 与一次 `sync --check`(均通过),提交由 sync 生成的本地镜像。 文档中另记录了一条已核对事实:`IdentifyCurrentPage` 要求任务已绑定 `device_id`,而批量创建允许 `deviceId` 为空——`Claim` 在事务中写入 `device_id`,因此 Agent 调用 identify 时设备必定已绑定。这一条曾是实施中标注的最高风险假设,现已由代码核对确认成立。 ## 验证 `go build ./...`、`go test ./app/goauto/task/...` 通过;线上迁移与约束已核对。 ## 状态 服务端实现与文档均已完成并上线,保持待验收。 ## 关于 sybimport 的 12 个失败用例 `app/goauto/sybimport` 有 12 个失败用例,**先于本工单存在**,来自 #272/#274 改变契约后未更新的旧断言,已单独记录为 #285。本次上线前后逐条比对失败集合完全一致,未新增。这批用例对应的代码自 `be03972`(2026-09-14)起已在线上运行。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#278