From 915b8d061d69121cbecdb6a7b458e3da6efe8844 Mon Sep 17 00:00:00 2001 From: OoO Date: Mon, 1 Jun 2026 00:21:10 +0800 Subject: [PATCH] =?UTF-8?q?V10.523=20=E8=A3=9C=E5=AE=89=E5=85=A8=20exact?= =?UTF-8?q?=20=E5=90=8C=E6=AC=BE=E6=AF=94=E5=83=B9=E8=A6=8F=E5=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO_NEXT_STEPS.txt | 1 + config.py | 2 +- docs/memory/history_logs.md | 1 + services/marketplace_product_matcher.py | 70 +++++++++++++++++++++++ tests/test_marketplace_product_matcher.py | 50 ++++++++++++++++ 5 files changed, 123 insertions(+), 1 deletion(-) diff --git a/TODO_NEXT_STEPS.txt b/TODO_NEXT_STEPS.txt index 535d827..bfd7750 100644 --- a/TODO_NEXT_STEPS.txt +++ b/TODO_NEXT_STEPS.txt @@ -4,6 +4,7 @@ ================================================================================ 【已完成】 + - V10.523 補一批高分真同款 exact identity 比價規則:Beauty Foot 足膜、KAMERIA 積雪草足膜、TS6 蜜愛潤滑液 / 蜜桃煥白凝膠 / 極淨白+煥白組合、Vaseline 嬰兒高純修護凝膠在規格、入數、品牌與品線完全對齊時可進 `exact / total_price / price_alert_exact`,讓可用比價覆蓋增加;同時保留 TS6 香味衣物手洗精等 variant-sensitive 款式在 `manual_review`,不放寬全域門檻。 - V10.522 將 PChome 補抓狀態 API 接上 read-only coverage snapshot:`/api/ai/pchome-match/backfill/status` 會同步回傳身份覆蓋、新鮮率、待刷新與待補抓數,Dashboard 補抓產線即使沒有最近任務結果,也能直接判讀下一步該刷新過期價格或補抓未搜尋商品。 - V10.521 將比價新鮮度 stale 指標上屏:首頁 KPI / PChome 補抓產線 / daily / growth 都顯示價格過期數,讓操作員分清「已確認同款但價格待刷新」與「尚未找到身份配對」;過期 identity refresh 也優先刷新 `total_price / price_alert_exact` 的正式價差配對。 - V10.520 拆開過期價格刷新與搜尋救援:`run_expired_identity_refresh()` 只刷新既有 `identity_v2` PChome product_id,不再因少數 product_id 查不到或低分而同步進入慢速 `fresh_search_recovery`;缺失 / 低分候選交給 `run_retryable_candidate_revalidation()` 處理,避免正式刷新 500+ 筆時被外部搜尋拖死,讓價格新鮮度可以穩定批次回升。 diff --git a/config.py b/config.py index 4f61e1c..079f661 100644 --- a/config.py +++ b/config.py @@ -402,7 +402,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '') # ========================================== # 系統版本與路徑 # ========================================== -SYSTEM_VERSION = "V10.522" +SYSTEM_VERSION = "V10.523" 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 2b6db5e..895759c 100644 --- a/docs/memory/history_logs.md +++ b/docs/memory/history_logs.md @@ -13,6 +13,7 @@ ## 📅 詳細更新日誌 (考古存檔) ### 2026-06-01:PChome 比價新鮮度操作閉環 +- **V10.523 高分真同款 exact identity 比價規則補強**: 針對正式環境反覆出現、分數已達 1.0 但因 `multi_component_pair` 或 variant review gate 被留在人工審核的真同款,補 Beauty Foot 足膜、KAMERIA 積雪草足膜、TS6 蜜愛潤滑液 / 蜜桃煥白凝膠 / 極淨白+煥白組合、Vaseline 嬰兒高純修護凝膠 focused exact identity。這些案例只有在品牌、品線、容量 / 重量與入數完全對齊時才進 `exact / total_price / price_alert_exact`;TS6 香味衣物手洗精等款式敏感商品仍維持 `manual_review`,全域 `MIN_MATCH_SCORE` 與 overwrite 保護不變。 - **V10.522 PChome backfill status 附帶 coverage snapshot**: `/api/ai/pchome-match/backfill/status` 在背景任務狀態外同步回傳 read-only `fetch_competitor_coverage()` 摘要,包含身份覆蓋、新鮮率、過期價格與待補抓數;Dashboard 補抓產線即使尚無最近 run result,也會顯示「身份覆蓋 / 新鮮 / 待刷新 / 待補抓」,讓操作員能分辨下一步該跑 expired identity refresh 還是 unmatched backfill。此狀態端點不寫 DB、不呼叫 LLM、不抓外站。 ### 2026-05-31:Webcrumbs 共用 UI Runtime 與市場情報 writer approval diff --git a/services/marketplace_product_matcher.py b/services/marketplace_product_matcher.py index cf9680e..e9f3d1f 100644 --- a/services/marketplace_product_matcher.py +++ b/services/marketplace_product_matcher.py @@ -501,6 +501,12 @@ FOCUSED_IDENTITY_VARIANT_REVIEW_BYPASS_REASONS = { "physiogel_ai_ice_essence_200ml_2pack", "playjoy_powerman_male_care_30ml", "ts6_private_elastic_gel_40g", + "beauty_foot_mask_exact_pack", + "kameria_centella_foot_mask_17ml_2pc", + "ts6_lubricant_100g_3pack", + "ts6_peach_bright_gel_45g_3pack", + "ts6_white_wash_peach_gel_kit", + "vaseline_baby_jelly_368g_3pack", } FOCUSED_IDENTITY_BRANDLESS_REVIEW_REASONS = { @@ -535,6 +541,12 @@ FOCUSED_IDENTITY_TOTAL_PRICE_REASONS = { "physiogel_ai_ice_essence_200ml_2pack", "playjoy_powerman_male_care_30ml", "ts6_private_elastic_gel_40g", + "beauty_foot_mask_exact_pack", + "kameria_centella_foot_mask_17ml_2pc", + "ts6_lubricant_100g_3pack", + "ts6_peach_bright_gel_45g_3pack", + "ts6_white_wash_peach_gel_kit", + "vaseline_baby_jelly_368g_3pack", } SEARCH_BROAD_ANCHORS = { @@ -4031,6 +4043,64 @@ def _has_focused_low_score_exact_identity_line(left: ProductIdentity, right: Pro and _has_exact_count_alignment(left, right) ): return "ts6_white_mousse_180g_3pack" + if ( + {"ts6", "護一生"} & (left.brand_tokens & right.brand_tokens) + and "蜜愛潤滑液" in left_text + and "蜜愛潤滑液" in right_text + and _has_shared_weight(left, right, 100) + and _has_exact_count_alignment(left, right) + ): + return "ts6_lubricant_100g_3pack" + if ( + {"ts6", "護一生"} & (left.brand_tokens & right.brand_tokens) + and "蜜桃煥白凝膠" in left_text + and "蜜桃煥白凝膠" in right_text + and _has_shared_weight(left, right, 45) + and _has_exact_count_alignment(left, right) + ): + return "ts6_peach_bright_gel_45g_3pack" + if ( + {"ts6", "護一生"} & (left.brand_tokens & right.brand_tokens) + and "極淨白私密潔膚露" in left_text + and "極淨白私密潔膚露" in right_text + and "蜜桃煥白凝膠" in left_text + and "蜜桃煥白凝膠" in right_text + and _has_shared_weight(left, right, 250) + and _has_shared_weight(left, right, 45) + ): + return "ts6_white_wash_peach_gel_kit" + if ( + {"beauty", "foot"} <= (left.brand_tokens & right.brand_tokens) + and "足膜" in left_text + and "足膜" in right_text + and any(_has_shared_volume(left, right, volume) for volume in (25, 30)) + and _has_exact_count_alignment(left, right) + and not _is_multi_variant_catalog_listing(left) + and not _is_multi_variant_catalog_listing(right) + ): + return "beauty_foot_mask_exact_pack" + if ( + {"kameria", "凱蜜菈"} & (left.brand_tokens & right.brand_tokens) + and "足足稱奇" in left_text + and "足足稱奇" in right_text + and "積雪草" in left_text + and "積雪草" in right_text + and "足膜" in left_text + and "足膜" in right_text + and _has_shared_volume(left, right, 17) + and _has_exact_count_alignment(left, right) + and not _is_multi_variant_catalog_listing(left) + and not _is_multi_variant_catalog_listing(right) + ): + return "kameria_centella_foot_mask_17ml_2pc" + if ( + {"vaseline", "凡士林"} & (left.brand_tokens & right.brand_tokens) + and "嬰兒高純修護凝膠" in left_text + and "嬰兒高純修護凝膠" in right_text + and _has_shared_weight(left, right, 368) + and _has_exact_count_alignment(left, right) + ): + return "vaseline_baby_jelly_368g_3pack" if ( {"derma", "丹麥德瑪"} & (left.brand_tokens & right.brand_tokens) and "寶寶" in left_text diff --git a/tests/test_marketplace_product_matcher.py b/tests/test_marketplace_product_matcher.py index b4e2cbe..62c7a12 100644 --- a/tests/test_marketplace_product_matcher.py +++ b/tests/test_marketplace_product_matcher.py @@ -1168,6 +1168,41 @@ def test_marketplace_matcher_promotes_focused_manual_gate_exact_lines_to_total_p "TS6 護一生緊彈水嫩凝膠 40g", "focused_exact_identity_ts6_private_elastic_gel_40g", ), + ( + "【日本Beauty Foot】去角質足膜 25mlx2枚入(三入組)", + "【日本Beauty Foot 】煥膚足膜(25ml*2枚入)三入組", + "focused_exact_identity_beauty_foot_mask_exact_pack", + ), + ( + "【日本Beauty Foot】去角質足膜-大尺寸 30mlx2枚入(二入組)", + "【日本Beauty Foot 】煥膚足膜大尺寸(30ml*2枚入)二入組", + "focused_exact_identity_beauty_foot_mask_exact_pack", + ), + ( + "【KAMERIA】凱蜜菈 足足稱奇積雪草去皮嫩足膜(17ml*2枚入)", + "Kameria 足足稱奇 積雪草去皮嫩足膜 17MLX2枚入", + "focused_exact_identity_kameria_centella_foot_mask_17ml_2pc", + ), + ( + "【TS6 護一生】蜜愛潤滑液(100gx3入)", + "TS6護一生 蜜愛潤滑液(100g)X3入", + "focused_exact_identity_ts6_lubricant_100g_3pack", + ), + ( + "【TS6 護一生】蜜桃煥白凝膠-私密美白保養(45gx3入)", + "TS6護一生 蜜桃煥白凝膠 45gX3", + "focused_exact_identity_ts6_peach_bright_gel_45g_3pack", + ), + ( + "【TS6 護一生】極淨白私密潔膚露250g+蜜桃煥白凝膠45g(私密清潔 私密美白保養)", + "TS6護一生 極淨白私密潔膚露250g+蜜桃煥白凝膠45g", + "focused_exact_identity_ts6_white_wash_peach_gel_kit", + ), + ( + "【Vaseline 凡士林】官方直營 經典嬰兒高純修護凝膠368gx3入", + "Vaseline 凡士林經典嬰兒高純修護凝膠368g x3入", + "focused_exact_identity_vaseline_baby_jelly_368g_3pack", + ), ( "【DERMA 丹麥德瑪】寶寶有機水嫩洗髮沐浴露150ml", "丹麥DERMA 有機寶寶洗髮沐浴露150ml", @@ -1206,6 +1241,21 @@ def test_marketplace_matcher_promotes_focused_manual_gate_exact_lines_to_total_p assert expected_reason in diagnostics.reasons +def test_marketplace_matcher_keeps_ts6_scented_laundry_variant_in_review(): + from services.marketplace_product_matcher import score_marketplace_match + + diagnostics = score_marketplace_match( + "【TS6 護一生】私舒衣物手洗精(300gx3入)", + "TS6護一生 私舒衣物手洗精(絲絨玫瑰)300gX3", + ) + + assert diagnostics.hard_veto is False + assert diagnostics.score >= 0.76 + assert diagnostics.price_basis == "manual_review" + assert diagnostics.alert_tier == "identity_review" + assert "focused_exact_total_price_safe" not in diagnostics.reasons + + def test_marketplace_matcher_keeps_ambiguous_ts6_white_mousse_packaging_out_of_total_price(): from services.marketplace_product_matcher import score_marketplace_match