V10.392 guard multi-component bundle matches
All checks were successful
CD Pipeline / deploy (push) Successful in 1m3s
All checks were successful
CD Pipeline / deploy (push) Successful in 1m3s
This commit is contained in:
@@ -325,7 +325,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
|
||||
# ==========================================
|
||||
# 系統版本與路徑
|
||||
# ==========================================
|
||||
SYSTEM_VERSION = "V10.391"
|
||||
SYSTEM_VERSION = "V10.392"
|
||||
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
|
||||
public_url = PUBLIC_URL # 用於模板顯示
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
## 📅 詳細更新日誌 (考古存檔)
|
||||
|
||||
### 2026-05-21:瀏覽器測試守門與 PChome 熱路徑優化
|
||||
- **V10.392 組合包件數防錯配**: marketplace matcher 新增 `multi_component_count_conflict`,當 MOMO 與 PChome 都是 `+`/`+` 組合包但組件數不同時直接進 `not_comparable`,避免三件組被拿去跟兩件組做總價告警;同步把該原因加入 evidence flags,讓告警與審核畫面可以清楚顯示「組合包件數不同」。
|
||||
- **V10.391 多款任選 catalog listing 防錯配**: marketplace matcher 新增 `catalog_variant_listing_alignment`,當 MOMO/PChome 雙方都是多款/多色/多香味任選 listing,且商品線、規格與類型一致時,可放行香氛擴香罐、香氛蠟燭等 catalog 型同款;同時把 Relove 菸鹼醯胺 vs 胺基酸私密清潔凝露列為變體衝突,並讓 competitor feeder 不再只因 `strong_exact_spec_match` 就把低分候選視為 recoverable,避免只同規格但品線不同的商品回寫正式比價。
|
||||
- **V10.390 PChome 近門檻商品比對規則**: marketplace matcher 補 17 組近門檻真同款召回與錯配防線,包含 OBgE 防曬棒、ARTMIS 私密清潔慕斯、Seche Vite 快乾亮油、TAICEND 屁屁噴、femfresh / VIGILL 私密清潔、Solone 眼部飾底乳、HYDSTO 車載香薰、小米 S101 刮鬍刀、PRAMY 定妝噴霧、I'M MEME 修容打亮棒、檜山坊滾珠精油、ARM&HAMMER 體香膏、Brush Baby WildOnes 電動牙刷與 Palmer's 按摩乳;同時把香氛/私密慕斯/定妝噴霧 finish 差異列為 variant-sensitive,避免不同香味、蔓越莓 vs 金縷梅、柔焦霧面 vs 水光亮面被誤推成直接價格告警。
|
||||
- **V10.388 精華乳 / 精華霜變體防錯配**: marketplace matcher 新增精華類 formulation conflict guard,當共享 identity anchor 只到「精華」但一側是「精華乳」、另一側是「精華霜 / 精華液」時會標記 `variant_descriptor_conflict` 並壓低同款分數,避免自白肌等同品牌相近品線被錯推成 PChome/MOMO 可直接價格告警。Competitor feeder 同步會用最新 matcher 重新驗舊配對;若舊 `identity_v2` 已被現行 matcher 判成低分或 veto,允許新的高信心候選替換,避免歷史錯配卡住正式 `competitor_prices`。
|
||||
|
||||
@@ -1241,6 +1241,18 @@ def _has_multi_component(identity: ProductIdentity) -> bool:
|
||||
)
|
||||
|
||||
|
||||
def _multi_component_count(identity: ProductIdentity) -> int:
|
||||
text = identity.normalized_name
|
||||
if not ("+" in text or "+" in text):
|
||||
return 1
|
||||
parts = [
|
||||
part.strip()
|
||||
for part in re.split(r"[++]", text)
|
||||
if part.strip() and not re.fullmatch(r"[\s\d-]+", part.strip())
|
||||
]
|
||||
return len(parts) if len(parts) > 1 else 1
|
||||
|
||||
|
||||
def _has_refill_pack(identity: ProductIdentity) -> bool:
|
||||
text = identity.normalized_name
|
||||
return bool(
|
||||
@@ -1563,6 +1575,7 @@ def _build_evidence_flags(
|
||||
"count_conflict",
|
||||
"bundle_offer_conflict",
|
||||
"multi_component_conflict",
|
||||
"multi_component_count_conflict",
|
||||
"accessory_case_conflict",
|
||||
"refill_pack_conflict",
|
||||
"price_ratio_extreme",
|
||||
@@ -1658,6 +1671,13 @@ def score_marketplace_match(
|
||||
reasons.append("bundle_offer_conflict")
|
||||
if _has_multi_component(left) != _has_multi_component(right):
|
||||
reasons.append("multi_component_conflict")
|
||||
multi_component_count_conflict = (
|
||||
_has_multi_component(left)
|
||||
and _has_multi_component(right)
|
||||
and _multi_component_count(left) != _multi_component_count(right)
|
||||
)
|
||||
if multi_component_count_conflict:
|
||||
reasons.append("multi_component_count_conflict")
|
||||
if _has_refill_pack(left) != _has_refill_pack(right):
|
||||
reasons.append("refill_pack_conflict")
|
||||
accessory_case_conflict = _has_accessory_case(left) != _has_accessory_case(right)
|
||||
@@ -1683,6 +1703,8 @@ def score_marketplace_match(
|
||||
hard_veto = True
|
||||
if _has_multi_component(left) != _has_multi_component(right):
|
||||
hard_veto = True
|
||||
if multi_component_count_conflict:
|
||||
hard_veto = True
|
||||
if _has_refill_pack(left) != _has_refill_pack(right):
|
||||
hard_veto = True
|
||||
if accessory_case_conflict:
|
||||
|
||||
@@ -765,27 +765,36 @@ def test_marketplace_matcher_rejects_fragrance_formula_and_finish_variant_mismat
|
||||
(
|
||||
"【MUJI 無印良品】芬香蠟燭.茉莉花香味/85g",
|
||||
"芬香蠟燭.梔子花香味/85g【MUJI 無印良品】",
|
||||
"variant_option_conflict",
|
||||
),
|
||||
(
|
||||
"【Play&Joy 官方直營】ARTMIS 蔓越莓私密清潔慕斯 250ml",
|
||||
"ARTMIS 金縷梅私密清潔慕斯 250ml",
|
||||
"variant_option_conflict",
|
||||
),
|
||||
(
|
||||
"【PRAMY 柏瑞美】磁吸控油定妝噴霧 100ML(柔焦霧面)",
|
||||
"【柏瑞美PRAMY】 磁吸控油定粧噴霧 水光亮面",
|
||||
"variant_option_conflict",
|
||||
),
|
||||
(
|
||||
"【Relove】8%菸鹼醯胺私密淨白清潔凝露120ml(私密清潔 私密美白 涼感潔淨 PH3.8弱酸呵護)",
|
||||
"RELOVE胺基酸私密清潔凝露120ml",
|
||||
"variant_option_conflict",
|
||||
),
|
||||
(
|
||||
"【CeraVe 適樂膚】極抗痕抗老全配組★極抗痕A醇緊緻修護精華+極抗痕多肽緊緻修護霜+極抗痕C10煥亮修護精華",
|
||||
"【CeraVe適樂膚】極抗痕A醇緊緻修護精華 30ml+極抗痕多肽緊緻修護霜 48g",
|
||||
"multi_component_count_conflict",
|
||||
),
|
||||
]
|
||||
|
||||
for momo_name, competitor_name in cases:
|
||||
for momo_name, competitor_name, expected_reason in cases:
|
||||
diagnostics = score_marketplace_match(momo_name, competitor_name)
|
||||
assert diagnostics.hard_veto is True
|
||||
assert diagnostics.comparison_mode == "not_comparable"
|
||||
assert diagnostics.score < 0.76
|
||||
assert "variant_option_conflict" in diagnostics.reasons
|
||||
assert expected_reason in diagnostics.reasons
|
||||
|
||||
|
||||
def test_marketplace_matcher_promotes_multi_variant_catalog_listings():
|
||||
|
||||
Reference in New Issue
Block a user