systemprompt_analytics/repository/agents/
stats_queries.rs1use anyhow::Result;
2use chrono::{DateTime, Utc};
3
4use super::AgentAnalyticsRepository;
5use crate::models::cli::{AgentAiStatsRow, AgentStatsRow, AgentTaskRow};
6
7impl AgentAnalyticsRepository {
8 pub async fn get_stats(
9 &self,
10 start: DateTime<Utc>,
11 end: DateTime<Utc>,
12 agent_filter: Option<&str>,
13 ) -> Result<AgentStatsRow> {
14 if let Some(agent) = agent_filter {
15 let pattern = format!("%{}%", agent);
16 sqlx::query_as!(
17 AgentStatsRow,
18 r#"
19 SELECT
20 COUNT(DISTINCT agent_name)::bigint as "total_agents!",
21 COUNT(*)::bigint as "total_tasks!",
22 COUNT(*) FILTER (WHERE status = 'completed')::bigint as "completed_tasks!",
23 COUNT(*) FILTER (WHERE status = 'failed')::bigint as "failed_tasks!",
24 COALESCE(AVG(execution_time_ms)::float8, 0) as "avg_execution_time_ms!"
25 FROM agent_tasks
26 WHERE started_at >= $1 AND started_at < $2
27 AND agent_name ILIKE $3
28 "#,
29 start,
30 end,
31 pattern
32 )
33 .fetch_one(&*self.pool)
34 .await
35 .map_err(Into::into)
36 } else {
37 sqlx::query_as!(
38 AgentStatsRow,
39 r#"
40 SELECT
41 COUNT(DISTINCT agent_name)::bigint as "total_agents!",
42 COUNT(*)::bigint as "total_tasks!",
43 COUNT(*) FILTER (WHERE status = 'completed')::bigint as "completed_tasks!",
44 COUNT(*) FILTER (WHERE status = 'failed')::bigint as "failed_tasks!",
45 COALESCE(AVG(execution_time_ms)::float8, 0) as "avg_execution_time_ms!"
46 FROM agent_tasks
47 WHERE started_at >= $1 AND started_at < $2
48 "#,
49 start,
50 end
51 )
52 .fetch_one(&*self.pool)
53 .await
54 .map_err(Into::into)
55 }
56 }
57
58 pub async fn get_ai_stats(
59 &self,
60 start: DateTime<Utc>,
61 end: DateTime<Utc>,
62 ) -> Result<AgentAiStatsRow> {
63 sqlx::query_as!(
64 AgentAiStatsRow,
65 r#"
66 SELECT
67 COUNT(*)::bigint as "total_ai_requests!",
68 COALESCE(SUM(cost_cents), 0)::bigint as "total_cost_cents!"
69 FROM ai_requests
70 WHERE created_at >= $1 AND created_at < $2
71 "#,
72 start,
73 end
74 )
75 .fetch_one(&*self.pool)
76 .await
77 .map_err(Into::into)
78 }
79
80 pub async fn get_tasks_for_trends(
81 &self,
82 start: DateTime<Utc>,
83 end: DateTime<Utc>,
84 agent_filter: Option<&str>,
85 ) -> Result<Vec<AgentTaskRow>> {
86 if let Some(agent) = agent_filter {
87 let pattern = format!("%{}%", agent);
88 sqlx::query_as!(
89 AgentTaskRow,
90 r#"
91 SELECT
92 started_at as "started_at!",
93 status,
94 execution_time_ms
95 FROM agent_tasks
96 WHERE started_at >= $1 AND started_at < $2
97 AND agent_name ILIKE $3
98 ORDER BY started_at
99 "#,
100 start,
101 end,
102 pattern
103 )
104 .fetch_all(&*self.pool)
105 .await
106 .map_err(Into::into)
107 } else {
108 sqlx::query_as!(
109 AgentTaskRow,
110 r#"
111 SELECT
112 started_at as "started_at!",
113 status,
114 execution_time_ms
115 FROM agent_tasks
116 WHERE started_at >= $1 AND started_at < $2
117 ORDER BY started_at
118 "#,
119 start,
120 end
121 )
122 .fetch_all(&*self.pool)
123 .await
124 .map_err(Into::into)
125 }
126 }
127}