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::{ContentRepositories, 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 repositories = ContentRepositories::new(pool)?;
32 let service = LinkAnalyticsService::new(repositories.link, repositories.link_analytics);
33
34 let campaign_id = CampaignId::new(args.campaign_id.clone());
35 let performance = service
36 .get_campaign_performance(&campaign_id)
37 .await?
38 .ok_or_else(|| anyhow!("Campaign not found: {}", args.campaign_id))?;
39
40 let output = CampaignAnalyticsOutput {
41 campaign_id: performance.campaign_id,
42 total_clicks: performance.total_clicks,
43 link_count: performance.link_count,
44 unique_visitors: performance.unique_visitors.unwrap_or(0),
45 conversion_count: performance.conversion_count.unwrap_or(0),
46 };
47
48 Ok(CommandOutput::card_value("Campaign Analytics", &output))
49}