Skip to main content

systemprompt_cli/commands/analytics/traffic/
mod.rs

1mod bots;
2mod devices;
3mod geo;
4mod sources;
5
6use anyhow::Result;
7use clap::Subcommand;
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use systemprompt_runtime::DatabaseContext;
11
12use crate::shared::render_result;
13use crate::CliConfig;
14
15#[derive(Debug, Subcommand)]
16pub enum TrafficCommands {
17    #[command(about = "Traffic source breakdown")]
18    Sources(sources::SourcesArgs),
19
20    #[command(about = "Geographic distribution")]
21    Geo(geo::GeoArgs),
22
23    #[command(about = "Device and browser breakdown")]
24    Devices(devices::DevicesArgs),
25
26    #[command(about = "Bot traffic analysis")]
27    Bots(bots::BotsArgs),
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
31pub struct TrafficSourceRow {
32    pub source: String,
33    pub session_count: i64,
34    pub percentage: f64,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
38pub struct TrafficSourcesOutput {
39    pub period: String,
40    pub sources: Vec<TrafficSourceRow>,
41    pub total_sessions: i64,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
45pub struct GeoRow {
46    pub country: String,
47    pub session_count: i64,
48    pub percentage: f64,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
52pub struct GeoOutput {
53    pub period: String,
54    pub countries: Vec<GeoRow>,
55    pub total_sessions: i64,
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
59pub struct DeviceRow {
60    pub device_type: String,
61    pub browser: String,
62    pub session_count: i64,
63    pub percentage: f64,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
67pub struct DevicesOutput {
68    pub period: String,
69    pub devices: Vec<DeviceRow>,
70    pub total_sessions: i64,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
74pub struct BotRow {
75    pub bot_type: String,
76    pub request_count: i64,
77    pub percentage: f64,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
81pub struct BotsOutput {
82    pub period: String,
83    pub human_sessions: i64,
84    pub bot_sessions: i64,
85    pub bot_percentage: f64,
86    pub bot_breakdown: Vec<BotRow>,
87}
88
89pub async fn execute(command: TrafficCommands, config: &CliConfig) -> Result<()> {
90    match command {
91        TrafficCommands::Sources(args) => {
92            let result = sources::execute(args, config).await?;
93            render_result(&result);
94            Ok(())
95        },
96        TrafficCommands::Geo(args) => {
97            let result = geo::execute(args, config).await?;
98            render_result(&result);
99            Ok(())
100        },
101        TrafficCommands::Devices(args) => {
102            let result = devices::execute(args, config).await?;
103            render_result(&result);
104            Ok(())
105        },
106        TrafficCommands::Bots(args) => {
107            let result = bots::execute(args, config).await?;
108            render_result(&result);
109            Ok(())
110        },
111    }
112}
113
114pub async fn execute_with_pool(
115    command: TrafficCommands,
116    db_ctx: &DatabaseContext,
117    config: &CliConfig,
118) -> Result<()> {
119    match command {
120        TrafficCommands::Sources(args) => {
121            let result = sources::execute_with_pool(args, db_ctx, config).await?;
122            render_result(&result);
123            Ok(())
124        },
125        TrafficCommands::Geo(args) => {
126            let result = geo::execute_with_pool(args, db_ctx, config).await?;
127            render_result(&result);
128            Ok(())
129        },
130        TrafficCommands::Devices(args) => {
131            let result = devices::execute_with_pool(args, db_ctx, config).await?;
132            render_result(&result);
133            Ok(())
134        },
135        TrafficCommands::Bots(args) => {
136            let result = bots::execute_with_pool(args, db_ctx, config).await?;
137            render_result(&result);
138            Ok(())
139        },
140    }
141}