本正文为最终版(2026-08-28 重写)。 此前的历史评论仅作决策过程记录;如与本正文冲突,一律以本正文为准。
AGENTS.md
30d8238
models.PDDProduct.status
pending
active
disabled
models/schema.go:59
models/purchase.go:91-103
PDDURLSnapshot
PDDGoodsIDSnapshot
ShopeeOrderNoSnapshot
Target*
Mapped*
SpecDecisionSnapshot
models/schema.go:297-300
shopee_product.specs_json
models/schema.go:315
confirmedMappings()
purchase/service.go:282
models.AgentDevice
models/schema.go:28-46
pdd_product_replacement
id
source_product_id
OnDelete:RESTRICT
target_product_id
origin_type
collection
purchase
origin_task_id
target_collection_task_id
status
superseded
mapping_status
matching
completed
completed_partial
created_by_device_id
decided_by
create_request_id
created_at
mapping_updated_at
要点:
origin_type + origin_task_id
replacesTaskId
target
status = active
collection_task.ActiveSlot
models/schema.go:128
AgentDevice
pdd_product_replacement_item
一个 PDD 商品可被多个虾皮商品共用,替换后各自的匹配结果可能不同(S1 已匹配、S2 需人工、S3 失败)。因此必须分项:
replacement_id
shopee_product_id
matched
manual_required
source
ai_match
exact_match
manual_mapping
confidence
reason
attempt_count
last_error_code
last_error_at
updated_at
target_product_id == source_product_id
replacement_item
access/purchaser.go
origin_type = collection
go test ./app/goauto/...
Architecture-and-Code-Map
Business-Rules-and-Glossary
sync
sync --check
待实施(数据库迁移需实施前再次人工确认)。
用户于 2026-08-28 与采购员沟通后确认:Agent 由采购员本人使用,采集与采购任务也由其创建,因此原设计中「先记录待确认、再由采购员在 Admin 批准」的双人复核在同一人身上属纯摩擦,予以取消。用户进一步明确:「尽量简单易用地用 PDD 代替商品替换失效的 PDD 商品,不要增加繁琐和误人心智的操作流程和文字。」
本评论修订 #129 的状态机与约束,覆盖正文中与 pending 审核流程相关的部分。
approved
rejected
decided_at
requested_at
正文第 2 项「同一 source_product_id 同时只允许一条 pending」调整为:
正文的数据模型(除状态与唯一性约束外)、权限、安全边界、文档影响不变。
用户于 2026-08-28 确认整体流程为「替换 → 自动 AI 匹配规格 → Agent 刷新看状态 → 继续采购」,并选定 AI 结果按 B 方案处理(高置信自动确认,低置信留人工)。本评论在 #129 的数据模型上补充承载该流程所需的状态字段。
pdd_product_replacement 增加:
该字段是 Agent 刷新时的唯一判据:matched 显示可继续采购,其余显示需人工匹配。没有它,Agent 只能靠猜。
审计只读接口需返回 mapping_status,供 Agent 的采购/采集任务详情展示与按钮显隐判断使用。
正文其余部分(表结构主体、唯一性约束、审计定位、decided_by 只能定位到设备的局限)不变。
基于当前代码 30d8238 复核,#129 → #131 → #130 → #132 的总体顺序可以保留,但本工单模型还不能完整承载最新版流程。以下内容建议由 Claude Code 审核并合并进最终正文后再实施。
#129 → #131 → #130 → #132
来源模型需同时支持采集任务与采购任务
origin_collection_task_id
origin_collection_task_id / origin_purchase_task_id
单条 mapping_status 无法表达多个虾皮商品的不同结果
shopee_product
pdd_product_replacement_item(replacement_id, shopee_product_id, mapping_status, source, confidence, reason, updated_at)
需要记录替代商品的采集证据
连续替换不是可靠的撤销
request_id
当前正文仍描述 pending 审核模型,评论改为即时生效;建议实施前把最终状态机、字段、接口和验收标准合并回正文,避免实现者漏读覆盖评论。
用户于 2026-08-28 明确授权:#129 涉及的数据库迁移可按已确认工单方案进入实施。
授权边界:仅覆盖本工单所需的数据模型/迁移实施与验证;不自动授权生产发布、删除数据、不可逆生产迁移或支付。开始实施时仍须按工单依赖、备份/回退方案和迁移验证门禁执行。当前回合仅制作 #130 + #132 原型,尚未实施 #129。
已按最终正文完成 #129,并推送到 main。
main
1787885000000_pdd_product_replacement.go
rg
go test ./app/goauto/replacement ./app/goauto/migrations ./app/goauto/access ./app/admin/router ./cmd/migrate/migration/version-local
.\\scripts\\verify.ps1 -Component server
go test ./...
go build
d585a906857a46752788c9f25d3ac0361739dada
b31ebf8888da7c3d9b71520938b104ff9e66511f
harness.py sync
696e0bc feat(#129): add PDD product replacement model
origin/main
created_by_device_id 只能定位 Agent 设备,不能追溯采购员账号;多人多机场景的设备绑定操作员仍需独立工单。本工单保持打开,状态为待验收。
用户于 2026-08-29 明确确认本工单通过验收。验收结论已记录,现关闭工单。没有新的长期事实变化,本次不重复同步 Wiki。
No dependencies set.
The note is not visible to the blocked user.
所属与来源
AGENTS.md「Gitea 交互与工单最小读取」记录回退原因。当前事实(提交
30d8238复核)models.PDDProduct.status三态pending/active/disabled(models/schema.go:59),可表达失效而无需删除。models/purchase.go:91-103),含PDDURLSnapshot、PDDGoodsIDSnapshot(带索引)、ShopeeOrderNoSnapshot、Target*/Mapped*/SpecDecisionSnapshot。外键改指不会丢失下单时的商品身份。models/schema.go:297-300)。shopee_product.specs_json(models/schema.go:315);采购任务中的Mapped*只是建任务时由confirmedMappings()(purchase/service.go:282)抄取的副本。models.AgentDevice(models/schema.go:28-46)只有设备身份,无操作人绑定。目标
非目标
实施方案
一、主表
pdd_product_replacementidsource_product_idOnDelete:RESTRICTtarget_product_idOnDelete:RESTRICTorigin_typecollection/purchase,check 约束origin_task_idorigin_type组合解释target_collection_task_idstatusactive/superseded,check 约束mapping_statusmatching/completed/completed_partialcreated_by_device_iddecided_by)create_request_idcreated_at/mapping_updated_at要点:
origin_type + origin_task_id组合表达来源。不得只用replacesTaskId——采集任务与采购任务是两张表,ID 可能重复。target_collection_task_id必须指向一条已completed或completed_partial且商品为target的采集任务,作为「哪次采集证明了替代商品」的证据。source_product_id同时只允许一条status = active的记录,用可空守卫列 + 复合唯一索引实现(参照collection_task.ActiveSlot,models/schema.go:128),保证跨 SQLite / MySQL / PostgreSQL 一致。created_by_device_id的已知局限必须写入实施结论:AgentDevice无操作人绑定,只能定位到设备,不能追溯到采购员账号。多人多机场景需先做「设备绑定操作员」,另行建单。二、分项表
pdd_product_replacement_item一个 PDD 商品可被多个虾皮商品共用,替换后各自的匹配结果可能不同(S1 已匹配、S2 需人工、S3 失败)。因此必须分项:
replacement_idshopee_product_idmapping_statusmatching/matched/manual_requiredsourceai_match/exact_match/manual_mappingconfidencereasonattempt_count/last_error_code/last_error_atupdated_at要点:
mapping_status不得用于判定某条采购任务能否续做;#130 展示与 #132 判定一律读取该任务对应虾皮商品的分项状态。三、登记接口
target_product_id == source_product_id;source_product_id已存在status = active的记录;target不是active;source_product_id不一致;target_collection_task_id缺失或不满足第 3 条;create_request_id重放时必须核对 source、target、origin_type、origin_task_id全部一致,返回既有记录;任一不一致返回幂等冲突错误,不得静默覆盖。四、纠错语义
superseded,新建 A→C 并只处理原记录replacement_item中记录的影响范围。superseded状态与影响集合数据;纠错动作的实施在 #131。五、权限
access/purchaser.go单独登记权限点。Agent 不直接获得 Admin 写权限:Agent 只在采集流程中提交替换上下文,登记与生效由服务端内部领域服务完成。安全边界
验收标准
origin_type = collection与purchase两种来源均可正确登记与查询。active记录时,再次登记被拒绝。active、替换链成环,三种情况均被拒绝。target_collection_task_id缺失或不满足要求时被拒绝。create_request_id携带不同内容时返回幂等冲突,不静默覆盖;内容一致时返回既有记录。created_by_device_id只能定位到设备的局限。验证方式
go test ./app/goauto/...依赖、并行与风险
文档影响
Architecture-and-Code-Map:新增替换关系与分项表及其边界。Business-Rules-and-Glossary:商品替换的业务定义、即时生效口径、纠错语义。sync与一轮sync --check,把页面与 revision 写回本工单。状态
待实施(数据库迁移需实施前再次人工确认)。
范围修订:取消人工确认环节,替换即时生效
用户于 2026-08-28 与采购员沟通后确认:Agent 由采购员本人使用,采集与采购任务也由其创建,因此原设计中「先记录待确认、再由采购员在 Admin 批准」的双人复核在同一人身上属纯摩擦,予以取消。用户进一步明确:「尽量简单易用地用 PDD 代替商品替换失效的 PDD 商品,不要增加繁琐和误人心智的操作流程和文字。」
本评论修订 #129 的状态机与约束,覆盖正文中与
pending审核流程相关的部分。一、状态机简化
status直接落approved,不再经过pending。status列与rejected值以便将来扩展,但本工单不产生这两种状态,也不提供任何审核接口。decided_at等同于requested_at;decided_by见第三节。二、唯一性约束调整
正文第 2 项「同一
source_product_id同时只允许一条pending」调整为:source_product_id只允许一条生效中的替换记录(即一个失效商品只能被替换一次)。三、审计与已知局限
models.AgentDevice(models/schema.go:28-46)只有设备身份(InstallID、型号、token),没有绑定到具体操作人。因此decided_by实际只能记录到发起设备,不能追溯到采购员账号。当前单人单机场景下等价,多人多机时需要先做「设备绑定操作员」,属另行建单范围,本工单不实现。四、接口调整
五、验收标准调整
approved记录并正确拒绝非法输入。decided_by只能定位到设备这一局限。正文的数据模型(除状态与唯一性约束外)、权限、安全边界、文档影响不变。
修订:增加匹配状态字段,串起替换后的规格匹配流程
用户于 2026-08-28 确认整体流程为「替换 → 自动 AI 匹配规格 → Agent 刷新看状态 → 继续采购」,并选定 AI 结果按 B 方案处理(高置信自动确认,低置信留人工)。本评论在 #129 的数据模型上补充承载该流程所需的状态字段。
一、替换记录新增匹配状态
pdd_product_replacement增加:mapping_status:matching/matched/manual_required,check 约束matching:替换已生效,AI 匹配进行中或待发起matched:规格映射已可用(AI 高置信自动确认,或人工已确认)manual_required:AI 关闭、AI 无结果、置信度不足或缺失,需人工在 Admin 匹配mapping_updated_at:状态最后变更时间该字段是 Agent 刷新时的唯一判据:
matched显示可继续采购,其余显示需人工匹配。没有它,Agent 只能靠猜。二、状态流转
matching;matched或manual_required;manual_required转为matched;三、只读查询接口补充
审计只读接口需返回
mapping_status,供 Agent 的采购/采集任务详情展示与按钮显隐判断使用。四、验收标准补充
mapping_status三态可正确写入与查询,非法值被 check 约束拒绝。matching。正文其余部分(表结构主体、唯一性约束、审计定位、
decided_by只能定位到设备的局限)不变。Codex 全栈复核:数据模型与跨工单契约待补全
基于当前代码
30d8238复核,#129 → #131 → #130 → #132的总体顺序可以保留,但本工单模型还不能完整承载最新版流程。以下内容建议由 Claude Code 审核并合并进最终正文后再实施。阻塞项
来源模型需同时支持采集任务与采购任务
origin_collection_task_id。origin_type + origin_task_id,或origin_collection_task_id / origin_purchase_task_id两个可空字段并加 check 约束。replacesTaskId,因为两个任务表可能出现相同 ID。单条
mapping_status无法表达多个虾皮商品的不同结果shopee_product共用;替换后可能出现 S1 已匹配、S2 需人工、S3 匹配失败。pdd_product_replacement_item(replacement_id, shopee_product_id, mapping_status, source, confidence, reason, updated_at)。需要记录替代商品的采集证据
target_collection_task_id,并要求其已完成或部分完成、商品为 target,保证审计能够回答“哪次成功采集证明了替代商品”。连续替换不是可靠的撤销
superseded并执行 A→C,只处理原记录影响范围。契约补充
request_id重放时必须核对 source、target、来源类型和来源任务均一致;相同 UUID 携带不同内容应返回幂等冲突。decided_by只能定位设备的限制可以保留,但建议字段明确命名为设备身份,避免被误解为采购员账号。工单一致性
当前正文仍描述 pending 审核模型,评论改为即时生效;建议实施前把最终状态机、字段、接口和验收标准合并回正文,避免实现者漏读覆盖评论。
PDD 商品替换(一):服务端替换关系记录与发起接口to PDD 商品替换(一):替换关系与分项匹配状态数据模型高风险实施授权记录
用户于 2026-08-28 明确授权:#129 涉及的数据库迁移可按已确认工单方案进入实施。
授权边界:仅覆盖本工单所需的数据模型/迁移实施与验证;不自动授权生产发布、删除数据、不可逆生产迁移或支付。开始实施时仍须按工单依赖、备份/回退方案和迁移验证门禁执行。当前回合仅制作 #130 + #132 原型,尚未实施 #129。
实施完成,待验收
已按最终正文完成 #129,并推送到
main。实现
pdd_product_replacement与pdd_product_replacement_item,迁移版本1787885000000_pdd_product_replacement.go;只新增表,不改既有表和数据。rg和定点源码读取;Gitea 与 Wiki 全程使用 Gitea MCP。验证
go test ./app/goauto/replacement ./app/goauto/migrations ./app/goauto/access ./app/admin/router ./cmd/migrate/migration/version-local:通过。go test ./app/goauto/...:通过。.\\scripts\\verify.ps1 -Component server:通过(go test ./...+go build)。文档
d585a906857a46752788c9f25d3ac0361739dadab31ebf8888da7c3d9b71520938b104ff9e66511fharness.py sync与一轮sync --check,一致性通过。提交
696e0bc feat(#129): add PDD product replacement modelorigin/main已知局限
created_by_device_id只能定位 Agent 设备,不能追溯采购员账号;多人多机场景的设备绑定操作员仍需独立工单。本工单保持打开,状态为待验收。用户于 2026-08-29 明确确认本工单通过验收。验收结论已记录,现关闭工单。没有新的长期事实变化,本次不重复同步 Wiki。