fix(cma): entity isolation batch2 (roll-forward/check-timeout/by-id/cost-abc)
ci/woodpecker/push/main Pipeline failed

Scope: backend/app/api/{alerts,action_plans,budget,cost}.py + tests

Task: 0-P1-project-20260918-entity-isolation-batch2
This commit is contained in:
Hermes CI Fix
2026-09-18 18:15:22 +08:00
parent b9c80f836e
commit ad953ac759
5 changed files with 467 additions and 24 deletions
+17 -12
View File
@@ -45,9 +45,10 @@ def resolve_alert(alert_id: int, data: dict, db: Session = Depends(get_db), enti
@router.post("/{alert_id}/process")
def process_alert(alert_id: int, data: dict, db: Session = Depends(get_db)):
"""标记预警为处理中"""
alert = db.query(KPIAlert).filter(KPIAlert.id == alert_id).first()
def process_alert(alert_id: int, data: dict, db: Session = Depends(get_db), entity_id: int = Depends(get_entity_id)):
"""标记预警为处理中(账套隔离: join kpi_definitions 按企业过滤, 2026-09-18)"""
alert = db.query(KPIAlert).join(KPIDefinition, KPIDefinition.id == KPIAlert.kpi_id).filter(
KPIAlert.id == alert_id, KPIDefinition.entity_id == entity_id).first()
if not alert:
raise HTTPException(404, "预警不存在")
if alert.status == "resolved":
@@ -63,9 +64,10 @@ def process_alert(alert_id: int, data: dict, db: Session = Depends(get_db)):
@router.post("/{alert_id}/escalate")
def escalate_alert(alert_id: int, data: dict, db: Session = Depends(get_db)):
"""升级预警级别"""
alert = db.query(KPIAlert).filter(KPIAlert.id == alert_id).first()
def escalate_alert(alert_id: int, data: dict, db: Session = Depends(get_db), entity_id: int = Depends(get_entity_id)):
"""升级预警级别(账套隔离: join kpi_definitions 按企业过滤, 2026-09-18)"""
alert = db.query(KPIAlert).join(KPIDefinition, KPIDefinition.id == KPIAlert.kpi_id).filter(
KPIAlert.id == alert_id, KPIDefinition.entity_id == entity_id).first()
if not alert:
raise HTTPException(404, "预警不存在")
assignee = data.get("assignee")
@@ -82,11 +84,13 @@ def escalate_alert(alert_id: int, data: dict, db: Session = Depends(get_db)):
@router.get("/check-timeout")
def check_alert_timeout(db: Session = Depends(get_db)):
"""超时预警检测 — 超过24小时未处理的pending预警自动升级为红色"""
def check_alert_timeout(db: Session = Depends(get_db), entity_id: int = Depends(get_entity_id)):
"""超时预警检测 — 超过24小时未处理的pending预警自动升级为红色
(账套隔离: join kpi_definitions 按企业过滤, 2026-09-18 — 原为全账套批处理)"""
from datetime import datetime, timedelta
cutoff = datetime.now() - timedelta(hours=24)
timeout_alerts = db.query(KPIAlert).filter(
timeout_alerts = db.query(KPIAlert).join(KPIDefinition, KPIDefinition.id == KPIAlert.kpi_id).filter(
KPIDefinition.entity_id == entity_id,
KPIAlert.status == "pending",
KPIAlert.created_at < cutoff,
KPIAlert.alert_level != "red",
@@ -102,9 +106,10 @@ def check_alert_timeout(db: Session = Depends(get_db)):
@router.post("/{alert_id}/create-action-plan")
def create_action_plan_from_alert(alert_id: int, data: dict, db: Session = Depends(get_db)):
"""从预警创建改善行动计划"""
alert = db.query(KPIAlert).filter(KPIAlert.id == alert_id).first()
def create_action_plan_from_alert(alert_id: int, data: dict, db: Session = Depends(get_db), entity_id: int = Depends(get_entity_id)):
"""从预警创建改善行动计划(账套隔离: join kpi_definitions 按企业过滤, 2026-09-18)"""
alert = db.query(KPIAlert).join(KPIDefinition, KPIDefinition.id == KPIAlert.kpi_id).filter(
KPIAlert.id == alert_id, KPIDefinition.entity_id == entity_id).first()
if not alert:
raise HTTPException(404, "预警不存在")
if alert.action_plan_linked_id: