V10.399 demote named variant catalog alerts
All checks were successful
CD Pipeline / deploy (push) Successful in 1m6s

This commit is contained in:
OoO
2026-05-24 12:14:34 +08:00
committed by AiderHeal Bot
parent 4622be3441
commit 8b4bcdf277
4 changed files with 43 additions and 2 deletions

View File

@@ -325,7 +325,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
# ==========================================
# 系統版本與路徑
# ==========================================
SYSTEM_VERSION = "V10.398"
SYSTEM_VERSION = "V10.399"
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
public_url = PUBLIC_URL # 用於模板顯示

View File

@@ -13,6 +13,7 @@
## 📅 詳細更新日誌 (考古存檔)
### 2026-05-24PChome 近門檻身份回收第二輪
- **V10.399 多香味 catalog 價格告警降級**: marketplace matcher 新增 `variant_selection_review`,當一側是無明確選項的商品線、另一側列出多個具名香味/款式選項時,允許同款身份回收但只進 `identity_review`,不直接進 `price_alert_exact`。首個正式案例是 HH 女性私密衣物抗菌手洗精 200ml 對 PChome 白麝香/清新花園/寶貝粉香多香味 listing此規則避免把多香味 catalog 價格誤當單一 variant 精準比價。
- **V10.398 true low confidence 保守回收**: marketplace matcher 針對正式前段 `true_low_confidence` 補一輪 focused exact identity lines讓 Baan 嬰兒修護唇膏、植村秀 3D 極細防水眼線膠筆、YSL 恆久完美透膚煙染腮紅、HH 私密植萃美白緊緻凝露、Lab52 學習刷牙漱口水、Benefit 經典菲菲染唇液、Herb24 晨霧純精油擴香儀、Pavaruni 40 香味 10ml 精油與 GATSBY 爆水擦澡濕巾等近門檻真同款可被回收;未放寬 `MIN_MATCH_SCORE`。同版保留 peripera 多色任選對單一色號、LUNASOL 頰彩對眼彩組、MUJI 細軸棉棒對黑色棉棒的低信心保護,並讓多組件套組即使達強身份證據也停在 `identity_review`,避免總價被誤當精準價格告警。
### 2026-05-21瀏覽器測試守門與 PChome 熱路徑優化

View File

@@ -503,6 +503,8 @@ VARIANT_OPTION_COLOR_WORDS = {
"梔子花",
"白麝香",
"黑麝香",
"清新花園",
"寶貝粉香",
"青檸羅勒",
"炭木香",
"無花果",
@@ -1630,6 +1632,7 @@ def _build_evidence_flags(
flags.append("catalog_count_omission")
for reason in (
"unit_comparable",
"variant_selection_review",
"variant_option_conflict",
"variant_descriptor_conflict",
"count_conflict",
@@ -1682,7 +1685,7 @@ def _classify_match_quality(
and (direct_spec_evidence or (shared_anchor and token_score >= 0.62 and sequence_score >= 0.58))
)
if strong_identity_evidence and not catalog_count_omission:
if multi_component_pair:
if multi_component_pair or "variant_selection_review" in reason_set:
return "exact", "manual_review", "identity_review"
return "exact", "total_price", "price_alert_exact"
@@ -1760,6 +1763,9 @@ def score_marketplace_match(
variant_option_conflict = _has_explicit_variant_option_conflict(left, right, shared_anchor)
if variant_option_conflict:
reasons.append("variant_option_conflict")
variant_selection_review = _has_named_variant_selection_review(left, right, shared_anchor)
if variant_selection_review:
reasons.append("variant_selection_review")
hard_veto = brand_conflict or spec_conflict
if bundle_offer_conflict:
@@ -2936,6 +2942,24 @@ def _has_explicit_variant_option_conflict(
return True
def _has_named_variant_selection_review(
left: ProductIdentity,
right: ProductIdentity,
shared_anchor: str,
) -> bool:
left_options = _explicit_variant_option_tokens(left)
right_options = _explicit_variant_option_tokens(right)
if bool(left_options) == bool(right_options):
return False
option_identity = left if left_options else right
named_options = {option for option in (left_options or right_options) if not option.isdigit()}
if len(named_options) < 2:
return False
text = option_identity.searchable_name
return _is_multi_variant_catalog_listing(option_identity) or bool(re.search(r"[//、,&]", text))
def _search_core_score(token: str, all_tokens: set[str]) -> tuple[int, int, str]:
cleaned = _clean_search_phrase(token)
if not cleaned:

View File

@@ -843,6 +843,22 @@ def test_marketplace_matcher_ignores_quantity_plus_markers_inside_component_spec
assert "multi_component_count_conflict" not in diagnostics.reasons
def test_marketplace_matcher_keeps_named_scent_catalog_in_identity_review():
from services.marketplace_product_matcher import score_marketplace_match
diagnostics = score_marketplace_match(
"【HH草本新淨界】女性私密衣物抗菌手洗精200ml(私密衣物手洗 衣物手洗精)",
"HH女性私密衣物抗菌手洗精 200ml (白麝香&清新花園&寶貝粉香)",
momo_price=399,
competitor_price=356,
)
assert diagnostics.score >= 0.76
assert diagnostics.hard_veto is False
assert diagnostics.alert_tier == "identity_review"
assert "variant_selection_review" in diagnostics.reasons
def test_marketplace_matcher_promotes_multi_variant_catalog_listings():
from services.marketplace_product_matcher import score_marketplace_match