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;
7use clap::Args;
8use systemprompt_database::DbPool;
9use systemprompt_files::FileRepository;
10use systemprompt_identifiers::{ContentId, FileId};
11use systemprompt_runtime::AppContext;
12
13use crate::CliConfig;
14use crate::commands::core::files::types::{FeaturedImageOutput, FileSummary};
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, config: &CliConfig) -> Result<CommandOutput> {
27    let ctx = AppContext::new().await?;
28    execute_with_pool(args, ctx.db_pool(), config).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::new(file_id_str);
42        service.set_featured(&file_id, &content_id).await?;
43
44        let output = FeaturedImageOutput {
45            content_id,
46            file: None,
47            message: "Featured image set successfully".to_owned(),
48        };
49
50        return Ok(CommandOutput::card_value("Featured Image Set", &output));
51    }
52
53    let file = service.find_featured_image(&content_id).await?;
54
55    let file_summary = file.map(|f| FileSummary {
56        id: FileId::new(f.id.to_string()),
57        path: f.path,
58        public_url: f.public_url,
59        mime_type: f.mime_type,
60        size_bytes: f.size_bytes,
61        ai_content: f.ai_content,
62        created_at: f.created_at,
63    });
64
65    let message = file_summary.as_ref().map_or_else(
66        || "No featured image set".to_owned(),
67        |f| format!("Featured image: {}", f.path),
68    );
69
70    let output = FeaturedImageOutput {
71        content_id,
72        file: file_summary,
73        message,
74    };
75
76    Ok(CommandOutput::card_value("Featured Image", &output))
77}