use crate::{ Activity, Agent, AgentMessage, Approval, ArtifactRecord, Company, Connector, Document, Goal, Project, Run, RunEventRecord, Task, Workspace, }; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct ProfileSnapshot { pub current_company_id: Option, pub profile_path: String, pub theme: String, pub locale: String, pub companies: Vec, pub connectors: Vec, pub workspaces: Vec, pub agents: Vec, pub goals: Vec, pub projects: Vec, pub tasks: Vec, pub approvals: Vec, pub runs: Vec, pub run_events: Vec, pub artifacts: Vec, pub activity: Vec, pub agent_messages: Vec, pub documents: Vec, } impl ProfileSnapshot { pub fn current_company(&self) -> Option<&Company> { self.current_company_id .as_ref() .and_then(|company_id| { self.companies .iter() .find(|company| &company.id == company_id) }) .or_else(|| self.companies.first()) } pub fn unread_messages(&self) -> usize { self.agent_messages .iter() .filter(|message| message.read_at.is_none()) .count() } pub fn pending_approvals(&self) -> usize { self.approvals .iter() .filter(|approval| approval.state == "pending") .count() } pub fn active_tasks(&self) -> usize { self.tasks .iter() .filter(|task| matches!(task.status.as_str(), "todo" | "in_progress" | "in_review")) .count() } pub fn active_runs(&self) -> usize { self.runs .iter() .filter(|run| { matches!( run.status.as_str(), "queued" | "running" | "waiting_approval" | "paused" ) }) .count() } }