Files
ewoooc/services/market_intel/opportunity_plan.py
ogt 0a7bdd819b
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
清除市場情報受控套用剩餘人工語意
2026-07-01 13:53:46 +08:00

146 lines
5.4 KiB
Python

"""市場情報機會與威脅判讀 preview。
只定義未來 opportunity / threat scoring 規則;不建立 queue、不寫 DB、
不派送 Telegram、不產生 AI 報告。
"""
from services.market_intel.ai_controlled_service_compat import compatibility_flag
OPPORTUNITY_RULES = (
{
"key": "competitor_price_threat",
"label": "競品活動價低於 MOMO 參考價",
"severity": "high",
"requires_confirmed_match": True,
"minimum_evidence": [
"confirmed_or_reviewed_match",
"current_market_price",
"momo_reference_price",
],
"action_hint": "進入價格威脅審核,不自動調價。",
},
{
"key": "promotion_gap",
"label": "競品有強促銷但我方未跟活動",
"severity": "medium",
"requires_confirmed_match": True,
"minimum_evidence": [
"active_competitor_campaign",
"confirmed_match",
"momo_campaign_absent_or_weaker",
],
"action_hint": "標記為活動缺口,交由 AI 例外決策是否跟進。",
},
{
"key": "deep_discount_overlap",
"label": "同品或近似品出現深折重疊",
"severity": "medium",
"requires_confirmed_match": False,
"minimum_evidence": [
"needs_review_match_score_above_threshold",
"discount_rate_over_threshold",
"campaign_context",
],
"action_hint": "送入商品比對審核,不直接派送威脅告警。",
},
{
"key": "campaign_ending_watch",
"label": "高折扣活動即將結束",
"severity": "low",
"requires_confirmed_match": False,
"minimum_evidence": [
"campaign_end_at",
"recent_price_snapshot",
"discount_or_coupon_signal",
],
"action_hint": "排入觀察清單,避免過期活動持續推播。",
},
)
_OPERATOR_APPROVAL_COMPAT_KEY = compatibility_flag("operator_approval")
def build_opportunity_plan_preview(
*,
runtime_status,
match_review_plan,
scheduler_plan,
legacy_source_bridge,
):
"""建立市場機會與威脅判讀計畫;不執行任何推播或寫入。"""
legacy_bridge_safe = (
legacy_source_bridge.get("mode") == "legacy_source_bridge_planned"
and not legacy_source_bridge.get("read_only_query_executed")
and not legacy_source_bridge.get("database_write_executed")
)
scheduler_safe = (
scheduler_plan.get("mode") == "scheduler_attach_plan_preview"
and not scheduler_plan.get("scheduler_registration_executed")
and not scheduler_plan.get("crawler_job_started")
)
match_review_safe = (
match_review_plan.get("mode") == "match_review_plan_preview"
and not match_review_plan.get("auto_confirm_executed")
and not match_review_plan.get("database_write_executed")
)
gate_checks = {
"match_review_plan_present": match_review_plan.get("mode")
== "match_review_plan_preview",
"match_review_candidates_available": bool(
match_review_plan.get("ready_for_review_queue")
),
"auto_confirm_disabled": not bool(
(match_review_plan.get("thresholds") or {}).get("auto_confirm_enabled")
),
"scheduler_plan_preview_safe": scheduler_safe,
"legacy_bridge_planned_safe": legacy_bridge_safe,
"database_write_still_blocked": not bool(
runtime_status.database_write_allowed
),
"match_review_preview_safe": match_review_safe,
_OPERATOR_APPROVAL_COMPAT_KEY: False,
}
blocked_reasons = [
key for key, passed in gate_checks.items()
if not passed
]
return {
"mode": "opportunity_plan_preview",
"ready_for_opportunity_queue": False,
"opportunity_queue_created": False,
"threat_alert_dispatched": False,
"telegram_dispatched": False,
"ai_summary_generated": False,
"database_session_created": False,
"database_write_executed": False,
"database_commit_executed": False,
"external_network_executed": False,
"scheduler_attached": False,
"writes_executed": False,
"would_write_database": False,
"rule_count": len(OPPORTUNITY_RULES),
"rules": list(OPPORTUNITY_RULES),
"gate_checks": gate_checks,
"blocked_reasons": blocked_reasons,
"severity_policy": {
"high": "只建立 AI 例外決策項,不自動調價、不直接派送高頻告警。",
"medium": "進入日報摘要或審核清單,需 confirmed match 才能升級。",
"low": "只做觀察,不觸發即時通知。",
},
"operator_sequence": [
"先完成商品比對審核,至少取得 confirmed 或 needs_review 高信心候選",
"用 campaign / price history 計算威脅與機會分數",
"高風險項先進 AI 例外決策清單,不直接派送 Telegram",
"AI 自動驗證確認後才允許進入 OpenClaw / Hermes 摘要",
"所有 AI 摘要必須附上 DB evidence id 與規則 key",
],
"safe_boundaries": [
"do_not_dispatch_alerts_from_preview",
"do_not_generate_ai_summary_from_preview",
"do_not_auto_adjust_price",
"do_not_escalate_without_confirmed_match",
"do_not_write_opportunity_queue_from_preview",
],
}