1use crate::storage::{GlobalAnalytics, ProjectAnalytics, ProjectStats, SessionFile};
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Serialize, Deserialize)]
10pub struct ProjectStatsDto {
11 pub project_name: String,
12 pub session_count: usize,
13 pub total_size: u64,
14 pub last_activity: Option<i64>,
15}
16
17impl From<ProjectStats> for ProjectStatsDto {
18 fn from(s: ProjectStats) -> Self {
19 Self {
20 project_name: s.project_name,
21 session_count: s.session_count,
22 total_size: s.total_size,
23 last_activity: s.last_activity,
24 }
25 }
26}
27
28#[derive(Debug, Serialize, Deserialize)]
30pub struct GlobalAnalyticsDto {
31 pub total_sessions: usize,
32 pub sessions_this_week: usize,
33 pub sessions_today: usize,
34 pub total_size: u64,
35 pub total_projects: usize,
36 pub subagent_count: usize,
37 pub avg_session_size: u64,
38 pub most_active_project: Option<String>,
39 pub top_tools: Vec<(String, usize)>,
40 pub total_errors: usize,
41}
42
43impl From<GlobalAnalytics> for GlobalAnalyticsDto {
44 fn from(a: GlobalAnalytics) -> Self {
45 Self {
46 total_sessions: a.total_sessions,
47 sessions_this_week: a.sessions_this_week,
48 sessions_today: a.sessions_today,
49 total_size: a.total_size,
50 total_projects: a.total_projects,
51 subagent_count: a.subagent_count,
52 avg_session_size: a.avg_session_size,
53 most_active_project: a.most_active_project,
54 top_tools: a.top_tools,
55 total_errors: a.total_errors,
56 }
57 }
58}
59
60#[derive(Debug, Serialize, Deserialize)]
62pub struct ProjectAnalyticsDto {
63 pub project_name: String,
64 pub total_sessions: usize,
65 pub sessions_this_week: usize,
66 pub sessions_today: usize,
67 pub total_size: u64,
68 pub subagent_count: usize,
69 pub avg_session_size: u64,
70 pub top_tools: Vec<(String, usize)>,
71 pub last_activity: Option<i64>,
72 pub total_errors: usize,
73}
74
75impl From<ProjectAnalytics> for ProjectAnalyticsDto {
76 fn from(a: ProjectAnalytics) -> Self {
77 Self {
78 project_name: a.project_name,
79 total_sessions: a.total_sessions,
80 sessions_this_week: a.sessions_this_week,
81 sessions_today: a.sessions_today,
82 total_size: a.total_size,
83 subagent_count: a.subagent_count,
84 avg_session_size: a.avg_session_size,
85 top_tools: a.top_tools,
86 last_activity: a.last_activity,
87 total_errors: a.total_errors,
88 }
89 }
90}
91
92#[derive(Debug, Serialize, Deserialize)]
94pub struct SessionFileDto {
95 pub session_id: String,
96 pub project_name: String,
97 pub file_size: u64,
98 pub created_at: i64,
99 pub modified_at: i64,
100 pub has_subagents: bool,
101 pub model: Option<String>,
102 pub error_count: usize,
103 pub first_message: Option<String>,
104 pub source_dir: String,
105 pub subagent_models: Option<Vec<String>>,
106}
107
108#[derive(Debug, Serialize, Deserialize)]
110pub struct PromptEntryDto {
111 pub session_id: String,
112 pub project_name: String,
113 pub prompt_text: String,
114 pub prompt_score: u8,
115 pub timestamp: Option<i64>,
116 pub model: Option<String>,
117}
118
119impl From<SessionFile> for SessionFileDto {
120 fn from(s: SessionFile) -> Self {
121 let subagent_models = s.subagent_models.map(|m| {
122 m.split(',').map(str::to_string).collect()
123 });
124 Self {
125 session_id: s.session_id,
126 project_name: s.project_name,
127 file_size: s.file_size,
128 created_at: s.created_at,
129 modified_at: s.modified_at,
130 has_subagents: s.has_subagents,
131 model: s.model,
132 error_count: s.error_count,
133 first_message: s.first_message,
134 source_dir: s.source_dir,
135 subagent_models,
136 }
137 }
138}