#[cfg(feature = "demo")]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn serve_dag_mermaid(state: &Arc<RwLock<DemoState>>) -> Response<Bytes> {
let state = state.read();
let mermaid_generator = MermaidGenerator::new(MermaidOptions {
show_complexity: true,
filter_external: true,
group_by_module: true,
max_depth: Some(10),
});
let mut diagram = mermaid_generator.generate(&state.analysis_results.dependency_graph);
if diagram.trim() == "graph TD" || diagram.trim().is_empty() {
let tdg_info = if let Some(tdg_summary) = &state.analysis_results.tdg_summary {
format!(
r#"
subgraph TDG_Legend[" TDG Analysis"]
TDG_Info["📊 {} files analyzed<br/>🔴 {} critical (TDG>2.5)<br/>🟡 {} warning (1.5-2.5)<br/>🟢 {} normal (<1.5)"]
TDG_Avg["📈 Average TDG: {:.2}"]
end"#,
tdg_summary.total_files,
tdg_summary.critical_files,
tdg_summary.warning_files,
tdg_summary.total_files - tdg_summary.critical_files - tdg_summary.warning_files,
tdg_summary.average_tdg
)
} else {
String::with_capacity(1024)
};
diagram = format!(
r"graph TD
A[DemoRunner] -->|uses| B[StatelessTemplateServer]
A -->|generates| C[DemoReport]
A -->|creates| D[System Diagram]
E[LocalDemoServer] -->|serves| F[Dashboard]
E -->|handles| G[API Endpoints]
H[DagBuilder] -->|creates| I[DependencyGraph]
H -->|processes| J[ProjectContext]
K[TDG Calculator] -->|analyzes| L[Technical Debt]
K -->|reports| M[TDG Scores]
N[File Discovery] -->|filters| O[Project Files]
N -->|excludes| P[External Dependencies]
{tdg_info}
%% TDG-based styling
style A fill:#90EE90
style E fill:#FFD700
style H fill:#FFA500
style K fill:#87CEEB
style N fill:#DDA0DD"
);
}
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "text/plain")
.header("Cache-Control", "max-age=60")
.body(Bytes::from(diagram))
.expect("HTTP response construction cannot fail")
}
#[cfg(feature = "demo")]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn serve_system_diagram_mermaid(state: &Arc<RwLock<DemoState>>) -> Response<Bytes> {
let state = state.read();
let system_diagram = if let Some(ref diagram) = state.system_diagram {
diagram.clone()
} else {
r"graph TD
A[AST Context Analysis] -->|uses| B[File Parser]
B --> C[Rust AST]
B --> D[TypeScript AST]
B --> E[Python AST]
F[Code Complexity] -->|analyzes| C
F -->|analyzes| D
F -->|analyzes| E
G[DAG Generation] -->|reads| C
G -->|reads| D
G -->|reads| E
H[Code Churn] -->|git history| I[Git Analysis]
J[Template Generation] -->|renders| K[Handlebars]
style A fill:#90EE90
style F fill:#FFD700
style G fill:#FFA500
style H fill:#FF6347
style J fill:#87CEEB"
.to_string()
};
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "text/plain")
.header("Cache-Control", "max-age=60")
.body(Bytes::from(system_diagram))
.expect("HTTP response construction cannot fail")
}
#[cfg(feature = "demo")]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn serve_architecture_analysis(state: &Arc<RwLock<DemoState>>) -> Response<Bytes> {
use crate::services::canonical_query::{
AnalysisContext, CallGraph, CanonicalQuery, SystemArchitectureQuery,
};
use rustc_hash::FxHashMap;
let state = state.read();
let context = AnalysisContext {
project_path: state.repository.clone(),
ast_dag: state.analysis_results.dependency_graph.clone(),
call_graph: CallGraph::default(),
complexity_map: FxHashMap::default(),
churn_analysis: Some(state.analysis_results.churn_analysis.clone()),
};
let query = SystemArchitectureQuery;
match query.execute(&context) {
Ok(result) => Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "application/json")
.header("Cache-Control", "max-age=60")
.body(Bytes::from(
serde_json::to_vec(&result).expect("JSON serialization cannot fail for result"),
))
.expect("HTTP response construction cannot fail"),
Err(_) => Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Bytes::from_static(b"Architecture analysis failed"))
.expect("HTTP response construction cannot fail"),
}
}
#[cfg(feature = "demo")]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn serve_defect_analysis(state: &Arc<RwLock<DemoState>>) -> Response<Bytes> {
let state = state.read();
let placeholder = serde_json::json!({
"summary": {
"total_files": state.analysis_results.files_analyzed,
"critical_files": 0,
"warning_files": 0,
"average_tdg": 1.2,
"p95_tdg": 2.1,
"p99_tdg": 3.0,
"estimated_debt_hours": 24.5,
"hotspots": []
},
"recommendations": []
});
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "application/json")
.header("Cache-Control", "max-age=60")
.body(Bytes::from(
serde_json::to_vec(&placeholder)
.expect("JSON serialization cannot fail for placeholder"),
))
.expect("HTTP response construction cannot fail")
}
#[cfg(feature = "demo")]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn serve_statistics_analysis(state: &Arc<RwLock<DemoState>>) -> Response<Bytes> {
let state = state.read();
let stats = serde_json::json!({
"structural_metrics": {
"node_count": state.analysis_results.dependency_graph.nodes.len(),
"edge_count": state.analysis_results.dependency_graph.edges.len(),
"density": calculate_graph_density(&state.analysis_results.dependency_graph),
"avg_degree": calculate_avg_degree(&state.analysis_results.dependency_graph),
},
"code_metrics": {
"total_files": state.analysis_results.complexity_report.summary.total_files,
"total_functions": state.analysis_results.complexity_report.summary.total_functions,
"median_complexity": state.analysis_results.complexity_report.summary.median_cyclomatic,
"complexity_p90": state.analysis_results.complexity_report.summary.p90_cyclomatic,
"tech_debt_hours": state.analysis_results.complexity_report.summary.technical_debt_hours,
},
"temporal_metrics": {
"total_commits": state.analysis_results.churn_analysis.summary.total_commits,
"total_files_changed": state.analysis_results.churn_analysis.summary.total_files_changed,
"active_authors": state.analysis_results.churn_analysis.summary.author_contributions.len(),
}
});
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "application/json")
.header("Cache-Control", "max-age=60")
.body(Bytes::from(
serde_json::to_vec(&stats).expect("JSON serialization cannot fail for stats"),
))
.expect("HTTP response construction cannot fail")
}
#[cfg(feature = "demo")]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn serve_system_diagram(state: &Arc<RwLock<DemoState>>) -> Response<Bytes> {
serve_architecture_analysis(state)
}
#[cfg(feature = "demo")]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn serve_analysis_stream(_state: &Arc<RwLock<DemoState>>) -> Response<Bytes> {
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "text/event-stream")
.body(Bytes::from_static(
b"data: {\"event\":\"complete\",\"result\":\"Analysis complete\"}\n\n",
))
.expect("HTTP response construction cannot fail")
}
#[cfg(feature = "demo")]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub(crate) fn serve_analysis_data(state: &Arc<RwLock<DemoState>>) -> Response<Bytes> {
let state = state.read();
let mut analysis_data = Vec::new();
for file in &state.analysis_results.complexity_report.files {
let total_complexity: u32 = file
.functions
.iter()
.map(|f| u32::from(f.metrics.cognitive))
.sum();
let max_complexity = file
.functions
.iter()
.map(|f| u32::from(f.metrics.cognitive))
.max()
.unwrap_or(0);
let total_loc: usize = file
.functions
.iter()
.map(|f| f.metrics.lines as usize)
.sum();
let churn_data = state
.analysis_results
.churn_analysis
.files
.iter()
.find(|f| f.relative_path == file.path);
let commit_count = churn_data.map_or(0, |c| c.commit_count);
let churn_score = churn_data.map_or(0.0, |c| c.churn_score);
let cognitive_normalized = (f64::from(max_complexity) / 20.0).min(3.0);
let churn_normalized = (f64::from(churn_score) / 10.0).min(3.0);
let tdg_value = (cognitive_normalized * 0.3 + churn_normalized * 0.3 + 0.4).min(3.0);
let tdg_severity = match tdg_value {
v if v > 2.5 => "Critical",
v if v > 1.5 => "Warning",
_ => "Normal",
};
analysis_data.push(serde_json::json!({
"path": file.path.replace("./server/src/", ""),
"complexity_metrics": {
"cognitive": max_complexity,
"cyclomatic": file.total_complexity.cyclomatic,
"total": total_complexity
},
"churn_metrics": {
"commit_count": commit_count,
"churn_score": churn_score
},
"tdg_score": tdg_value,
"tdg_severity": tdg_severity,
"lines_of_code": total_loc
}));
}
if analysis_data.is_empty() {
analysis_data = vec![
serde_json::json!({
"path": "demo/server.rs",
"complexity_metrics": { "cognitive": 12, "cyclomatic": 10, "total": 45 },
"churn_metrics": { "commit_count": 5, "churn_score": 3.2 },
"tdg_score": 0.89,
"tdg_severity": "Low",
"lines_of_code": 789
}),
serde_json::json!({
"path": "services/dag_builder.rs",
"complexity_metrics": { "cognitive": 18, "cyclomatic": 15, "total": 67 },
"churn_metrics": { "commit_count": 8, "churn_score": 5.1 },
"tdg_score": 1.67,
"tdg_severity": "Medium",
"lines_of_code": 456
}),
serde_json::json!({
"path": "handlers/tools.rs",
"complexity_metrics": { "cognitive": 9, "cyclomatic": 7, "total": 28 },
"churn_metrics": { "commit_count": 3, "churn_score": 1.8 },
"tdg_score": 0.65,
"tdg_severity": "Low",
"lines_of_code": 234
}),
];
}
let response_data = serde_json::json!({
"ast_contexts": analysis_data,
"total_files": state.analysis_results.files_analyzed,
"timestamp": chrono::Utc::now().to_rfc3339()
});
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "application/json")
.header("Cache-Control", "max-age=60")
.body(Bytes::from(
serde_json::to_vec(&response_data)
.expect("JSON serialization cannot fail for response data"),
))
.expect("HTTP response construction cannot fail")
}
#[cfg(feature = "demo")]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn calculate_graph_density(graph: &DependencyGraph) -> f64 {
let n = graph.nodes.len() as f64;
if n <= 1.0 {
0.0
} else {
graph.edges.len() as f64 / (n * (n - 1.0))
}
}
#[cfg(feature = "demo")]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
fn calculate_avg_degree(graph: &DependencyGraph) -> f64 {
let n = graph.nodes.len() as f64;
if n == 0.0 {
0.0
} else {
2.0 * graph.edges.len() as f64 / n
}
}