Skip to main content

systemprompt_cli/commands/core/content/analytics/
clicks.rs

1use crate::cli_settings::CliConfig;
2use crate::commands::core::content::types::{ClickRow, ClicksOutput};
3use crate::shared::CommandResult;
4use anyhow::Result;
5use clap::Args;
6use systemprompt_content::LinkAnalyticsService;
7use systemprompt_database::DbPool;
8use systemprompt_identifiers::LinkId;
9use systemprompt_runtime::AppContext;
10
11#[derive(Debug, Args)]
12pub struct ClicksArgs {
13    #[arg(help = "Link ID")]
14    pub link_id: String,
15
16    #[arg(long, default_value = "20")]
17    pub limit: i64,
18
19    #[arg(long, default_value = "0")]
20    pub offset: i64,
21}
22
23pub async fn execute(args: ClicksArgs, config: &CliConfig) -> Result<CommandResult<ClicksOutput>> {
24    let ctx = AppContext::new().await?;
25    execute_with_pool(args, ctx.db_pool(), config).await
26}
27
28pub async fn execute_with_pool(
29    args: ClicksArgs,
30    pool: &DbPool,
31    _config: &CliConfig,
32) -> Result<CommandResult<ClicksOutput>> {
33    let service = LinkAnalyticsService::new(pool)?;
34
35    let link_id = LinkId::new(args.link_id.clone());
36    let clicks = service
37        .get_link_clicks(&link_id, Some(args.limit), Some(args.offset))
38        .await?;
39
40    let total = clicks.len() as i64;
41    let click_rows: Vec<ClickRow> = clicks
42        .into_iter()
43        .filter_map(|click| {
44            Some(ClickRow {
45                click_id: click.id.to_string(),
46                session_id: click.session_id,
47                user_id: click.user_id,
48                clicked_at: click.clicked_at?,
49                referrer_page: click.referrer_page,
50                device_type: click.device_type,
51                country: click.country,
52                is_conversion: click.is_conversion.unwrap_or(false),
53            })
54        })
55        .collect();
56
57    let output = ClicksOutput {
58        link_id,
59        clicks: click_rows,
60        total,
61    };
62
63    Ok(CommandResult::table(output)
64        .with_title("Link Clicks")
65        .with_columns(vec![
66            "click_id".to_string(),
67            "session_id".to_string(),
68            "clicked_at".to_string(),
69            "device_type".to_string(),
70            "country".to_string(),
71        ]))
72}