skill_web/api/
analytics.rs1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use super::{ApiClient, ApiResult};
7
8#[derive(Clone)]
9pub struct AnalyticsApi {
10 client: ApiClient,
11}
12
13impl AnalyticsApi {
14 pub fn new(client: ApiClient) -> Self {
15 Self { client }
16 }
17
18 pub async fn get_overview(&self, days: u32) -> ApiResult<AnalyticsOverviewResponse> {
20 self.client
21 .get(&format!("/analytics/overview?days={}", days))
22 .await
23 }
24
25 pub async fn get_top_queries(&self, limit: usize, days: u32) -> ApiResult<TopQueriesResponse> {
27 self.client
28 .get(&format!(
29 "/analytics/top-queries?limit={}&days={}",
30 limit, days
31 ))
32 .await
33 }
34
35 pub async fn get_feedback_stats(&self, days: u32) -> ApiResult<FeedbackStatsResponse> {
37 self.client
38 .get(&format!("/analytics/feedback-stats?days={}", days))
39 .await
40 }
41
42 pub async fn get_timeline(
44 &self,
45 days: u32,
46 interval_hours: u32,
47 ) -> ApiResult<SearchTimelineResponse> {
48 self.client
49 .get(&format!(
50 "/analytics/timeline?days={}&interval_hours={}",
51 days, interval_hours
52 ))
53 .await
54 }
55}
56
57#[derive(Debug, Clone, Deserialize, Serialize)]
60pub struct AnalyticsOverviewResponse {
61 pub total_searches: usize,
62 pub total_feedback: usize,
63 pub positive_feedback: usize,
64 pub negative_feedback: usize,
65 pub avg_latency_ms: f64,
66 pub avg_results: f64,
67 pub recent_searches: Vec<SearchHistorySummary>,
68}
69
70#[derive(Debug, Clone, Deserialize, Serialize)]
71pub struct SearchHistorySummary {
72 pub query: String,
73 pub results_count: usize,
74 pub duration_ms: u64,
75 pub timestamp: DateTime<Utc>,
76}
77
78#[derive(Debug, Clone, Deserialize, Serialize)]
79pub struct TopQueriesResponse {
80 pub queries: Vec<QueryStats>,
81}
82
83#[derive(Debug, Clone, Deserialize, Serialize)]
84pub struct QueryStats {
85 pub query: String,
86 pub count: usize,
87 pub avg_results: f64,
88 pub avg_latency_ms: f64,
89 pub positive_feedback: usize,
90 pub negative_feedback: usize,
91}
92
93#[derive(Debug, Clone, Deserialize, Serialize)]
94pub struct FeedbackStatsResponse {
95 pub by_type: Vec<FeedbackTypeCount>,
96 pub top_positive: Vec<ResultFeedbackSummary>,
97 pub top_negative: Vec<ResultFeedbackSummary>,
98}
99
100#[derive(Debug, Clone, Deserialize, Serialize)]
101pub struct FeedbackTypeCount {
102 pub feedback_type: String,
103 pub count: usize,
104}
105
106#[derive(Debug, Clone, Deserialize, Serialize)]
107pub struct ResultFeedbackSummary {
108 pub result_id: String,
109 pub positive_count: usize,
110 pub negative_count: usize,
111 pub total_count: usize,
112}
113
114#[derive(Debug, Clone, Deserialize, Serialize)]
115pub struct SearchTimelineResponse {
116 pub timeline: Vec<TimelineDataPoint>,
117}
118
119#[derive(Debug, Clone, Deserialize, Serialize)]
120pub struct TimelineDataPoint {
121 pub timestamp: DateTime<Utc>,
122 pub search_count: usize,
123 pub avg_latency_ms: f64,
124}