Files
prop-data-guard/backend/app/services/alert_service.py
T
hiderfong 6d70520e79 feat: 全量功能模块开发与集成测试修复
- 新增后端模块:Alert、APIAsset、Compliance、Lineage、Masking、Risk、SchemaChange、Unstructured、Watermark
- 新增前端模块页面与API接口
- 新增Alembic迁移脚本(002-014)覆盖全量业务表
- 新增测试数据生成脚本与集成测试脚本
- 修复metadata模型JSON类型导入缺失导致启动失败的问题
- 修复前端Alert/APIAsset页面request模块路径错误
- 更新docker-compose与开发计划文档
2026-04-25 08:51:38 +08:00

93 lines
3.4 KiB
Python

from typing import List, Optional
from sqlalchemy.orm import Session
from datetime import datetime
from app.models.alert import AlertRule, AlertRecord, WorkOrder
from app.models.project import ClassificationProject, ClassificationResult
from app.models.risk import RiskAssessment
def init_builtin_alert_rules(db: Session):
if db.query(AlertRule).first():
return
rules = [
AlertRule(name="L5字段数量突增", trigger_condition="l5_count", threshold=5, severity="high"),
AlertRule(name="项目风险分过高", trigger_condition="risk_score", threshold=80, severity="critical"),
AlertRule(name="Schema新增敏感字段", trigger_condition="schema_change", threshold=1, severity="medium"),
]
for r in rules:
db.add(r)
db.commit()
def check_alerts(db: Session) -> List[AlertRecord]:
"""Run alert checks and create records."""
rules = db.query(AlertRule).filter(AlertRule.is_active == True).all()
records = []
for rule in rules:
if rule.trigger_condition == "l5_count":
projects = db.query(ClassificationProject).all()
for p in projects:
l5_count = db.query(ClassificationResult).filter(
ClassificationResult.project_id == p.id,
ClassificationResult.level_id.isnot(None),
).join(ClassificationResult.level).filter(
ClassificationResult.level.has(code="L5")
).count()
if l5_count >= rule.threshold:
rec = AlertRecord(
rule_id=rule.id,
title=f"项目 {p.name} L5字段数量达到 {l5_count}",
content=f"阈值: {rule.threshold}",
severity=rule.severity,
)
db.add(rec)
records.append(rec)
elif rule.trigger_condition == "risk_score":
risks = db.query(RiskAssessment).filter(
RiskAssessment.entity_type == "project",
RiskAssessment.risk_score >= rule.threshold,
).all()
for rsk in risks:
rec = AlertRecord(
rule_id=rule.id,
title=f"项目 {rsk.entity_name} 风险分 {rsk.risk_score}",
content=f"阈值: {rule.threshold}",
severity=rule.severity,
)
db.add(rec)
records.append(rec)
db.commit()
return records
def create_work_order(db: Session, alert_id: int, title: str, description: str, assignee_id: Optional[int] = None) -> WorkOrder:
wo = WorkOrder(
alert_id=alert_id,
title=title,
description=description,
assignee_id=assignee_id,
)
db.add(wo)
db.commit()
db.refresh(wo)
return wo
def update_work_order_status(db: Session, wo_id: int, status: str, resolution: str = None) -> WorkOrder:
wo = db.query(WorkOrder).filter(WorkOrder.id == wo_id).first()
if wo:
wo.status = status
if resolution:
wo.resolution = resolution
if status == "resolved":
wo.resolved_at = datetime.utcnow()
# Also resolve linked alert
if wo.alert_id:
alert = db.query(AlertRecord).filter(AlertRecord.id == wo.alert_id).first()
if alert:
alert.status = "resolved"
db.commit()
db.refresh(wo)
return wo