Skip to main content

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(&params).await?;
92            output::print_output(json_mode, &response, || {
93                output::stats_history_table(&response.data)
94            })?;
95        }
96    }
97    Ok(())
98}