systemprompt_cli/commands/core/content/analytics/
campaign.rs1use crate::cli_settings::CliConfig;
7use crate::commands::core::content::types::CampaignAnalyticsOutput;
8use crate::context::CommandContext;
9use crate::shared::CommandOutput;
10use anyhow::{Result, anyhow};
11use clap::Args;
12use systemprompt_content::LinkAnalyticsService;
13use systemprompt_database::DbPool;
14use systemprompt_identifiers::CampaignId;
15
16#[derive(Debug, Args)]
17pub struct CampaignArgs {
18 #[arg(help = "Campaign ID")]
19 pub campaign_id: String,
20}
21
22pub async fn execute(args: CampaignArgs, ctx: &CommandContext) -> Result<CommandOutput> {
23 execute_with_pool(args, &ctx.db_pool().await?, &ctx.cli).await
24}
25
26pub async fn execute_with_pool(
27 args: CampaignArgs,
28 pool: &DbPool,
29 _config: &CliConfig,
30) -> Result<CommandOutput> {
31 let service = LinkAnalyticsService::new(pool)?;
32
33 let campaign_id = CampaignId::new(args.campaign_id.clone());
34 let performance = service
35 .get_campaign_performance(&campaign_id)
36 .await?
37 .ok_or_else(|| anyhow!("Campaign not found: {}", args.campaign_id))?;
38
39 let output = CampaignAnalyticsOutput {
40 campaign_id: performance.campaign_id,
41 total_clicks: performance.total_clicks,
42 link_count: performance.link_count,
43 unique_visitors: performance.unique_visitors.unwrap_or(0),
44 conversion_count: performance.conversion_count.unwrap_or(0),
45 };
46
47 Ok(CommandOutput::card_value("Campaign Analytics", &output))
48}