feat: 数据治理 — 入库约束+元数据卡片+编码清洗+审计看板

This commit is contained in:
Hermes CI Fix
2026-07-22 12:06:52 +08:00
parent ec6af751a5
commit 748c2da43f
8 changed files with 452 additions and 2 deletions
+62
View File
@@ -253,10 +253,72 @@ def quality_stats(db: Session = Depends(get_db)):
if cnt:
type_counts[t] = cnt
# ── 数据审计看板统计 ──
# KPI完整度评分
all_kpis = db.query(KPIDefinition).filter(KPIDefinition.status == "active").all()
total = len(all_kpis)
complete_kpis = 0
missing_metadata_count = 0
missing_data_count = 0
stale_data_count = 0
from datetime import datetime, timedelta
six_months_ago = datetime.now() - timedelta(days=180)
for kpi in all_kpis:
# 元数据完整度检查
has_meta = all([
kpi.formula and kpi.formula.strip(),
kpi.data_source and kpi.data_source.strip(),
kpi.data_owner and kpi.data_owner.strip(),
kpi.unit and kpi.unit.strip(),
kpi.target_value is not None,
])
if has_meta:
complete_kpis += 1
else:
missing_metadata_count += 1
# 数据缺失检查(是否有实际值)
val = db.query(KPIValue).filter(
KPIValue.kpi_id == kpi.id,
KPIValue.actual_value.isnot(None),
).first()
if not val:
missing_data_count += 1
# 超30天未更新预警
latest_val = db.query(KPIValue).filter(
KPIValue.kpi_id == kpi.id,
KPIValue.actual_value.isnot(None),
).order_by(KPIValue.period.desc()).first()
if latest_val and latest_val.calculated_at:
if latest_val.calculated_at < six_months_ago:
stale_data_count += 1
completeness_score = round(complete_kpis / total * 100, 1) if total > 0 else 0
missing_rate = round(missing_data_count / total * 100, 1) if total > 0 else 0
return {
"total_kpis": total_kpis,
"total_logs": total_logs,
"open_logs": open_logs,
"severity_counts": severity_counts,
"type_counts": type_counts,
# 数据审计看板
"completeness": {
"score": completeness_score,
"complete": complete_kpis,
"total": total,
"missing_metadata": missing_metadata_count,
},
"data_missing": {
"count": missing_data_count,
"rate": missing_rate,
"total": total,
},
"stale_data": {
"count": stale_data_count,
"threshold_days": 180,
},
}