ralph/cli/queue/
dashboard.rs1use 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#[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 #[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 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 reports::print_dashboard(&report)?;
58
59 Ok(())
60}