Skip to main content

systemprompt_cli/commands/analytics/sessions/
mod.rs

1mod live;
2mod stats;
3mod trends;
4
5use anyhow::Result;
6use clap::Subcommand;
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use systemprompt_runtime::DatabaseContext;
10
11use crate::CliConfig;
12
13#[derive(Debug, Subcommand)]
14pub enum SessionsCommands {
15    #[command(about = "Session statistics")]
16    Stats(stats::StatsArgs),
17
18    #[command(about = "Session trends over time")]
19    Trends(trends::TrendsArgs),
20
21    #[command(about = "Real-time active sessions")]
22    Live(live::LiveArgs),
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
26pub struct SessionStatsOutput {
27    pub period: String,
28    pub total_sessions: i64,
29    pub active_sessions: i64,
30    pub unique_users: i64,
31    pub avg_duration_seconds: i64,
32    pub avg_requests_per_session: f64,
33    pub conversion_rate: f64,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
37pub struct SessionTrendPoint {
38    pub timestamp: String,
39    pub session_count: i64,
40    pub active_users: i64,
41    pub avg_duration_seconds: i64,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
45pub struct SessionTrendsOutput {
46    pub period: String,
47    pub group_by: String,
48    pub points: Vec<SessionTrendPoint>,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
52pub struct ActiveSessionRow {
53    pub session_id: String,
54    pub user_type: String,
55    pub started_at: String,
56    pub duration_seconds: i64,
57    pub request_count: i64,
58    pub last_activity: String,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
62pub struct LiveSessionsOutput {
63    pub active_count: i64,
64    pub sessions: Vec<ActiveSessionRow>,
65    pub timestamp: String,
66}
67
68pub async fn execute(command: SessionsCommands, config: &CliConfig) -> Result<()> {
69    match command {
70        SessionsCommands::Stats(args) => stats::execute(args, config).await,
71        SessionsCommands::Trends(args) => trends::execute(args, config).await,
72        SessionsCommands::Live(args) => live::execute(args, config).await,
73    }
74}
75
76pub async fn execute_with_pool(
77    command: SessionsCommands,
78    db_ctx: &DatabaseContext,
79    config: &CliConfig,
80) -> Result<()> {
81    match command {
82        SessionsCommands::Stats(args) => stats::execute_with_pool(args, db_ctx, config).await,
83        SessionsCommands::Trends(args) => trends::execute_with_pool(args, db_ctx, config).await,
84        SessionsCommands::Live(args) => live::execute_with_pool(args, db_ctx, config).await,
85    }
86}