fix(incidents): bind durable readback tenant context

This commit is contained in:
ogt
2026-07-11 20:10:17 +08:00
parent 476c6a6315
commit ca5ed596dc
6 changed files with 79 additions and 18 deletions

View File

@@ -155,6 +155,12 @@ class IncidentTimelineResponse(BaseModel):
""",
)
async def list_incidents(
project_id: str = Query(
"awoooi",
min_length=1,
max_length=64,
description="租戶 IDlegacy incident surface 預設綁定 awoooi。",
),
generate_missing_decisions: bool = Query(
False,
description=(
@@ -180,7 +186,9 @@ async def list_incidents(
try:
# 透過 Service 取得活躍事件
incidents = await incident_service.get_active_incidents()
incidents = await incident_service.get_active_incidents(
project_id=project_id,
)
# 按時間排序 (最新優先)
# 2026-03-26 修復: 處理 timezone-aware 與 naive datetime 混合問題
@@ -289,7 +297,15 @@ async def list_incidents(
summary="取得單一事件",
description="取得特定事件的詳細資訊。",
)
async def get_incident(incident_id: str) -> IncidentResponse:
async def get_incident(
incident_id: str,
project_id: str = Query(
"awoooi",
min_length=1,
max_length=64,
description="租戶 IDlegacy incident surface 預設綁定 awoooi。",
),
) -> IncidentResponse:
"""
取得單一事件
@@ -306,7 +322,10 @@ async def get_incident(incident_id: str) -> IncidentResponse:
incident_service = get_incident_service()
try:
incident = await incident_service.get_for_readback(incident_id)
incident = await incident_service.get_for_readback(
incident_id,
project_id=project_id,
)
if incident is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,

View File

@@ -168,13 +168,13 @@ class IncidentDBRepository(IIncidentRepository):
record = result.scalar_one_or_none()
return _record_to_incident(record) if record else None
async def get_active(self) -> list[Incident]:
async def get_active(self, *, project_id: str | None = None) -> list[Incident]:
"""取得所有活躍的 Incident"""
active_statuses = [
IncidentStatus.INVESTIGATING,
IncidentStatus.MITIGATING,
]
async with get_db_context() as db:
async with get_db_context(project_id) as db:
result = await db.execute(
select(IncidentRecord)
.where(IncidentRecord.status.in_(active_statuses))

View File

@@ -125,7 +125,11 @@ class IIncidentRepository(Protocol):
"""根據 ID 取得 Incident"""
...
async def get_active(self) -> list[Incident]:
async def get_active(
self,
*,
project_id: str | None = None,
) -> list[Incident]:
"""取得所有活躍的 Incident"""
...

View File

@@ -730,9 +730,17 @@ class IncidentService:
)
return "updated"
async def get_for_readback(self, incident_id: str) -> Incident | None:
async def get_for_readback(
self,
incident_id: str,
*,
project_id: str | None = None,
) -> Incident | None:
"""Return durable incident truth, with Redis as an availability fallback."""
incident = await self.get_from_episodic_memory(incident_id)
incident = await self.get_from_episodic_memory(
incident_id,
project_id=project_id,
)
if incident is not None:
return incident
@@ -742,7 +750,11 @@ class IncidentService:
)
return await self.get_from_working_memory(incident_id)
async def get_active_incidents(self) -> list[Incident]:
async def get_active_incidents(
self,
*,
project_id: str | None = None,
) -> list[Incident]:
"""
列出所有活躍的 Incidents。
@@ -755,7 +767,9 @@ class IncidentService:
try:
from src.repositories.incident_repository import get_incident_repository
incidents = await get_incident_repository().get_active()
incidents = await get_incident_repository().get_active(
project_id=project_id,
)
logger.info(
"get_active_incidents_from_episodic_memory",
count=len(incidents),