Skip to main content

systemprompt_analytics/models/
mod.rs

1//! Public DTO/row types for the analytics crate.
2//!
3//! Submodules are split by domain (engagement, events, fingerprint, funnel)
4//! plus a `reporting` family of row structs consumed by report frontends such
5//! as `systemprompt-cli`.
6//!
7//! Copyright (c) systemprompt.io — Business Source License 1.1.
8//! See <https://systemprompt.io> for licensing details.
9
10mod engagement;
11mod events;
12mod fingerprint;
13mod funnel;
14pub mod reporting;
15
16pub use engagement::{CreateEngagementEventInput, EngagementEvent, EngagementOptionalMetrics};
17pub use events::{
18    AnalyticsEventBatchResponse, AnalyticsEventCreated, AnalyticsEventType, ConversionEventData,
19    CreateAnalyticsEventBatchInput, CreateAnalyticsEventInput, EngagementEventData,
20    LinkClickEventData, ScrollEventData,
21};
22pub use fingerprint::{FingerprintAnalysisResult, FingerprintReputation, FlagReason};
23pub use funnel::{
24    CreateFunnelInput, CreateFunnelStepInput, Funnel, FunnelMatchType, FunnelProgress, FunnelStats,
25    FunnelStep, FunnelStepStats, FunnelWithSteps,
26};
27pub use reporting::*;
28
29use chrono::{DateTime, Utc};
30use serde::{Deserialize, Serialize};
31use sqlx::FromRow;
32use systemprompt_identifiers::{ContextId, SessionId, UserId};
33
34#[derive(Debug, Clone, Copy, Serialize, Deserialize, FromRow)]
35pub struct UserMetricsWithTrends {
36    #[serde(rename = "users_24h")]
37    pub count_24h: i64,
38    #[serde(rename = "users_7d")]
39    pub count_7d: i64,
40    #[serde(rename = "users_30d")]
41    pub count_30d: i64,
42    #[serde(rename = "users_prev_24h")]
43    pub prev_24h: i64,
44    #[serde(rename = "users_prev_7d")]
45    pub prev_7d: i64,
46    #[serde(rename = "users_prev_30d")]
47    pub prev_30d: i64,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
51pub struct RecentConversation {
52    pub context_id: ContextId,
53    pub agent_name: String,
54    pub user_name: String,
55    pub status: String,
56    pub message_count: i64,
57    pub started_at: DateTime<Utc>,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
61pub struct ContentStat {
62    pub title: String,
63    pub slug: String,
64    pub views_5m: i64,
65    pub views_1h: i64,
66    pub views_1d: i64,
67    pub views_7d: i64,
68    pub views_30d: i64,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
72pub struct AnalyticsSession {
73    pub session_id: SessionId,
74    pub user_id: Option<UserId>,
75    pub fingerprint_hash: Option<String>,
76    pub ip_address: Option<String>,
77    pub user_agent: Option<String>,
78    pub device_type: Option<String>,
79    pub browser: Option<String>,
80    pub os: Option<String>,
81    pub country: Option<String>,
82    pub city: Option<String>,
83    pub referrer_url: Option<String>,
84    pub utm_source: Option<String>,
85    pub utm_medium: Option<String>,
86    pub utm_campaign: Option<String>,
87    pub utm_content: Option<String>,
88    pub utm_term: Option<String>,
89    pub is_bot: bool,
90    pub is_scanner: Option<bool>,
91    pub is_behavioral_bot: Option<bool>,
92    pub behavioral_bot_reason: Option<String>,
93    pub started_at: Option<DateTime<Utc>>,
94    pub last_activity_at: Option<DateTime<Utc>>,
95    pub ended_at: Option<DateTime<Utc>>,
96    pub request_count: Option<i32>,
97    pub task_count: Option<i32>,
98    pub ai_request_count: Option<i32>,
99    pub message_count: Option<i32>,
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
103pub struct AnalyticsEvent {
104    pub id: String,
105    pub event_type: String,
106    pub event_category: String,
107    pub severity: String,
108    pub user_id: UserId,
109    pub session_id: Option<SessionId>,
110    pub message: Option<String>,
111    pub metadata: Option<String>,
112    pub timestamp: DateTime<Utc>,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
116pub struct ErrorSummary {
117    pub error_type: String,
118    pub count: i64,
119    pub last_occurred: DateTime<Utc>,
120    pub sample_message: Option<String>,
121}
122
123#[derive(Debug, Clone, Copy, Serialize, Deserialize, FromRow)]
124pub struct PlatformOverview {
125    pub total_users: i64,
126    pub active_users_24h: i64,
127    pub active_users_7d: i64,
128    pub total_sessions: i64,
129    pub active_sessions: i64,
130    pub total_contexts: i64,
131    pub total_tasks: i64,
132    pub total_ai_requests: i64,
133}
134
135#[derive(Debug, Clone, Copy, Serialize, Deserialize, FromRow)]
136pub struct CostOverview {
137    pub total_cost: f64,
138    pub cost_24h: f64,
139    pub cost_7d: f64,
140    pub cost_30d: f64,
141    pub avg_cost_per_request: f64,
142}
143
144#[derive(Debug, Clone, Copy, Serialize, Deserialize, FromRow)]
145pub struct ActivityTrend {
146    pub date: DateTime<Utc>,
147    pub sessions: i64,
148    pub contexts: i64,
149    pub tasks: i64,
150    pub ai_requests: i64,
151    pub tool_executions: i64,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
155pub struct TopUser {
156    pub user_id: UserId,
157    pub user_name: String,
158    pub session_count: i64,
159    pub task_count: i64,
160    pub ai_request_count: i64,
161    pub total_cost: f64,
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
165pub struct TopAgent {
166    pub agent_name: String,
167    pub task_count: i64,
168    pub success_rate: f64,
169    pub avg_duration_ms: i64,
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
173pub struct TopTool {
174    pub tool_name: String,
175    pub execution_count: i64,
176    pub success_rate: f64,
177    pub avg_duration_ms: i64,
178}
179
180#[derive(Debug, Clone, Copy, Serialize, Deserialize, FromRow)]
181pub struct TrafficSummary {
182    pub total_sessions: i64,
183    pub unique_visitors: i64,
184    pub page_views: i64,
185    pub avg_session_duration_seconds: f64,
186    pub bounce_rate: f64,
187}
188
189#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
190pub struct TrafficSource {
191    pub source: String,
192    pub sessions: i64,
193    pub percentage: f64,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
197pub struct DeviceBreakdown {
198    pub device_type: String,
199    pub count: i64,
200    pub percentage: f64,
201}
202
203#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
204pub struct BrowserBreakdown {
205    pub browser: String,
206    pub count: i64,
207    pub percentage: f64,
208}
209
210#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
211pub struct GeographicBreakdown {
212    pub country: String,
213    pub count: i64,
214    pub percentage: f64,
215}
216
217#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, FromRow)]
218pub struct BotTrafficStats {
219    pub total_requests: i64,
220    pub bot_requests: i64,
221    pub human_requests: i64,
222    pub bot_percentage: f64,
223}
224
225#[derive(Debug, Clone, Copy, Serialize, Deserialize, FromRow)]
226pub struct ConversationSummary {
227    pub total_conversations: i64,
228    pub active_conversations: i64,
229    pub completed_conversations: i64,
230    pub avg_messages_per_conversation: f64,
231    pub avg_duration_minutes: f64,
232}
233
234#[derive(Debug, Clone, Copy, Serialize, Deserialize, FromRow)]
235pub struct ConversationTrend {
236    pub date: DateTime<Utc>,
237    pub new_conversations: i64,
238    pub completed_conversations: i64,
239    pub total_messages: i64,
240}
241
242#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
243pub struct ConversationByAgent {
244    pub agent_name: String,
245    pub conversation_count: i64,
246    pub avg_messages: f64,
247    pub success_rate: f64,
248}