koprogo_api/infrastructure/web/handlers/
dashboard_handlers.rs

1// Infrastructure Web Handlers: Dashboard
2//
3// HTTP handlers for dashboard endpoints
4
5use crate::infrastructure::web::{AppState, AuthenticatedUser};
6use actix_web::{get, web, HttpResponse, Responder};
7
8/// GET /api/v1/dashboard/accountant/stats
9/// Get accountant dashboard statistics
10#[get("/dashboard/accountant/stats")]
11pub async fn get_accountant_stats(
12    state: web::Data<AppState>,
13    user: AuthenticatedUser,
14) -> impl Responder {
15    let organization_id = match user.organization_id {
16        Some(org_id) => org_id,
17        None => {
18            return HttpResponse::BadRequest().body("User does not belong to an organization");
19        }
20    };
21
22    match state
23        .dashboard_use_cases
24        .get_accountant_stats(organization_id)
25        .await
26    {
27        Ok(stats) => HttpResponse::Ok().json(stats),
28        Err(e) => HttpResponse::InternalServerError().body(e),
29    }
30}
31
32/// GET /api/v1/dashboard/accountant/transactions?limit=10
33/// Get recent transactions for dashboard
34#[get("/dashboard/accountant/transactions")]
35pub async fn get_recent_transactions(
36    state: web::Data<AppState>,
37    user: AuthenticatedUser,
38    query: web::Query<RecentTransactionsQuery>,
39) -> impl Responder {
40    let organization_id = match user.organization_id {
41        Some(org_id) => org_id,
42        None => {
43            return HttpResponse::BadRequest().body("User does not belong to an organization");
44        }
45    };
46
47    let limit = query.limit.unwrap_or(10).min(50); // Max 50 transactions
48
49    match state
50        .dashboard_use_cases
51        .get_recent_transactions(organization_id, limit)
52        .await
53    {
54        Ok(transactions) => HttpResponse::Ok().json(transactions),
55        Err(e) => HttpResponse::InternalServerError().body(e),
56    }
57}
58
59#[derive(serde::Deserialize)]
60pub struct RecentTransactionsQuery {
61    pub limit: Option<usize>,
62}