Files
ewoooc/services/market_intel/manual_sample_candidate_queue.py
OoO f6d34628f6
All checks were successful
CD Pipeline / deploy (push) Successful in 1m4s
新增市場情報候選審核佇列草案
2026-05-19 01:05:27 +08:00

149 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""市場情報人工候選審核 queue 草案預覽。
本模組只把 sample result handoff 轉成 review queue draft
不建立正式 queue、不寫 DB、不掛 scheduler、不連外。
"""
from services.market_intel.manual_sample_review import (
build_manual_sample_candidate_handoff_preview,
)
def _priority_for_candidate(candidate):
band = str(candidate.get("confidence_band") or "").lower()
if band == "high":
return 80
if band == "medium":
return 50
return 20
def _build_queue_item(candidate, batch_id):
candidate_key = str(candidate.get("candidate_key") or "")
return {
"queue_item_key": f"review:{candidate_key}",
"candidate_key": candidate_key,
"platform_code": str(candidate.get("platform_code") or ""),
"candidate_url": str(candidate.get("candidate_url") or ""),
"candidate_text": str(candidate.get("candidate_text") or ""),
"confidence_band": str(candidate.get("confidence_band") or "unknown"),
"score": candidate.get("score") or 0,
"rank_position": candidate.get("rank_position") or 0,
"review_state": "needs_review",
"review_priority": _priority_for_candidate(candidate),
"created_from_batch_id": batch_id,
"write_status": "blocked_preview_only",
"approval_required": True,
}
def build_manual_sample_candidate_queue_draft_preview(
*,
runtime_status,
acceptance_contract,
sample_result=None,
payload_error=None,
limit=20,
):
"""建立候選活動人工審核 queue 草案;只回 preview不保存。"""
handoff = build_manual_sample_candidate_handoff_preview(
runtime_status=runtime_status,
acceptance_contract=acceptance_contract,
sample_result=sample_result,
payload_error=payload_error,
limit=limit,
)
batch_id = ""
if isinstance(sample_result, dict):
batch_id = str(sample_result.get("batch_id") or "")
queue_items = [
_build_queue_item(candidate, batch_id)
for candidate in handoff.get("candidates", [])
]
queue_draft_ready = bool(handoff.get("handoff_ready") and queue_items)
blocked_reasons = list(handoff.get("blocked_reasons", []))
if not queue_draft_ready:
blocked_reasons.append("review_queue_draft_not_ready")
blocked_reasons.append("review_queue_persist_still_blocked")
return {
"mode": "manual_sample_candidate_queue_draft_preview",
"handoff": {
"mode": handoff["mode"],
"handoff_ready": handoff["handoff_ready"],
"candidate_handoff_created": handoff["candidate_handoff_created"],
"candidate_handoff_persisted": handoff["candidate_handoff_persisted"],
"handoff_summary": handoff["handoff_summary"],
},
"payload_received": handoff["payload_received"],
"payload_valid_json_object": handoff["payload_valid_json_object"],
"payload_error": handoff["payload_error"],
"payload_persisted": False,
"sample_result_persisted": False,
"handoff_ready": handoff["handoff_ready"],
"queue_draft_ready": queue_draft_ready,
"review_queue_draft_created": bool(queue_items),
"review_queue_created": False,
"review_queue_persisted": False,
"candidate_import_allowed": False,
"scheduler_attached": False,
"external_network_executed": False,
"database_connection_opened": False,
"database_session_created": False,
"database_write_executed": False,
"database_commit_executed": False,
"writes_executed": False,
"would_write_database": False,
"blocked_reasons": blocked_reasons,
"queue_summary": {
"queue_item_count": len(queue_items),
"review_queue_created": False,
"queue_persisted": False,
"import_allowed": False,
},
"queue_contract": {
"contract_type": "draft_contract_only",
"table_name": "market_campaign_candidate_review_queue",
"required_fields": [
"queue_item_key",
"candidate_key",
"platform_code",
"candidate_url",
"candidate_text",
"confidence_band",
"score",
"review_state",
"review_priority",
"created_from_batch_id",
],
"forbidden_actions": [
"insert_review_queue_rows",
"auto_approve_candidates",
"insert_market_campaigns",
"attach_scheduler_jobs",
],
},
"queue_items": queue_items,
"operator_next_actions": [
{
"key": "review_queue_draft_manually",
"label": "人工確認候選 URL、分數與優先序後才可提出正式 queue 建立申請",
"write_status": "blocked",
},
{
"key": "approve_queue_persistence_later",
"label": "正式寫入候選審核 queue 需要另一次明確批准與 DB 備援檢查",
"write_status": "blocked",
},
],
"safe_boundaries": [
*handoff["safe_boundaries"],
"do_not_create_candidate_review_queue_from_preview",
"do_not_persist_candidate_review_queue_draft",
"do_not_write_market_tables_from_queue_draft",
"do_not_auto_approve_candidates",
"do_not_attach_scheduler_from_queue_draft",
"do_not_touch_momo_db_lifecycle",
],
}