所属 MVP:#275 | 来源:用户 2026-09-14 需求讨论(原话摘要见 #275)
服务端支持创建、下发图搜类采集任务,并在 Agent 识别出商品后回填身份;对明显不合理的候选做价格兜底。
models.CollectionTask.Source
source IN ('admin','agent_current_page')
task/current_page.go
IdentifyCurrentPage
PDDProductID
pdd_product
models.SYBProduct.ImageURL
type:text;not null
无。但契约需先定下来供 #277 使用,因此建议与 #276 并行最先启动。
collection_task.source
image_search
syb_product.unit_price_cent
docs/08-agent-api-contract.md
后端与接口改动,不强制 UI 原型。需先确认 API、数据与状态设计。
admin
agent_current_page
Go 单元测试 + .\scriptserify.ps1 -Component server。
.\scriptserify.ps1 -Component server
数据库迁移(check 约束变更)属高风险不可逆操作,实施前必须再次人工确认。
必须更新 docs/08-agent-api-contract.md;数据结构与状态变化需同步架构与业务规则 Wiki 页面。
来源:用户要求“在 #278 补定这组 API 契约,再继续 #277”。本轮仅本地实施和测试,不发布线上;#276 权限改动、#278/#279 本地迁移已获用户授权。
POST /api/admin/v1/collection-tasks/image-search/batch
{"requestId":"UUID","sybProductIds":[123,456],"ruleId":1,"deviceId":null,"overwriteLinked":false}
shopeeProductId
ruleId
deviceId
overwriteLinked=true
sybProductIds
success
taskId
replayed
code/message
successCount/failureCount/skippedCount
collection_task.image_search_snapshot
urlSnapshot
pddProductId=null
urlSnapshot/goodsIdSnapshot
继续复用 next/claim/start,source=image_search 时新增:
source=image_search
{"imageSearch":{"imageUrl":"https://example.invalid/reference.jpg","mediaType":"image/jpeg","sizeBytes":12345,"sha256":"64位小写十六进制"}}
imageSearch
复用 POST /api/agent/v1/current-page-collection-tasks/:taskId/identify,请求仍为 requestId/shareUrl,响应保持现有身份结构。
POST /api/agent/v1/current-page-collection-tasks/:taskId/identify
requestId/shareUrl
现有提交只包含来源常量/CHECK 迁移骨架,尚无完整创建、图片下发、身份扩展与价格兜底实现,#278 仍未完成;不得据此宣称 #277 的依赖已满足。下一步先完成这些 Server 能力和契约测试,再接 #277。共享正式契约需按 Wiki-first 更新 Android-Agent-API-Contract、架构和业务规则镜像,不能以本评论替代永久 API 契约。
本会话无可用 Gitea MCP,采用 Gitea API 回退;先前 DNS 失败已恢复,本次读取工单与评论均返回 HTTP 200。
已确认继续实施 #278。当前先处理服务端基础契约:保留 image_search 来源约束,收窄迁移为目标字段的幂等变更,随后补充批量创建、图片元数据快照、Agent 能力校验、识别接口扩展、价格保护及契约测试。#277 暂不并行接入,待 #278 服务端契约和测试通过后继续。
本轮不发布线上;MCP 连接器不可用,使用 REST API 回退。
已完成:
overwriteLinked
pdd.image-search.v1
提交:7b540f3、42b5312。验证:go test -p 1 ./app/goauto/task ./app/goauto/clientapi ./app/goauto/access 通过。
7b540f3
42b5312
go test -p 1 ./app/goauto/task ./app/goauto/clientapi ./app/goauto/access
SYB 默认币种按 TWD 处理;PDD 价格为人民币,尚未把跨币种金额直接比较,价格保护将在币种策略明确后完成。当前仅本地代码,未执行数据库迁移、未发布线上。
release/283
c80d0c9
main
c14f5f5
go build ./...
go test ./...
npm run build:prod
1789400000000_image_search_collection.go
DROP CHECK ck_collection_task_source
ADD CONSTRAINT
ImageSearchSnapshot
task/image_search.go
mediaType / sizeBytes / sha256
imageSearchMaxBytes = 10MB
PriceGuardSkipped
CROSS_CURRENCY_TWD_PDD_CNY
app/goauto/task
git diff --stat main..release/283 -- docs/
docs/
本工单「文档影响」写明"必须更新",且按仓库规则该文件是共享 API 的唯一事实来源。新增的图搜任务下发载荷(参考图元数据字段、image_search 来源、身份回填路径)目前只存在于代码中。
补齐该文档后本工单即可进入待验收。
1d01186
be03972..1d01186
/home/goauto/releases/20260915-1d01186
65e404c4721d592a
systemctl is-active goauto.service
active
127.0.0.1:8010
collection_task
shopee_product
外部入口验证:
GET /
GET /api/admin/v1/collection-tasks
{"code":401,"msg":"cookie token is empty"}
{"code":401,...}
最后两行是关键对照:图搜接口返回 401 而非 404,证明新路由已注册。
回退方式:把 current 软链切回 20260914-be03972-r2 后重启。两条迁移均为加列与放宽约束,不阻碍回退到旧二进制。
current
20260914-be03972-r2
提交:baa9408、35b69fc、66ab36c、ffa5fc0、7b540f3、42b5312、45437a9、cda1978、12e9aa8。
baa9408
35b69fc
66ab36c
ffa5fc0
45437a9
cda1978
12e9aa8
1789400000000_image_search_collection
image_search_snapshot
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 生成的本地镜像。
Android-Agent-API-Contract
4d1ba4423229
harness.py sync
sync --check
文档中另记录了一条已核对事实:IdentifyCurrentPage 要求任务已绑定 device_id,而批量创建允许 deviceId 为空——Claim 在事务中写入 device_id,因此 Agent 调用 identify 时设备必定已绑定。这一条曾是实施中标注的最高风险假设,现已由代码核对确认成立。
device_id
Claim
go build ./...、go test ./app/goauto/task/... 通过;线上迁移与约束已核对。
go test ./app/goauto/task/...
服务端实现与文档均已完成并上线,保持待验收。
app/goauto/sybimport 有 12 个失败用例,先于本工单存在,来自 #272/#274 改变契约后未更新的旧断言,已单独记录为 #285。本次上线前后逐条比对失败集合完全一致,未新增。这批用例对应的代码自 be03972(2026-09-14)起已在线上运行。
app/goauto/sybimport
be03972
No dependencies set.
The note is not visible to the blocked user.
目标
服务端支持创建、下发图搜类采集任务,并在 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 并行最先启动。
方案
collection_task.source增加取值image_search。check 约束变更属于数据库迁移,需新增 version-local 迁移文件;实施前必须人工确认。IdentifyCurrentPage形态,允许image_search来源调用。syb_product.unit_price_cent偏离超过可配阈值(建议默认 3 倍)时不建立关联,任务明确失败并记录错误码。此项只挡最离谱的错配,不构成"服务端判断商品是否正确"。docs/08-agent-api-contract.md。设计证据
后端与接口改动,不强制 UI 原型。需先确认 API、数据与状态设计。
验收
admin/agent_current_page任务不受影响。验证
Go 单元测试 +
.\scriptserify.ps1 -Component server。风险
数据库迁移(check 约束变更)属高风险不可逆操作,实施前必须再次人工确认。
文档影响
必须更新
docs/08-agent-api-contract.md;数据结构与状态变化需同步架构与业务规则 Wiki 页面。API 契约补充 v1(目标契约,不代表已实现)
来源:用户要求“在 #278 补定这组 API 契约,再继续 #277”。本轮仅本地实施和测试,不发布线上;#276 权限改动、#278/#279 本地迁移已获用户授权。
1. 批量创建
POST /api/admin/v1/collection-tasks/image-search/batchshopeeProductId去重,一个蝦皮商品产生一个采集任务。ruleId必填,沿用现有采集规则快照;deviceId可空,但只能由支持图搜能力的新 Agent 领取。overwriteLinked=true),不能把上一版“仅未关联”摘要理解成取消覆盖需求。shopeeProductId、该组sybProductIds、success、taskId、replayed或code/message;总计使用successCount/failureCount/skippedCount。2. 图片与任务快照
collection_task.image_search_snapshotJSON,不复用urlSnapshot存图片 URL,不新增任务表。pddProductId=null,urlSnapshot/goodsIdSnapshot为空;图片信息独立保存。3. Agent 下发
继续复用 next/claim/start,
source=image_search时新增:imageSearch;Agent 在解析任务时验证元数据,下载校验成功后才写入 MediaStore。4. 身份回填与重采
复用
POST /api/agent/v1/current-page-collection-tasks/:taskId/identify,请求仍为requestId/shareUrl,响应保持现有身份结构。5. 成功后关联边界
实现状态与文档
现有提交只包含来源常量/CHECK 迁移骨架,尚无完整创建、图片下发、身份扩展与价格兜底实现,#278 仍未完成;不得据此宣称 #277 的依赖已满足。下一步先完成这些 Server 能力和契约测试,再接 #277。共享正式契约需按 Wiki-first 更新 Android-Agent-API-Contract、架构和业务规则镜像,不能以本评论替代永久 API 契约。
本会话无可用 Gitea MCP,采用 Gitea API 回退;先前 DNS 失败已恢复,本次读取工单与评论均返回 HTTP 200。
实施开始记录(本地)
已确认继续实施 #278。当前先处理服务端基础契约:保留
image_search来源约束,收窄迁移为目标字段的幂等变更,随后补充批量创建、图片元数据快照、Agent 能力校验、识别接口扩展、价格保护及契约测试。#277 暂不并行接入,待 #278 服务端契约和测试通过后继续。本轮不发布线上;MCP 连接器不可用,使用 REST API 回退。
本地实施进展(待验收)
已完成:
POST /api/admin/v1/collection-tasks/image-search/batch,按 SYB 明细按shopeeProductId去重,支持overwriteLinked、批次稳定 requestId、单商品活动任务防重。source=image_search任务下发图片元数据,服务端不会把图片字节放入载荷。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 价格为人民币,尚未把跨币种金额直接比较,价格保护将在币种策略明确后完成。当前仅本地代码,未执行数据库迁移、未发布线上。
核对范围与方法(2026-09-15)
release/283@c80d0c9;基线main@c14f5f5。go build ./...、go test ./...(server)、npm run build:prod(web)、逐条对照工单验收项读取 diff。结论:实现达标,文档未完成
已完成
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上限。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来源、身份回填路径)目前只存在于代码中。补齐该文档后本工单即可进入待验收。
上线信息(共用)
1d01186,已推送be03972..1d01186到main。/home/goauto/releases/20260915-1d01186,二进制 SHA-256 前缀65e404c4721d592a(本地与服务器一致)。systemctl is-active goauto.service=active,监听127.0.0.1:8010。collection_task222 行、shopee_product26901 行,逐一相符。外部入口验证:
GET /GET /api/admin/v1/collection-tasks{"code":401,"msg":"cookie token is empty"}POST /api/admin/v1/collection-tasks/image-search/batch{"code":401,...}最后两行是关键对照:图搜接口返回 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 上限。PriceGuardSkipped+CROSS_CURRENCY_TWD_PDD_CNY,不自动关联而保留人工复核。IdentifyCurrentPage放行image_search来源。线上迁移核对
上一轮评论提出的文档缺口已补
docs/08-agent-api-contract.md新增「SYB 商品 PDD 图搜采集(#275~#280)」章节共 160 行。按 Wiki-first 流程执行:先更新线上页面Android-Agent-API-Contract并在线回读,revision4d1ba4423229;再运行一次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)起已在线上运行。