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