Files
ewoooc/services/market_intel/write_approval_runbook.py
OoO bc900321f8
All checks were successful
CD Pipeline / deploy (push) Successful in 1m1s
feat(market-intel): add alert review queue migration blueprint
2026-05-18 19:51:36 +08:00

135 lines
5.0 KiB
Python
Raw Permalink 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.
"""市場情報正式寫入前的人工批准 runbook。
本模組只產生 gate 與操作順序,不建立 DB session、不執行 migration、不寫入資料。
"""
def _status_value(status, key, default=False):
return bool(getattr(status, key, default))
def build_write_approval_runbook(
*,
phase,
status,
schema_smoke,
seed_plan,
write_guard,
writer_plan,
):
"""建立正式 seed write 前的 read-only runbook。"""
gates = [
{
"key": "schema_smoke_passed",
"label": "ORM metadata smoke 已通過,八張 market_* table 與 market_platforms 欄位完整",
"passed": bool(schema_smoke.get("passed")),
},
{
"key": "backup_completed",
"label": "已在正式推版前執行 python backup_system.py",
"passed": False,
},
{
"key": "migration_file_reviewed",
"label": "market_* schema migration 已人工審核,且不 drop/alter 既有業績資料表",
"passed": False,
},
{
"key": "feature_flags_enabled_for_write_window",
"label": "寫入窗口才可同時啟用 MARKET_INTEL_ENABLED 與 MARKET_INTEL_WRITE_ENABLED",
"passed": bool(_status_value(status, "enabled") and _status_value(status, "write_enabled")),
},
{
"key": "database_write_allowed",
"label": "runtime database_write_allowed 為 true",
"passed": bool(_status_value(status, "database_write_allowed")),
},
{
"key": "manual_operator_approval",
"label": "操作者已明確批准一次性 market_platforms seed upsert",
"passed": False,
},
{
"key": "rollback_plan_reviewed",
"label": "已確認回復策略:關閉 flags、app-only rollback、必要時清理 seed rows",
"passed": False,
},
{
"key": "production_smoke_targets_defined",
"label": "已定義 /health 與市場情報 API smoke targets",
"passed": True,
},
]
blocked_reasons = [gate["key"] for gate in gates if not gate["passed"]]
return {
"phase": phase,
"mode": "approval_runbook_read_only",
"ready_for_real_write": False,
"writes_executed": False,
"would_write_database": False,
"database_session_created": False,
"database_commit_executed": False,
"external_network_executed": False,
"scheduler_attached": False,
"approval_required": True,
"approval_token_present": False,
"blocked_reasons": blocked_reasons,
"approval_gates": gates,
"seed_count": int(seed_plan.get("seed_count") or 0),
"writer_operation_count": int(writer_plan.get("operation_count") or 0),
"schema_smoke": schema_smoke,
"write_guard_summary": {
"ready_to_write": bool(write_guard.get("ready_to_write")),
"would_write_database": bool(write_guard.get("would_write_database")),
"blocked_reasons": write_guard.get("blocked_reasons", []),
},
"operator_sequence": [
{
"key": "scope_review",
"label": "確認 git diff 只包含 market_intel、ADR/TODO、版本與測試",
},
{
"key": "backup",
"label": "執行 python backup_system.py保存正式環境回復點",
},
{
"key": "migration_apply_window",
"label": "在維護窗口套用 market_* migration不觸碰 momo-db 容器生命週期",
},
{
"key": "seed_preview_compare",
"label": "比對 platform_seed_writer_plan 的 4 筆 upsert preview",
},
{
"key": "one_time_seed_write",
"label": "另開明確批准後才允許一次性 seed writer 真寫入",
},
{
"key": "post_write_smoke",
"label": "驗證 /health、/market_intel、schema_smoke 與 deployment_readiness",
},
],
"rollback_plan": [
{
"key": "disable_flags",
"label": "立刻關閉 MARKET_INTEL_ENABLED、MARKET_INTEL_CRAWLER_ENABLED、MARKET_INTEL_WRITE_ENABLED",
},
{
"key": "app_only_rollback",
"label": "回退 momo-app 程式版本,只 recreate momo-app不碰 momo-db",
},
{
"key": "seed_rows_cleanup",
"label": "若唯一異常來自 platform seed可在人工審核後刪除或停用 market_platforms seed rows",
},
],
"hard_safety_boundaries": [
"no_external_crawling_during_seed_write",
"no_scheduler_attach_during_seed_write",
"no_momo_db_container_lifecycle_change",
"no_remove_orphans",
"health_probe_uses_health_endpoint_only",
],
}