koprogo_api/infrastructure/web/handlers/
organization_handlers.rs

1use crate::infrastructure::web::{AppState, AuthenticatedUser};
2use actix_web::{get, web, HttpResponse, Responder};
3use chrono::{DateTime, Utc};
4use serde::Serialize;
5
6#[derive(Serialize)]
7pub struct OrganizationResponse {
8    pub id: String,
9    pub name: String,
10    pub slug: String,
11    pub contact_email: String,
12    pub contact_phone: Option<String>,
13    pub subscription_plan: String,
14    pub max_buildings: i32,
15    pub max_users: i32,
16    pub is_active: bool,
17    pub created_at: DateTime<Utc>,
18}
19
20/// List all organizations (SuperAdmin only)
21#[get("/organizations")]
22pub async fn list_organizations(
23    state: web::Data<AppState>,
24    user: AuthenticatedUser,
25) -> impl Responder {
26    // Only SuperAdmin can access all organizations
27    if user.role != "superadmin" {
28        return HttpResponse::Forbidden().json(serde_json::json!({
29            "error": "Only SuperAdmin can access all organizations"
30        }));
31    }
32
33    let result = sqlx::query!(
34        r#"
35        SELECT id, name, slug, contact_email, contact_phone, subscription_plan, max_buildings, max_users, is_active, created_at
36        FROM organizations
37        ORDER BY created_at DESC
38        "#
39    )
40    .fetch_all(&state.pool)
41    .await;
42
43    match result {
44        Ok(rows) => {
45            let organizations: Vec<OrganizationResponse> = rows
46                .into_iter()
47                .map(|row| OrganizationResponse {
48                    id: row.id.to_string(),
49                    name: row.name,
50                    slug: row.slug,
51                    contact_email: row.contact_email,
52                    contact_phone: row.contact_phone,
53                    subscription_plan: row.subscription_plan,
54                    max_buildings: row.max_buildings,
55                    max_users: row.max_users,
56                    is_active: row.is_active,
57                    created_at: row.created_at,
58                })
59                .collect();
60
61            HttpResponse::Ok().json(serde_json::json!({
62                "data": organizations
63            }))
64        }
65        Err(e) => HttpResponse::InternalServerError().json(serde_json::json!({
66            "error": format!("Failed to fetch organizations: {}", e)
67        })),
68    }
69}