koprogo_api/application/use_cases/
stats_use_cases.rs1use crate::application::dto::{
2 AdminDashboardStats, SeedDataStats, SyndicDashboardStats, UrgentTask,
3};
4use crate::application::ports::StatsRepository;
5use std::sync::Arc;
6use uuid::Uuid;
7
8pub struct StatsUseCases {
9 repo: Arc<dyn StatsRepository>,
10}
11
12impl StatsUseCases {
13 pub fn new(repo: Arc<dyn StatsRepository>) -> Self {
14 Self { repo }
15 }
16
17 pub async fn get_admin_dashboard_stats(&self) -> Result<AdminDashboardStats, String> {
18 self.repo.get_admin_dashboard_stats().await
19 }
20
21 pub async fn get_seed_data_stats(&self) -> Result<SeedDataStats, String> {
22 self.repo.get_seed_data_stats().await
23 }
24
25 pub async fn get_syndic_stats(
26 &self,
27 organization_id: Uuid,
28 ) -> Result<SyndicDashboardStats, String> {
29 self.repo.get_syndic_stats(organization_id).await
30 }
31
32 pub async fn get_owner_stats_by_user_id(
34 &self,
35 user_id: Uuid,
36 ) -> Result<SyndicDashboardStats, String> {
37 match self.repo.find_owner_id_by_user_id(user_id).await? {
38 None => Ok(SyndicDashboardStats {
39 total_buildings: 0,
40 total_units: 0,
41 total_owners: 0,
42 pending_expenses_count: 0,
43 pending_expenses_amount: 0.0,
44 next_meeting: None,
45 }),
46 Some(owner_id) => self.repo.get_owner_stats(owner_id).await,
47 }
48 }
49
50 pub async fn get_syndic_urgent_tasks(
51 &self,
52 organization_id: Uuid,
53 ) -> Result<Vec<UrgentTask>, String> {
54 self.repo.get_syndic_urgent_tasks(organization_id).await
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61 use async_trait::async_trait;
62
63 struct MockStatsRepository {
64 owner_id: Option<Uuid>,
65 }
66
67 #[async_trait]
68 impl StatsRepository for MockStatsRepository {
69 async fn get_admin_dashboard_stats(&self) -> Result<AdminDashboardStats, String> {
70 Ok(AdminDashboardStats {
71 total_organizations: 5,
72 total_users: 50,
73 total_buildings: 10,
74 active_subscriptions: 4,
75 total_owners: 30,
76 total_units: 100,
77 total_expenses: 200,
78 total_meetings: 20,
79 })
80 }
81 async fn get_seed_data_stats(&self) -> Result<SeedDataStats, String> {
82 Ok(SeedDataStats {
83 seed_organizations: 1,
84 production_organizations: 4,
85 seed_buildings: 3,
86 seed_units: 15,
87 seed_owners: 10,
88 seed_unit_owners: 15,
89 seed_expenses: 20,
90 seed_meetings: 5,
91 seed_users: 8,
92 })
93 }
94 async fn get_syndic_stats(
95 &self,
96 _organization_id: Uuid,
97 ) -> Result<SyndicDashboardStats, String> {
98 Ok(SyndicDashboardStats {
99 total_buildings: 2,
100 total_units: 10,
101 total_owners: 8,
102 pending_expenses_count: 3,
103 pending_expenses_amount: 1500.0,
104 next_meeting: None,
105 })
106 }
107 async fn get_owner_stats(&self, _owner_id: Uuid) -> Result<SyndicDashboardStats, String> {
108 Ok(SyndicDashboardStats {
109 total_buildings: 1,
110 total_units: 2,
111 total_owners: 5,
112 pending_expenses_count: 1,
113 pending_expenses_amount: 500.0,
114 next_meeting: None,
115 })
116 }
117 async fn find_owner_id_by_user_id(&self, _user_id: Uuid) -> Result<Option<Uuid>, String> {
118 Ok(self.owner_id)
119 }
120 async fn get_syndic_urgent_tasks(
121 &self,
122 _organization_id: Uuid,
123 ) -> Result<Vec<UrgentTask>, String> {
124 Ok(vec![])
125 }
126 }
127
128 #[tokio::test]
129 async fn test_get_admin_dashboard_stats() {
130 let repo = Arc::new(MockStatsRepository { owner_id: None });
131 let use_cases = StatsUseCases::new(repo);
132 let stats = use_cases.get_admin_dashboard_stats().await.unwrap();
133 assert_eq!(stats.total_organizations, 5);
134 assert_eq!(stats.total_buildings, 10);
135 }
136
137 #[tokio::test]
138 async fn test_get_owner_stats_no_owner_record_returns_empty() {
139 let repo = Arc::new(MockStatsRepository { owner_id: None });
140 let use_cases = StatsUseCases::new(repo);
141 let stats = use_cases
142 .get_owner_stats_by_user_id(Uuid::new_v4())
143 .await
144 .unwrap();
145 assert_eq!(stats.total_buildings, 0);
146 assert_eq!(stats.total_units, 0);
147 assert!(stats.next_meeting.is_none());
148 }
149
150 #[tokio::test]
151 async fn test_get_owner_stats_with_owner_record() {
152 let owner_id = Uuid::new_v4();
153 let repo = Arc::new(MockStatsRepository {
154 owner_id: Some(owner_id),
155 });
156 let use_cases = StatsUseCases::new(repo);
157 let stats = use_cases
158 .get_owner_stats_by_user_id(Uuid::new_v4())
159 .await
160 .unwrap();
161 assert_eq!(stats.total_buildings, 1);
162 assert_eq!(stats.pending_expenses_count, 1);
163 }
164}