Skip to main content

systemprompt_models/admin/
mod.rs

1//! Admin-dashboard read models.
2//!
3//! Aggregate DTOs surfaced by the admin API: user metrics with trend
4//! deltas, content statistics, recent conversations, activity trends,
5//! and traffic breakdowns (browser, device, geography, bot share).
6//! These are projection types — they carry no behaviour and are never
7//! persisted directly.
8//!
9//! Copyright (c) systemprompt.io — Business Source License 1.1.
10//! See <https://systemprompt.io> for licensing details.
11
12use chrono::{DateTime, Utc};
13use serde::{Deserialize, Serialize};
14use systemprompt_identifiers::{ContextId, UserId};
15
16#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
17#[serde(rename_all = "lowercase")]
18pub enum LogLevel {
19    Trace,
20    Debug,
21    #[default]
22    Info,
23    Warn,
24    Error,
25}
26
27impl std::fmt::Display for LogLevel {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        match self {
30            Self::Trace => write!(f, "TRACE"),
31            Self::Debug => write!(f, "DEBUG"),
32            Self::Info => write!(f, "INFO"),
33            Self::Warn => write!(f, "WARN"),
34            Self::Error => write!(f, "ERROR"),
35        }
36    }
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct LogEntry {
41    pub timestamp: DateTime<Utc>,
42    pub level: LogLevel,
43    pub module: String,
44    pub message: String,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct UserInfo {
49    pub id: UserId,
50    pub name: String,
51    pub email: Option<String>,
52    pub active_sessions: i64,
53    pub last_session_at: Option<DateTime<Utc>>,
54    pub roles: Vec<String>,
55}
56
57#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
58pub struct UserMetricsWithTrends {
59    pub total_users: i64,
60    pub active_users: i64,
61    pub new_users_today: i64,
62    pub new_users_week: i64,
63    pub new_users_month: i64,
64    pub users_trend_7d: f64,
65    pub users_trend_30d: f64,
66    pub active_trend_7d: f64,
67    pub active_trend_30d: f64,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct ContentStat {
72    pub content_type: String,
73    pub count: i64,
74    pub total_size: Option<i64>,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct RecentConversation {
79    pub context_id: ContextId,
80    pub user_name: Option<String>,
81    pub message_count: i64,
82    pub last_activity: DateTime<Utc>,
83    pub agent_name: Option<String>,
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct ActivityTrend {
88    pub date: String,
89    pub message_count: i64,
90    pub user_count: i64,
91    pub task_count: i64,
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct BrowserBreakdown {
96    pub browser: String,
97    pub count: i64,
98    pub percentage: f64,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct DeviceBreakdown {
103    pub device_type: String,
104    pub count: i64,
105    pub percentage: f64,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct GeographicBreakdown {
110    pub country: String,
111    pub count: i64,
112    pub percentage: f64,
113}
114
115#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
116pub struct BotTrafficStats {
117    pub total_requests: i64,
118    pub bot_requests: i64,
119    pub human_requests: i64,
120    pub bot_percentage: f64,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct AnalyticsData {
125    pub user_metrics: Option<UserMetricsWithTrends>,
126    pub content_stats: Vec<ContentStat>,
127    pub recent_conversations: Vec<RecentConversation>,
128    pub activity_trends: Vec<ActivityTrend>,
129    pub traffic: Option<TrafficData>,
130}
131
132#[derive(Debug, Clone, Default, Serialize, Deserialize)]
133pub struct TrafficData {
134    pub browsers: Vec<BrowserBreakdown>,
135    pub devices: Vec<DeviceBreakdown>,
136    pub countries: Vec<GeographicBreakdown>,
137    pub bot_traffic: BotTrafficStats,
138}