1use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
7pub struct SymbolFact {
8 pub path: String,
9 pub name: String,
10 pub kind: String,
11 pub complexity: u32,
12 pub calls: Vec<String>,
13 pub start_byte: usize,
14 pub end_byte: usize,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
18pub struct FileFact {
19 pub snapshot_id: String,
20 pub path: String,
21 pub language: String,
22 pub bytes: u64,
23 pub loc: u32,
24 pub sloc: u32,
25 pub complexity_total: u32,
26 pub max_fn_complexity: u32,
27 pub symbol_count: u32,
28 pub import_count: u32,
29 pub fan_in: u32,
30 pub fan_out: u32,
31 pub churn_30d: u32,
32 pub churn_90d: u32,
33 pub authors_90d: u32,
34 pub last_changed_ms: Option<u64>,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
38pub struct RepoEdge {
39 pub from_path: String,
40 pub to_path: String,
41 pub kind: String,
42 pub weight: u32,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
46pub struct RepoSnapshotRecord {
47 pub id: String,
48 pub workspace: String,
49 pub head_commit: Option<String>,
50 pub dirty_fingerprint: String,
51 pub analyzer_version: String,
52 pub indexed_at_ms: u64,
53 pub dirty: bool,
54 pub graph_path: String,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
58pub struct ToolSpanView {
59 pub span_id: String,
60 pub tool: String,
61 pub status: String,
62 pub lead_time_ms: Option<u64>,
63 pub tokens_in: Option<u32>,
64 pub tokens_out: Option<u32>,
65 pub reasoning_tokens: Option<u32>,
66 pub cost_usd_e6: Option<i64>,
67 pub paths: Vec<String>,
68 pub parent_span_id: Option<String>,
69 pub depth: u32,
70 pub subtree_cost_usd_e6: Option<i64>,
71 pub subtree_token_count: Option<u32>,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
75pub struct ToolSpanSample {
76 pub span_id: String,
77 pub session_id: String,
78 pub tool: Option<String>,
79 pub lead_time_ms: Option<u64>,
80 pub tokens_in: Option<u32>,
81 pub tokens_out: Option<u32>,
82 pub reasoning_tokens: Option<u32>,
83 pub cost_usd_e6: Option<i64>,
84 pub paths: Vec<String>,
85}
86
87impl From<&crate::store::tool_span_index::ToolSpanRecord> for ToolSpanSample {
88 fn from(span: &crate::store::tool_span_index::ToolSpanRecord) -> Self {
89 Self {
90 span_id: span.span_id.clone(),
91 session_id: span.session_id.clone(),
92 tool: span.tool.clone(),
93 lead_time_ms: span.lead_time_ms,
94 tokens_in: span.tokens_in,
95 tokens_out: span.tokens_out,
96 reasoning_tokens: span.reasoning_tokens,
97 cost_usd_e6: span.cost_usd_e6,
98 paths: span.paths.clone(),
99 }
100 }
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
104pub struct RankedFile {
105 pub path: String,
106 pub value: u64,
107 pub complexity_total: u32,
108 pub churn_30d: u32,
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
112pub struct RankedTool {
113 pub tool: String,
114 pub calls: u64,
115 pub p50_ms: Option<u64>,
116 pub p95_ms: Option<u64>,
117 pub total_tokens: u64,
118 pub total_reasoning_tokens: u64,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
122pub struct MetricsReport {
123 pub snapshot: Option<RepoSnapshotRecord>,
124 pub hottest_files: Vec<RankedFile>,
125 pub most_changed_files: Vec<RankedFile>,
126 pub most_complex_files: Vec<RankedFile>,
127 pub highest_risk_files: Vec<RankedFile>,
128 pub slowest_tools: Vec<RankedTool>,
129 pub highest_token_tools: Vec<RankedTool>,
130 pub highest_reasoning_tools: Vec<RankedTool>,
131 pub agent_pain_hotspots: Vec<RankedFile>,
132}
133
134#[derive(Debug, Clone, Default, PartialEq, Eq)]
135pub struct FileHistory {
136 pub churn_30d: u32,
137 pub churn_90d: u32,
138 pub authors_90d: u32,
139 pub last_changed_ms: Option<u64>,
140}
141
142#[derive(Debug, Clone, Default, PartialEq, Eq)]
143pub struct RepoAnalysis {
144 pub path: String,
145 pub language: String,
146 pub bytes: u64,
147 pub loc: u32,
148 pub sloc: u32,
149 pub complexity_total: u32,
150 pub max_fn_complexity: u32,
151 pub imports: Vec<String>,
152 pub symbols: Vec<SymbolFact>,
153}