From d60cb54c0885704e605d71c06cdc2a53ac85c2cb Mon Sep 17 00:00:00 2001 From: OG T Date: Mon, 23 Mar 2026 22:31:18 +0800 Subject: [PATCH] =?UTF-8?q?fix(api):=20resolve=5Fincident=5Fafter=5Fapprov?= =?UTF-8?q?al=20=E4=BD=BF=E7=94=A8=E7=9B=B4=E6=8E=A5=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=82=8F=E8=BC=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原因: 透過 _persist_incident 間接更新失敗 修復: 改用直接 Redis + DB 更新 (與 debug endpoint 相同邏輯) Co-Authored-By: Claude Opus 4.5 --- apps/api/src/services/proposal_service.py | 97 ++++++++++++++--------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/apps/api/src/services/proposal_service.py b/apps/api/src/services/proposal_service.py index 905b9246..20390644 100644 --- a/apps/api/src/services/proposal_service.py +++ b/apps/api/src/services/proposal_service.py @@ -531,58 +531,79 @@ class ProposalService: Returns: 是否更新成功 """ + from sqlalchemy import select + logger.info( "resolve_incident_starting", incident_id=incident_id, approval_id=approval_id, ) + redis_client = get_redis() + key = f"{INCIDENT_KEY_PREFIX}{incident_id}" + redis_ok = False + db_ok = False + + # 1. 更新 Redis try: - incident = await self._load_incident(incident_id) - if not incident: - logger.warning( - "resolve_incident_not_found", + data = await redis_client.get(key) + if data: + incident = Incident.model_validate_json(data) + old_status = incident.status.value + incident.status = IncidentStatus.RESOLVED + incident.updated_at = datetime.now(timezone.utc) + if incident.decision: + incident.decision.state = "completed" + await redis_client.set(key, incident.model_dump_json(), ex=604800) + redis_ok = True + logger.info( + "resolve_incident_redis_updated", incident_id=incident_id, - approval_id=approval_id, + old_status=old_status, + new_status="resolved", ) - return False - - logger.info( - "resolve_incident_loaded", - incident_id=incident_id, - current_status=incident.status.value, - ) - - # 更新狀態 - old_status = incident.status - incident.status = IncidentStatus.RESOLVED - incident.updated_at = datetime.now(timezone.utc) - - # 更新 decision.state (如果有) - if incident.decision: - incident.decision.state = "completed" - - # 持久化 - await self._persist_incident(incident) - - logger.info( - "incident_resolved_after_approval", - incident_id=incident_id, - approval_id=approval_id, - old_status=old_status.value, - new_status="resolved", - ) - - return True - except Exception as e: logger.exception( - "resolve_incident_error", + "resolve_incident_redis_error", incident_id=incident_id, - approval_id=approval_id, error=str(e), ) - return False + + # 2. 更新 DB + try: + async with get_db_context() as db: + stmt = select(IncidentRecord).where( + IncidentRecord.incident_id == incident_id + ) + result = await db.execute(stmt) + record = result.scalar_one_or_none() + if record: + record.status = "resolved" + record.updated_at = datetime.now(timezone.utc) + await db.commit() + db_ok = True + logger.info( + "resolve_incident_db_updated", + incident_id=incident_id, + ) + except Exception as e: + logger.exception( + "resolve_incident_db_error", + incident_id=incident_id, + error=str(e), + ) + + success = redis_ok and db_ok + logger.info( + "resolve_incident_completed", + incident_id=incident_id, + approval_id=approval_id, + success=success, + redis_ok=redis_ok, + db_ok=db_ok, + ) + + return success # =============================================================================