feat: 数据治理 — 入库约束+元数据卡片+编码清洗+审计看板
This commit is contained in:
@@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user