koprogo_api/infrastructure/web/handlers/
stats_handlers.rs

1use crate::infrastructure::web::{AppState, AuthenticatedUser};
2use actix_web::{get, web, HttpResponse, Responder};
3use serde::Serialize;
4
5#[derive(Serialize)]
6pub struct DashboardStats {
7    pub total_organizations: i64,
8    pub total_users: i64,
9    pub total_buildings: i64,
10    pub active_subscriptions: i64,
11    pub total_owners: i64,
12    pub total_units: i64,
13    pub total_expenses: i64,
14    pub total_meetings: i64,
15}
16
17/// Get dashboard statistics (SuperAdmin only)
18#[get("/stats/dashboard")]
19pub async fn get_dashboard_stats(
20    state: web::Data<AppState>,
21    user: AuthenticatedUser,
22) -> impl Responder {
23    // Only SuperAdmin can access these stats
24    if user.role != "superadmin" {
25        return HttpResponse::Forbidden().json(serde_json::json!({
26            "error": "Only SuperAdmin can access dashboard statistics"
27        }));
28    }
29
30    // Count organizations
31    let orgs_result = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM organizations")
32        .fetch_one(&state.pool)
33        .await;
34
35    // Count users
36    let users_result = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM users")
37        .fetch_one(&state.pool)
38        .await;
39
40    // Count buildings
41    let buildings_result = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM buildings")
42        .fetch_one(&state.pool)
43        .await;
44
45    // Count active subscriptions (organizations with is_active = true)
46    let active_subs_result =
47        sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM organizations WHERE is_active = true")
48            .fetch_one(&state.pool)
49            .await;
50
51    // Count owners
52    let owners_result = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM owners")
53        .fetch_one(&state.pool)
54        .await;
55
56    // Count units
57    let units_result = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM units")
58        .fetch_one(&state.pool)
59        .await;
60
61    // Count expenses
62    let expenses_result = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM expenses")
63        .fetch_one(&state.pool)
64        .await;
65
66    // Count meetings
67    let meetings_result = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM meetings")
68        .fetch_one(&state.pool)
69        .await;
70
71    // Handle errors
72    match (
73        orgs_result,
74        users_result,
75        buildings_result,
76        active_subs_result,
77        owners_result,
78        units_result,
79        expenses_result,
80        meetings_result,
81    ) {
82        (
83            Ok(total_organizations),
84            Ok(total_users),
85            Ok(total_buildings),
86            Ok(active_subscriptions),
87            Ok(total_owners),
88            Ok(total_units),
89            Ok(total_expenses),
90            Ok(total_meetings),
91        ) => {
92            let stats = DashboardStats {
93                total_organizations,
94                total_users,
95                total_buildings,
96                active_subscriptions,
97                total_owners,
98                total_units,
99                total_expenses,
100                total_meetings,
101            };
102            HttpResponse::Ok().json(stats)
103        }
104        _ => HttpResponse::InternalServerError().json(serde_json::json!({
105            "error": "Failed to fetch dashboard statistics"
106        })),
107    }
108}