fix(comparison): 比价 best 无 is_best 时兜底回落「含源最低价」 #201

Merged
guke merged 3 commits from fix/comparison-best-fallback-no-isbest into main 2026-07-30 11:00:36 +08:00
Member

背景
_derive_from_platforms 是比价记录的单一真相源派生函数(pricebot done 帧带 platforms 时走它),正常路径直接取 platforms 里 is_best=true 的那行当最低价。

线上出现一类帧(如记录 id 3304):全平台 has_dish_diff(菜品「相似替换 / 价格仅供参考」),pricebot 认为无法认定权威最低价,于是一个 is_best 都不标。此时旧逻辑 best=None,导致 best_platform_id / best_price_cents / saved_amount_cents / is_source_best 整条落 NULL,连锁反应:

首页比价价显示 0.00
记录页无最低价红框
省额丢失、「累计发现可省」漏计
方案
无 is_best 时兜底:在有价行里取最低价当参考 best。

关键设计点 —— 候选池含源(而非仅目标):源平台常年全菜、价可信。若源本身最便宜(其余都是更贵的相似替换),则 best 回落到源、saved=0、is_source_best=True。这与仓库老派生函数 _derive 的既有语义(「全目标缺菜 → 回落源、不虚报省」)完全一致,三个派生函数行为对齐。

⚠️ 若像分支首个提交那样排除源、强选最低目标,当源最便宜时会选中更贵目标 → saved 变负,倒扣 get_stats 的「累计发现可省」(该聚合按 status='success' 求和、不带 >0 过滤)。第二个提交据此修正为含源。

影响面 / 兼容性
只影响「带 platforms 且无任何 is_best」这一条兜底分支;正常有 is_best 的路径不变。
老客户端不带 platforms → 走 _derive,不受影响。
纯派生逻辑,无 schema / 无迁移,回滚成本低。

背景 _derive_from_platforms 是比价记录的单一真相源派生函数(pricebot done 帧带 platforms 时走它),正常路径直接取 platforms 里 is_best=true 的那行当最低价。 线上出现一类帧(如记录 id 3304):全平台 has_dish_diff(菜品「相似替换 / 价格仅供参考」),pricebot 认为无法认定权威最低价,于是一个 is_best 都不标。此时旧逻辑 best=None,导致 best_platform_id / best_price_cents / saved_amount_cents / is_source_best 整条落 NULL,连锁反应: 首页比价价显示 0.00 记录页无最低价红框 省额丢失、「累计发现可省」漏计 方案 无 is_best 时兜底:在有价行里取最低价当参考 best。 关键设计点 —— 候选池含源(而非仅目标):源平台常年全菜、价可信。若源本身最便宜(其余都是更贵的相似替换),则 best 回落到源、saved=0、is_source_best=True。这与仓库老派生函数 _derive 的既有语义(「全目标缺菜 → 回落源、不虚报省」)完全一致,三个派生函数行为对齐。 ⚠️ 若像分支首个提交那样排除源、强选最低目标,当源最便宜时会选中更贵目标 → saved 变负,倒扣 get_stats 的「累计发现可省」(该聚合按 status='success' 求和、不带 >0 过滤)。第二个提交据此修正为含源。 影响面 / 兼容性 只影响「带 platforms 且无任何 is_best」这一条兜底分支;正常有 is_best 的路径不变。 老客户端不带 platforms → 走 _derive,不受影响。 纯派生逻辑,无 schema / 无迁移,回滚成本低。
guke added 3 commits 2026-07-30 11:00:32 +08:00
#195 改为只认 pricebot platforms.is_best 后, 全平台 has_dish_diff
(相似替换/仅供参考) pricebot 一个 is_best 都不标时, best_*/saved 整条落
NULL → 首页价 ¥0.0 / 记录页无最低红框 / 省额丢失 (线上占 success ~33%)。

_derive_from_platforms 增兜底: 无 is_best 但有有价目标时取最低价当参考 best,
不再让派生列静默 NULL; 复用 platforms 单源, 不引入 comparison_results 双源。

TDD: 新增 test_harvest_done_platforms_no_isbest_falls_back_to_cheapest_target
(id 3304 型), 先复现 best_platform_id=None 再修绿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
无 is_best 兜底原本排除源、强选最低目标;当源本身最便宜时(全平台
dish-diff 相似替换),会误选更贵目标 → saved 变负,倒扣 get_stats 的
「累计发现可省」(该聚合按 status=success 求和、不带 >0 过滤)。

改为在含源的有价行里取最低价,与老派生函数 _derive「全目标缺菜回落源、
不虚报省」同一语义:源最便宜 → best=源、saved=0、is_source_best=True。
补回归测试:源最便宜场景(旧逻辑 best 误选更贵目标、saved 为负)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
guke merged commit b6ddb275f4 into main 2026-07-30 11:00:36 +08:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: WonderableAI/shaguabijia-app-server#201