feat(audit): Phase 11 告警操作完整溯源 — alert_operation_log + 歷史回填
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 1m29s
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 1m29s
統帥指令「所有告警訊息通通寫入資料庫,並記錄相關操作」 變更: - phase11_alert_operation_log.sql: 新表 (Event Sourcing,不可變) - phase11b_backfill_alert_operation_log.sql: 歷史回填 654 筆 - 14 筆 ALERT_RECEIVED (incidents) - 265 筆 TELEGRAM_SENT (approval_records) - 265 筆 USER_ACTION (approval_records) - 110 筆 EXECUTION_COMPLETED (audit_logs) - db/models.py: AlertOperationLog SQLAlchemy model - repositories/alert_operation_log_repository.py: append/list_by_incident/get_stats - webhooks.py: _try_auto_repair_background 寫入 AUTO_REPAIR_TRIGGERED + EXECUTION_COMPLETED + TELEGRAM_RESULT_SENT - webhooks.py: _push_to_telegram_background 寫入 TELEGRAM_SENT - telegram.py: handle_callback 寫入 USER_ACTION (approve/reject) 已執行 migration: awoooi_prod@192.168.0.188 ✅ Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -396,6 +396,54 @@ class AutoRepairExecution(Base):
|
||||
)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# AlertOperationLog - Phase 11 告警操作溯源 (Event Sourcing)
|
||||
# 2026-04-08 Claude Code: 統帥指令「所有操作都必須被記錄,寫入資料庫」
|
||||
# 不可變 — 只 INSERT,不 UPDATE/DELETE
|
||||
# =============================================================================
|
||||
|
||||
class AlertOperationLog(Base):
|
||||
"""
|
||||
告警操作完整溯源
|
||||
|
||||
Event Sourcing 模式:每個告警生命週期的每個事件都寫一筆。
|
||||
不可變 (Immutable)。
|
||||
|
||||
event_type 值:
|
||||
ALERT_RECEIVED / TELEGRAM_SENT / USER_ACTION /
|
||||
AUTO_REPAIR_TRIGGERED / EXECUTION_STARTED / EXECUTION_COMPLETED /
|
||||
TELEGRAM_RESULT_SENT / RESOLVED / SILENCED / ESCALATED
|
||||
"""
|
||||
__tablename__ = "alert_operation_log"
|
||||
|
||||
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=generate_uuid)
|
||||
|
||||
# 關聯 (允許 NULL,不同事件有不同關聯)
|
||||
incident_id: Mapped[str | None] = mapped_column(String(30), nullable=True, index=True)
|
||||
approval_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
|
||||
audit_log_id: Mapped[str | None] = mapped_column(String(36), nullable=True)
|
||||
auto_repair_id: Mapped[str | None] = mapped_column(String(36), nullable=True)
|
||||
|
||||
# 事件核心
|
||||
event_type: Mapped[str] = mapped_column(String(50), nullable=False, index=True)
|
||||
actor: Mapped[str | None] = mapped_column(String(100), nullable=True, index=True)
|
||||
action_detail: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
||||
|
||||
# 執行結果 (NULL = 不適用)
|
||||
success: Mapped[bool | None] = mapped_column(nullable=True)
|
||||
error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
|
||||
# 結構化上下文
|
||||
context: Mapped[dict] = mapped_column(JSON, default=dict, nullable=False)
|
||||
|
||||
# 時間戳 (台北時區,不可變)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=taipei_now)
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_aol_created_at", "created_at"),
|
||||
)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# IncidentRecord - Phase 6.2 Episodic Memory (PostgreSQL)
|
||||
# =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user