Skip to main content

systemprompt_cli/commands/core/content/link/
show.rs

1//! `core content link show` command.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use crate::commands::core::content::types::LinkDetailOutput;
7use crate::context::CommandContext;
8use crate::shared::CommandOutput;
9use anyhow::{Result, anyhow};
10use clap::Args;
11use systemprompt_content::services::LinkGenerationService;
12
13const DEFAULT_BASE_URL: &str = "https://systemprompt.io";
14
15#[derive(Debug, Args)]
16pub struct ShowArgs {
17    #[arg(help = "Short code")]
18    pub short_code: String,
19}
20
21pub async fn execute(args: ShowArgs, ctx: &CommandContext) -> Result<CommandOutput> {
22    let pool = ctx.db_pool().await?;
23    let service = LinkGenerationService::new(&pool)?;
24
25    let link = service
26        .get_link_by_short_code(&args.short_code)
27        .await?
28        .ok_or_else(|| anyhow!("Link not found: {}", args.short_code))?;
29
30    let full_url = link.get_full_url();
31    let short_url = format!("{}/r/{}", DEFAULT_BASE_URL, link.short_code);
32
33    let output = LinkDetailOutput {
34        id: link.id,
35        short_code: link.short_code,
36        target_url: link.target_url,
37        full_url: if full_url == short_url {
38            short_url
39        } else {
40            full_url
41        },
42        link_type: link.link_type,
43        campaign_id: link.campaign_id,
44        campaign_name: link.campaign_name,
45        source_content_id: link.source_content_id,
46        click_count: link.click_count.unwrap_or(0),
47        unique_click_count: link.unique_click_count.unwrap_or(0),
48        conversion_count: link.conversion_count.unwrap_or(0),
49        is_active: link.is_active.unwrap_or(true),
50        created_at: link.created_at,
51    };
52
53    Ok(CommandOutput::card_value("Link Details", &output))
54}