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::CliConfig;
13
14#[derive(Debug, Subcommand)]
15pub enum TrafficCommands {
16    #[command(about = "Traffic source breakdown")]
17    Sources(sources::SourcesArgs),
18
19    #[command(about = "Geographic distribution")]
20    Geo(geo::GeoArgs),
21
22    #[command(about = "Device and browser breakdown")]
23    Devices(devices::DevicesArgs),
24
25    #[command(about = "Bot traffic analysis")]
26    Bots(bots::BotsArgs),
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
30pub struct TrafficSourceRow {
31    pub source: String,
32    pub session_count: i64,
33    pub percentage: f64,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
37pub struct TrafficSourcesOutput {
38    pub period: String,
39    pub sources: Vec<TrafficSourceRow>,
40    pub total_sessions: i64,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
44pub struct GeoRow {
45    pub country: String,
46    pub session_count: i64,
47    pub percentage: f64,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
51pub struct GeoOutput {
52    pub period: String,
53    pub countries: Vec<GeoRow>,
54    pub total_sessions: i64,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
58pub struct DeviceRow {
59    pub device_type: String,
60    pub browser: String,
61    pub session_count: i64,
62    pub percentage: f64,
63}
64
65#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
66pub struct DevicesOutput {
67    pub period: String,
68    pub devices: Vec<DeviceRow>,
69    pub total_sessions: i64,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
73pub struct BotRow {
74    pub bot_type: String,
75    pub request_count: i64,
76    pub percentage: f64,
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
80pub struct BotsOutput {
81    pub period: String,
82    pub human_sessions: i64,
83    pub bot_sessions: i64,
84    pub bot_percentage: f64,
85    pub bot_breakdown: Vec<BotRow>,
86}
87
88pub async fn execute(command: TrafficCommands, config: &CliConfig) -> Result<()> {
89    match command {
90        TrafficCommands::Sources(args) => sources::execute(args, config).await,
91        TrafficCommands::Geo(args) => geo::execute(args, config).await,
92        TrafficCommands::Devices(args) => devices::execute(args, config).await,
93        TrafficCommands::Bots(args) => bots::execute(args, config).await,
94    }
95}
96
97pub async fn execute_with_pool(
98    command: TrafficCommands,
99    db_ctx: &DatabaseContext,
100    config: &CliConfig,
101) -> Result<()> {
102    match command {
103        TrafficCommands::Sources(args) => sources::execute_with_pool(args, db_ctx, config).await,
104        TrafficCommands::Geo(args) => geo::execute_with_pool(args, db_ctx, config).await,
105        TrafficCommands::Devices(args) => devices::execute_with_pool(args, db_ctx, config).await,
106        TrafficCommands::Bots(args) => bots::execute_with_pool(args, db_ctx, config).await,
107    }
108}