use super::{DateTime, Result, UserId, Utc, async_trait}; /// Aggregated statistics for the dashboard. #[derive(Debug, Clone, serde::Serialize)] pub struct DashboardStats { /// Number of tasks due today. pub tasks_due_today: i64, /// Number of tasks due within the next 7 days. pub tasks_due_this_week: i64, /// Number of overdue tasks. pub overdue_count: i64, /// Number of unread emails. pub unread_emails: i64, /// Number of events in the next 7 days. pub upcoming_events: i64, /// Number of active projects. pub active_projects: i64, /// Top tasks by urgency score. pub high_urgency_tasks: Vec, } /// A task with high urgency for dashboard display. #[derive(Debug, Clone, serde::Serialize)] pub struct HighUrgencyTask { /// Task ID as string. pub id: String, /// Task description. pub description: String, /// Calculated urgency score. pub urgency: f64, /// Task status. pub status: String, /// Due date if set, formatted as ISO string. pub due: Option, } /// Repository for dashboard statistics. #[async_trait] pub trait StatsRepository: Send + Sync { /// Computes aggregated dashboard statistics for a user. /// /// Calendar-day windows (`today_start`, `tomorrow_start`, `week_end`) are /// passed in as UTC instants derived from the user's *local* day, so "due /// today/this week" respect the user's timezone rather than UTC midnights. /// `now` is the reference instant for overdue/upcoming comparisons. async fn get_dashboard_stats( &self, user_id: UserId, now: DateTime, today_start: DateTime, tomorrow_start: DateTime, week_end: DateTime, ) -> Result; }