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    // CLI: user-provided partial lookup
14    #[arg(help = "Link ID")]
15    pub link_id: String,
16
17    #[arg(long, default_value = "20")]
18    pub limit: i64,
19
20    #[arg(long, default_value = "0")]
21    pub offset: i64,
22}
23
24pub async fn execute(args: ClicksArgs, config: &CliConfig) -> Result<CommandResult<ClicksOutput>> {
25    let ctx = AppContext::new().await?;
26    execute_with_pool(args, ctx.db_pool(), config).await
27}
28
29pub async fn execute_with_pool(
30    args: ClicksArgs,
31    pool: &DbPool,
32    _config: &CliConfig,
33) -> Result<CommandResult<ClicksOutput>> {
34    let service = LinkAnalyticsService::new(pool)?;
35
36    let link_id = LinkId::new(args.link_id.clone());
37    let clicks = service
38        .get_link_clicks(&link_id, Some(args.limit), Some(args.offset))
39        .await?;
40
41    let total = clicks.len() as i64;
42    let click_rows: Vec<ClickRow> = clicks
43        .into_iter()
44        .filter_map(|click| {
45            Some(ClickRow {
46                click_id: click.id.to_string(),
47                session_id: click.session_id,
48                user_id: click.user_id,
49                clicked_at: click.clicked_at?,
50                referrer_page: click.referrer_page,
51                device_type: click.device_type,
52                country: click.country,
53                is_conversion: click.is_conversion.unwrap_or(false),
54            })
55        })
56        .collect();
57
58    let output = ClicksOutput {
59        link_id,
60        clicks: click_rows,
61        total,
62    };
63
64    Ok(CommandResult::table(output)
65        .with_title("Link Clicks")
66        .with_columns(vec![
67            "click_id".to_string(),
68            "session_id".to_string(),
69            "clicked_at".to_string(),
70            "device_type".to_string(),
71            "country".to_string(),
72        ]))
73}