ironflow_cli/commands/stats.rs
1//! Stats commands: aggregate and historical.
2
3use anyhow::Result;
4use clap::{Args, Subcommand};
5use ironflow_sdk::IronflowClient;
6use ironflow_sdk::client::StatsHistoryParams;
7use uuid::Uuid;
8
9use crate::output;
10
11/// Stats subcommand arguments.
12///
13/// # Examples
14///
15/// ```
16/// use ironflow_cli::commands::stats::StatsArgs;
17/// ```
18#[derive(Debug, Args)]
19pub struct StatsArgs {
20 /// Stats subcommand. Omit for aggregate stats.
21 #[command(subcommand)]
22 pub command: Option<StatsCommands>,
23}
24
25/// Available stats subcommands.
26///
27/// # Examples
28///
29/// ```
30/// use ironflow_cli::commands::stats::StatsCommands;
31/// ```
32#[derive(Debug, Subcommand)]
33pub enum StatsCommands {
34 /// Show time-bucketed historical statistics.
35 History {
36 /// Filter by workflow name (case-insensitive substring match).
37 #[arg(long)]
38 workflow: Option<String>,
39 /// Time period: 24h, 7d, 30d, 90d. Defaults to 7d.
40 #[arg(long, default_value = "7d")]
41 period: String,
42 /// Bucket granularity: 1h, 1d, 1w. Auto-derived from period when omitted.
43 #[arg(long)]
44 granularity: Option<String>,
45 /// Filter by run status (pending, running, completed, failed, etc.).
46 #[arg(long)]
47 status: Option<String>,
48 /// Filter by labels. Comma-separated `key:value` pairs.
49 #[arg(long)]
50 label: Option<String>,
51 /// Filter by step presence (only applies to completed/cancelled runs).
52 #[arg(long)]
53 has_steps: Option<bool>,
54 /// Filter by author: the user ID that triggered the run.
55 ///
56 /// Also matches runs triggered by one of that user's API keys.
57 #[arg(long)]
58 created_by: Option<Uuid>,
59 },
60}
61
62/// Execute the `stats` command tree.
63///
64/// # Errors
65///
66/// Returns an error on API failure.
67pub async fn execute(client: &IronflowClient, args: &StatsArgs, json_mode: bool) -> Result<()> {
68 match &args.command {
69 None => {
70 let response = client.get_stats().await?;
71 output::print_output(json_mode, &response, || output::stats_table(&response.data))?;
72 }
73 Some(StatsCommands::History {
74 workflow,
75 period,
76 granularity,
77 status,
78 label,
79 has_steps,
80 created_by,
81 }) => {
82 let params = StatsHistoryParams {
83 workflow: workflow.as_deref(),
84 period: Some(period.as_str()),
85 granularity: granularity.as_deref(),
86 status: status.as_deref(),
87 label: label.as_deref(),
88 has_steps: *has_steps,
89 created_by: *created_by,
90 };
91 let response = client.stats_history_with(¶ms).await?;
92 output::print_output(json_mode, &response, || {
93 output::stats_history_table(&response.data)
94 })?;
95 }
96 }
97 Ok(())
98}