Files
goauto/server/app
QiuSWandClaude Opus 5 a27db5f960 fix(server): 检出 SYB 规格塌缩并明确失败,不再静默共用同一映射 (#289)
sybimport.Parse 剥离 【...】,而括号里经常是真正的规格标识而非备注:
款号 白色【207A】、色号 黑色【M0059C1】、颜色组合 【深灰+淺灰】。剥离后
不同的虾皮规格塌缩成同一个 target_color,而它正是采购查映射的键,同键
即同映射,Agent 会为不同规格点击同一个 PDD 值。

线上实测(2026-09-16):颜色塌缩键 78 个、涉及 61 个商品、190 个原始
规格;尺码塌缩键 24 个;受影响明细 407 条。落在塌缩键上的采购任务 3 笔,
order_created 0 笔——至今没出事是因为每个塌缩键目前只有一条规格真正
下过单,不是设计上有保证。最高危的 6 个键全部尚未采购。

本次不改解析契约、不迁移数据,只让它明确失败:采购预览命中塌缩键时返回
SPEC_KEY_AMBIGUOUS 并提前返回,不再落到就绪判定;process_stage 一并拦截,
因为塌缩的键不能走 AI 匹配那条路——再匹配一次也只会为同一个键写一份映射,
而问题恰恰是多个规格共用这个键。

`[必须]` 解析原语下沉到新的叶子包 sybspec。sybimport 已依赖 purchase,
采购侧直接引用会成环;而两边各写一份镜像实现必然漂移,届时塌缩检测会拿错
半边去比,结论反而不可信。sybimport 保留别名转发,调用方无需改动。

`[必须]` 检测按虾皮商品加载全部明细,不是本次请求的那几条:塌缩是商品级
属性,只看请求内的明细会漏判。

TestBatchPreviewBulkLoadsAndNeverCallsAIMatcher 的查询数由 7 改为 8,新增
的是一次有界批量查询。该断言守的是不得出现 N+1,不是具体数字。

测试样本全部取自线上真实数据。app/goauto/sybimport 的 12 个失败先于本次
存在(#285),未新增。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NTDbDcwbDw1TSAcE6wfh2F
2026-09-16 10:20:09 +08:00
..