CI / Check (push) Has been skipped
CI / Detect Changes (push) Successful in 6s
CI / Deploy Agent (push) Successful in 4m8s
CI / Deploy Dashboard (push) Successful in 4m58s
CI / Deploy Docs (push) Has been skipped
CI / Deploy MCP (push) Has been skipped
90 lines
2.3 KiB
Rust
90 lines
2.3 KiB
Rust
use axum::Json;
|
|
use mongodb::bson::doc;
|
|
|
|
use super::dto::*;
|
|
use compliance_core::models::ScanRun;
|
|
use compliance_core::tenant_ctx::TenantCtx;
|
|
|
|
#[tracing::instrument(skip_all)]
|
|
pub async fn health() -> Json<serde_json::Value> {
|
|
Json(serde_json::json!({ "status": "ok" }))
|
|
}
|
|
|
|
#[tracing::instrument(skip_all)]
|
|
pub async fn stats_overview(
|
|
axum::extract::Extension(agent): AgentExt,
|
|
tenant: TenantCtx,
|
|
) -> ApiResult<OverviewStats> {
|
|
let db = tenant_db(&agent, &tenant).await?;
|
|
let db = &db;
|
|
|
|
let total_repositories = db
|
|
.repositories()
|
|
.count_documents(doc! {})
|
|
.await
|
|
.unwrap_or(0);
|
|
let total_findings = db.findings().count_documents(doc! {}).await.unwrap_or(0);
|
|
let critical_findings = db
|
|
.findings()
|
|
.count_documents(doc! { "severity": "critical" })
|
|
.await
|
|
.unwrap_or(0);
|
|
let high_findings = db
|
|
.findings()
|
|
.count_documents(doc! { "severity": "high" })
|
|
.await
|
|
.unwrap_or(0);
|
|
let medium_findings = db
|
|
.findings()
|
|
.count_documents(doc! { "severity": "medium" })
|
|
.await
|
|
.unwrap_or(0);
|
|
let low_findings = db
|
|
.findings()
|
|
.count_documents(doc! { "severity": "low" })
|
|
.await
|
|
.unwrap_or(0);
|
|
let total_sbom_entries = db
|
|
.sbom_entries()
|
|
.count_documents(doc! {})
|
|
.await
|
|
.unwrap_or(0);
|
|
let total_cve_alerts = db.cve_alerts().count_documents(doc! {}).await.unwrap_or(0);
|
|
let total_issues = db
|
|
.tracker_issues()
|
|
.count_documents(doc! {})
|
|
.await
|
|
.unwrap_or(0);
|
|
|
|
let recent_scans: Vec<ScanRun> = match db
|
|
.scan_runs()
|
|
.find(doc! {})
|
|
.sort(doc! { "started_at": -1 })
|
|
.limit(10)
|
|
.await
|
|
{
|
|
Ok(cursor) => collect_cursor_async(cursor).await,
|
|
Err(e) => {
|
|
tracing::warn!("Failed to fetch recent scans: {e}");
|
|
Vec::new()
|
|
}
|
|
};
|
|
|
|
Ok(Json(ApiResponse {
|
|
data: OverviewStats {
|
|
total_repositories,
|
|
total_findings,
|
|
critical_findings,
|
|
high_findings,
|
|
medium_findings,
|
|
low_findings,
|
|
total_sbom_entries,
|
|
total_cve_alerts,
|
|
total_issues,
|
|
recent_scans,
|
|
},
|
|
total: None,
|
|
page: None,
|
|
}))
|
|
}
|