Skip to main content

systemprompt_cli/commands/core/content/files/
featured.rs

1//! `core content files featured` command setting the featured image.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use anyhow::{Result, anyhow};
7use clap::Args;
8use systemprompt_database::DbPool;
9use systemprompt_files::FileRepository;
10use systemprompt_identifiers::{ContentId, FileId};
11
12use crate::CliConfig;
13use crate::commands::core::files::types::{FeaturedImageOutput, FileSummary};
14use crate::context::CommandContext;
15use crate::shared::CommandOutput;
16
17#[derive(Debug, Clone, Args)]
18pub struct FeaturedArgs {
19    #[arg(value_name = "CONTENT_ID", help = "Content ID")]
20    pub content: String,
21
22    #[arg(long, help = "Set featured image")]
23    pub set: Option<String>,
24}
25
26pub(super) async fn execute(args: FeaturedArgs, ctx: &CommandContext) -> Result<CommandOutput> {
27    let app = ctx.app_context().await?;
28    execute_with_pool(args, app.db_pool(), &ctx.cli).await
29}
30
31pub async fn execute_with_pool(
32    args: FeaturedArgs,
33    pool: &DbPool,
34    _config: &CliConfig,
35) -> Result<CommandOutput> {
36    let service = FileRepository::new(pool);
37
38    let content_id = ContentId::new(args.content.clone());
39
40    if let Some(file_id_str) = args.set {
41        let file_id = FileId::try_new(&file_id_str)
42            .map_err(|e| anyhow!("Invalid file ID '{}': {}", file_id_str, e))?;
43        service.set_featured(&file_id, &content_id).await?;
44
45        let output = FeaturedImageOutput {
46            content_id,
47            file: None,
48            message: "Featured image set successfully".to_owned(),
49        };
50
51        return Ok(CommandOutput::card_value("Featured Image Set", &output));
52    }
53
54    let file = service.find_featured_image(&content_id).await?;
55
56    let file_summary = file.map(|f| FileSummary {
57        id: f.id,
58        path: f.path,
59        public_url: f.public_url,
60        mime_type: f.mime_type,
61        size_bytes: f.size_bytes,
62        ai_content: f.ai_content,
63        created_at: f.created_at,
64    });
65
66    let message = file_summary.as_ref().map_or_else(
67        || "No featured image set".to_owned(),
68        |f| format!("Featured image: {}", f.path),
69    );
70
71    let output = FeaturedImageOutput {
72        content_id,
73        file: file_summary,
74        message,
75    };
76
77    Ok(CommandOutput::card_value("Featured Image", &output))
78}