systemprompt_cli/commands/core/content/
list.rs1use super::types::{ContentListOutput, ContentSummary};
2use crate::cli_settings::CliConfig;
3use crate::shared::CommandOutput;
4use anyhow::Result;
5use clap::Args;
6use systemprompt_content::ContentRepository;
7use systemprompt_database::DbPool;
8use systemprompt_identifiers::{LocaleCode, SourceId};
9use systemprompt_runtime::AppContext;
10
11#[derive(Debug, Args)]
12pub struct ListArgs {
13 #[arg(long, help = "Filter by source ID")]
14 pub source: Option<String>,
15
16 #[arg(long, help = "Filter by category ID")]
17 pub category: Option<String>,
18
19 #[arg(long, default_value = "20")]
20 pub limit: i64,
21
22 #[arg(long, default_value = "0")]
23 pub offset: i64,
24}
25
26pub async fn execute(args: ListArgs, 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: ListArgs,
33 pool: &DbPool,
34 _config: &CliConfig,
35) -> Result<CommandOutput> {
36 let repo = ContentRepository::new(pool)?;
37
38 let items = match &args.source {
39 Some(source_id) => {
40 let source = SourceId::new(source_id.clone());
41 repo.list_by_source(&source, &LocaleCode::new("en")).await?
42 },
43 None => repo.list(args.limit, args.offset).await?,
44 };
45
46 let summaries: Vec<ContentSummary> = items
47 .into_iter()
48 .filter(|c| {
49 args.category.as_ref().is_none_or(|cat| {
50 c.category_id
51 .as_ref()
52 .is_some_and(|cid| cid.as_str() == cat)
53 })
54 })
55 .map(|c| ContentSummary {
56 id: c.id,
57 slug: c.slug,
58 title: c.title,
59 kind: c.kind,
60 source_id: c.source_id,
61 category_id: c.category_id,
62 published_at: Some(c.published_at),
63 })
64 .collect();
65
66 let total = summaries.len() as i64;
67
68 let output = ContentListOutput {
69 items: summaries,
70 total,
71 limit: args.limit,
72 offset: args.offset,
73 };
74
75 Ok(CommandOutput::table_of(
76 vec!["id", "title", "kind", "source_id", "published_at"],
77 &output.items,
78 )
79 .with_title("Content"))
80}