Skip to main content

ralph/cli/queue/
dashboard.rs

1//! Queue dashboard subcommand - aggregated analytics for GUI clients.
2//!
3//! Responsibilities:
4//! - Load queue, done, and productivity data once.
5//! - Delegate to reports::dashboard for aggregation.
6//! - Emit a single JSON payload combining all dashboard sections.
7//!
8//! Not handled here:
9//! - Report data structures (see reports/dashboard.rs).
10//! - Queue file loading (see crate::queue).
11//!
12//! Invariants/assumptions:
13//! - Dashboard only supports JSON output (designed for GUI consumption).
14//! - Productivity stats are optional (may not exist for new projects).
15
16use anyhow::Result;
17use clap::Args;
18
19use crate::cli::load_and_validate_queues;
20use crate::config::Resolved;
21use crate::productivity;
22use crate::reports;
23
24/// Arguments for `ralph queue dashboard`.
25#[derive(Args)]
26#[command(
27    after_long_help = "Examples:\n  ralph queue dashboard\n  ralph queue dashboard --days 30\n  ralph queue dashboard --days 7\n\n\
28The dashboard command returns all analytics data in a single JSON payload for GUI clients.\n\
29Each section includes a 'status' field ('ok' or 'unavailable') for graceful partial failure handling."
30)]
31pub struct QueueDashboardArgs {
32    /// Number of days for time-based analytics (velocity, burndown, history).
33    #[arg(long, default_value_t = 30)]
34    pub days: u32,
35}
36
37pub(crate) fn handle(resolved: &Resolved, args: QueueDashboardArgs) -> Result<()> {
38    let (queue_file, done_file) = load_and_validate_queues(resolved, true)?;
39    let done_ref = done_file
40        .as_ref()
41        .filter(|d| !d.tasks.is_empty() || resolved.done_path.exists());
42
43    // Load productivity stats (optional - may not exist for new projects)
44    let cache_dir = resolved.repo_root.join(".ralph/cache");
45    let productivity_stats = productivity::load_productivity_stats(&cache_dir)
46        .inspect_err(|e| log::debug!("Dashboard: productivity stats unavailable: {}", e))
47        .ok();
48
49    let report = reports::build_dashboard_report(
50        &queue_file,
51        done_ref,
52        productivity_stats.as_ref(),
53        args.days,
54    );
55
56    // Dashboard only supports JSON output (designed for GUI consumption)
57    reports::print_dashboard(&report)?;
58
59    Ok(())
60}