feat: 全量功能模块开发与集成测试修复
- 新增后端模块:Alert、APIAsset、Compliance、Lineage、Masking、Risk、SchemaChange、Unstructured、Watermark - 新增前端模块页面与API接口 - 新增Alembic迁移脚本(002-014)覆盖全量业务表 - 新增测试数据生成脚本与集成测试脚本 - 修复metadata模型JSON类型导入缺失导致启动失败的问题 - 修复前端Alert/APIAsset页面request模块路径错误 - 更新docker-compose与开发计划文档
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
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
|
||||
Reference in New Issue
Block a user