fix(api): tolerate legacy incident outcomes
All checks were successful
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / tests (push) Successful in 1m16s
CD Pipeline / build-and-deploy (push) Successful in 4m35s
CD Pipeline / post-deploy-checks (push) Successful in 1m47s

This commit is contained in:
Your Name
2026-05-19 12:07:38 +08:00
parent 3514ff38fe
commit db4fa420ea
3 changed files with 67 additions and 7 deletions

View File

@@ -528,6 +528,32 @@ def parse_decision_chain(value: Any, incident_id: str | None = None):
return None
def parse_incident_outcome(value: Any, incident_id: str | None = None):
"""Best-effort restore of legacy outcome payloads from PostgreSQL."""
if not value:
return None
from src.models.incident import IncidentOutcome
if not isinstance(value, dict):
logger.warning(
"legacy_incident_outcome_skipped",
incident_id=incident_id,
value_type=type(value).__name__,
)
return None
try:
return IncidentOutcome(**value)
except Exception as exc:
logger.warning(
"incident_outcome_parse_failed",
incident_id=incident_id,
error=str(exc),
)
return None
# =============================================================================
# Constants
# =============================================================================
@@ -816,8 +842,6 @@ class IncidentService:
方案 C: 解析時正規化舊格式 Enum 值
"""
from src.models.incident import IncidentOutcome
# 方案 C: 正規化 signals 內的舊格式 severity
signals = []
for s in (record.signals or []):
@@ -830,10 +854,9 @@ class IncidentService:
record.decision_chain,
incident_id=record.incident_id,
)
outcome = (
IncidentOutcome(**record.outcome)
if record.outcome
else None
outcome = parse_incident_outcome(
record.outcome,
incident_id=record.incident_id,
)
# 方案 C: 正規化舊格式 Enum 值
@@ -1234,7 +1257,7 @@ class IncidentService:
timeout=_effective_timeout,
)
break # 成功,離開 retry loop
except asyncio.TimeoutError:
except TimeoutError:
logger.warning(
"km_conversion_timeout",
incident_id=incident_id,