diff --git a/TODO_NEXT_STEPS.txt b/TODO_NEXT_STEPS.txt index 886a491..552131b 100644 --- a/TODO_NEXT_STEPS.txt +++ b/TODO_NEXT_STEPS.txt @@ -4,6 +4,7 @@ ================================================================================ 【已完成】 + - V10.563 收斂正式 preview 假可救候選:M.A.C 超持妝輕透濾鏡蜜粉若只有 PChome 端出現明確色號(例如 `#絕絕紫`),會標成 `variant_selection_review` 並維持 `true_low_confidence`,不再佔 recoverable 池;SAUGELLA 賽吉兒菁萃潔浴凝露新增潤澤 / 日用型 / 加強 / 黃金女郎型變體互斥,避免同品線不同私密清潔款式被誤救成 matched。 - V10.561 補 PChome 比價補強前端分段回饋:Dashboard 的 PChome 卡片從「補抓產線」改為「比價補強產線」,按鈕與確認文案同步說明會先刷新舊 identity、再重評近門檻與補抓未配對;結果區新增刷新 / 重評 / 補抓三段 matched/total 摘要,避免後端已完成分段統計但操作員仍只看到一個籠統成功數。 - V10.560 串起手動 PChome 比價補強三段式流程:`/api/ai/pchome-match/backfill` 現在不只跑近門檻重評與未配對補抓,也會先用小批次 `run_expired_identity_refresh()` 刷新已知 `identity_v2` 舊價格,讓操作員按一次補強就能同時處理「舊 identity 新鮮度」、「near-threshold low_score」與「pending identity」三條主線。結果 payload 新增 `stale_identity_refresh` 分段統計,方便後續 Dashboard / 簡報 / AI 決策知道覆蓋率改善是來自刷新、重評或補抓。 - V10.559 收斂 retryable 有效身份新鮮度:`_fetch_retryable_candidate_skus()` 不再把 `expires_at IS NULL` 的舊 PChome `identity_v2` 當成有效阻擋條件,只有明確 `expires_at > CURRENT_TIMESTAMP` 的新鮮 identity 才會阻止 near-threshold revalidation。未知新鮮度仍走 V10.551 的 expired / recovery 刷新入口,重評後仍必須通過最新版 matcher、hard-veto、auto write safety 與既有正式候選覆寫保護,避免為了拉覆蓋率犧牲準確率。 diff --git a/config.py b/config.py index f405957..91f2b6e 100644 --- a/config.py +++ b/config.py @@ -402,7 +402,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '') # ========================================== # 系統版本與路徑 # ========================================== -SYSTEM_VERSION = "V10.561" +SYSTEM_VERSION = "V10.563" LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log') public_url = PUBLIC_URL # 用於模板顯示 diff --git a/docs/memory/history_logs.md b/docs/memory/history_logs.md index 71101a6..88fdc06 100644 --- a/docs/memory/history_logs.md +++ b/docs/memory/history_logs.md @@ -13,6 +13,7 @@ ## 📅 詳細更新日誌 (考古存檔) ### 2026-06-01:PChome 比價新鮮度操作閉環 +- **V10.563 正式 preview 假可救候選收斂**: 針對正式 `retryable_candidate_preview` 露出的 M.A.C 蜜粉與 SAUGELLA 菁萃潔浴凝露案例補 guard。M.A.C 單邊明確色號(如 `#絕絕紫`)會進 `variant_selection_review`,維持 `true_low_confidence`;SAUGELLA 潤澤 / 日用型 / 加強 / 黃金女郎型互斥,直接 hard veto,避免同品線不同私密清潔款式被當成 recoverable low_score。 - **V10.561 PChome 比價補強前端分段回饋**: Dashboard 的 PChome 操作卡改名為「比價補強產線」,手動按鈕與確認文案同步說明三段流程;結果摘要會顯示刷新、重評、補抓各自的 matched/total,讓操作員能判斷覆蓋率改善來自舊 identity 新鮮度回補、近門檻 matcher 回刷,或 pending 商品 fresh search 補抓。 - **V10.560 手動 PChome 比價補強三段式串接**: `/api/ai/pchome-match/backfill` 與每日 scheduler 口徑對齊,手動執行時先小批次刷新過期 `identity_v2`,再跑近門檻候選重評,最後補抓高優先未配對商品。回傳結果新增 `stale_identity_refresh` 分段統計,讓後續 Dashboard、簡報與 AI 決策能區分覆蓋率改善來自舊 identity 新鮮度回補、matcher 回刷,還是 fresh search 補抓。 - **V10.559 retryable 有效身份新鮮度收斂**: `_fetch_retryable_candidate_skus()` 的既有 identity 阻擋條件改成只接受 `cp.expires_at > CURRENT_TIMESTAMP`,不再讓 `expires_at IS NULL` 的未知新鮮度舊配對壓住近門檻候選回刷。未知新鮮度仍由 expired identity refresh / recovery 路徑處理,最後寫入仍必須通過現行 matcher、hard-veto、auto write safety 與 stronger existing production match 保護。 diff --git a/services/marketplace_product_matcher.py b/services/marketplace_product_matcher.py index a27df00..95ec80a 100644 --- a/services/marketplace_product_matcher.py +++ b/services/marketplace_product_matcher.py @@ -713,6 +713,7 @@ VARIANT_OPTION_COLOR_WORDS = { "奶茶色", "豆沙色", "紫色", + "絕絕紫", "薰衣草", "藍色", "綠色", @@ -3180,7 +3181,7 @@ def _has_saugella_private_wash_variant_conflict(left: ProductIdentity, right: Pr and ("saugella" in right_text or "賽吉兒" in right_text) ): return False - variant_tokens = ("日用", "加強", "黃金女郎型") + variant_tokens = ("日用", "日用型", "加強", "潤澤", "黃金女郎型") left_hits = {token for token in variant_tokens if token in left_text} right_hits = {token for token in variant_tokens if token in right_text} return bool(left_hits and right_hits and left_hits.isdisjoint(right_hits)) diff --git a/tests/test_marketplace_product_matcher.py b/tests/test_marketplace_product_matcher.py index af7c76a..0546694 100644 --- a/tests/test_marketplace_product_matcher.py +++ b/tests/test_marketplace_product_matcher.py @@ -2085,6 +2085,7 @@ def test_marketplace_matcher_rejects_saugella_private_wash_variant_gap(): for momo_name in ( "【SAUGELLA 賽吉兒】菁萃潔浴凝露日用250ml二入組", "【SAUGELLA 賽吉兒】菁萃潔浴凝露加強250ml二入組", + "【SAUGELLA 賽吉兒】菁萃潔浴凝露潤澤二入組", ): diagnostics = score_marketplace_match( momo_name, @@ -2097,6 +2098,28 @@ def test_marketplace_matcher_rejects_saugella_private_wash_variant_gap(): assert diagnostics.comparison_mode == "not_comparable" assert "saugella_variant_conflict" in diagnostics.reasons + production_preview = score_marketplace_match( + "【SAUGELLA 賽吉兒】菁萃潔浴凝露潤澤二入組", + "《2入特惠》SAUGELLA賽吉兒 菁萃潔浴凝露【日用型】500ml", + ) + assert production_preview.hard_veto is True + assert "saugella_variant_conflict" in production_preview.reasons + + +def test_marketplace_matcher_keeps_mac_powder_single_shade_as_review(): + from services.competitor_price_feeder import _classify_low_score_attempt + from services.marketplace_product_matcher import score_marketplace_match + + diagnostics = score_marketplace_match( + "【M.A.C】超持妝輕透濾鏡蜜粉(國際航空版)", + "【M.A.C】超持妝輕透濾鏡蜜粉6.5g #絕絕紫", + ) + + assert diagnostics.score < 0.76 + assert diagnostics.hard_veto is False + assert "variant_selection_review" in diagnostics.reasons + assert _classify_low_score_attempt(diagnostics.score, diagnostics) == "true_low_confidence" + def test_marketplace_matcher_rejects_dr_hsieh_labsmart_vs_repair_serum_line_gap(): from services.marketplace_product_matcher import score_marketplace_match