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:
hiderfong
2026-04-25 08:51:38 +08:00
parent 8b2bc84399
commit 6d70520e79
110 changed files with 6125 additions and 87 deletions
+92
View File
@@ -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