Add DAST, graph modules, toast notifications, and dashboard enhancements
Add DAST scanning and code knowledge graph features across the stack: - compliance-dast and compliance-graph workspace crates - Agent API handlers and routes for DAST targets/scans and graph builds - Core models and traits for DAST and graph domains - Dashboard pages for DAST targets/findings/overview and graph explorer/impact - Toast notification system with auto-dismiss for async action feedback - Button click animations and disabled states for better UX Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -88,6 +88,70 @@ impl Database {
|
||||
)
|
||||
.await?;
|
||||
|
||||
// graph_nodes: compound (repo_id, graph_build_id)
|
||||
self.graph_nodes()
|
||||
.create_index(
|
||||
IndexModel::builder()
|
||||
.keys(doc! { "repo_id": 1, "graph_build_id": 1 })
|
||||
.build(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// graph_edges: compound (repo_id, graph_build_id)
|
||||
self.graph_edges()
|
||||
.create_index(
|
||||
IndexModel::builder()
|
||||
.keys(doc! { "repo_id": 1, "graph_build_id": 1 })
|
||||
.build(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// graph_builds: compound (repo_id, started_at DESC)
|
||||
self.graph_builds()
|
||||
.create_index(
|
||||
IndexModel::builder()
|
||||
.keys(doc! { "repo_id": 1, "started_at": -1 })
|
||||
.build(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// impact_analyses: unique (repo_id, finding_id)
|
||||
self.impact_analyses()
|
||||
.create_index(
|
||||
IndexModel::builder()
|
||||
.keys(doc! { "repo_id": 1, "finding_id": 1 })
|
||||
.options(IndexOptions::builder().unique(true).build())
|
||||
.build(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// dast_targets: index on repo_id
|
||||
self.dast_targets()
|
||||
.create_index(
|
||||
IndexModel::builder()
|
||||
.keys(doc! { "repo_id": 1 })
|
||||
.build(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// dast_scan_runs: compound (target_id, started_at DESC)
|
||||
self.dast_scan_runs()
|
||||
.create_index(
|
||||
IndexModel::builder()
|
||||
.keys(doc! { "target_id": 1, "started_at": -1 })
|
||||
.build(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// dast_findings: compound (scan_run_id, vuln_type)
|
||||
self.dast_findings()
|
||||
.create_index(
|
||||
IndexModel::builder()
|
||||
.keys(doc! { "scan_run_id": 1, "vuln_type": 1 })
|
||||
.build(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
tracing::info!("Database indexes ensured");
|
||||
Ok(())
|
||||
}
|
||||
@@ -116,8 +180,43 @@ impl Database {
|
||||
self.inner.collection("tracker_issues")
|
||||
}
|
||||
|
||||
// Graph collections
|
||||
pub fn graph_nodes(&self) -> Collection<compliance_core::models::graph::CodeNode> {
|
||||
self.inner.collection("graph_nodes")
|
||||
}
|
||||
|
||||
pub fn graph_edges(&self) -> Collection<compliance_core::models::graph::CodeEdge> {
|
||||
self.inner.collection("graph_edges")
|
||||
}
|
||||
|
||||
pub fn graph_builds(&self) -> Collection<compliance_core::models::graph::GraphBuildRun> {
|
||||
self.inner.collection("graph_builds")
|
||||
}
|
||||
|
||||
pub fn impact_analyses(&self) -> Collection<compliance_core::models::graph::ImpactAnalysis> {
|
||||
self.inner.collection("impact_analyses")
|
||||
}
|
||||
|
||||
// DAST collections
|
||||
pub fn dast_targets(&self) -> Collection<DastTarget> {
|
||||
self.inner.collection("dast_targets")
|
||||
}
|
||||
|
||||
pub fn dast_scan_runs(&self) -> Collection<DastScanRun> {
|
||||
self.inner.collection("dast_scan_runs")
|
||||
}
|
||||
|
||||
pub fn dast_findings(&self) -> Collection<DastFinding> {
|
||||
self.inner.collection("dast_findings")
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn raw_collection(&self, name: &str) -> Collection<mongodb::bson::Document> {
|
||||
self.inner.collection(name)
|
||||
}
|
||||
|
||||
/// Get the raw MongoDB database handle (for graph persistence)
|
||||
pub fn inner(&self) -> &mongodb::Database {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user