koprogo_api/infrastructure/web/handlers/
user_handlers.rs1use 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 UserResponse {
8 pub id: String,
9 pub email: String,
10 pub first_name: String,
11 pub last_name: String,
12 pub role: String,
13 pub organization_id: Option<String>,
14 pub is_active: bool,
15 pub created_at: DateTime<Utc>,
16}
17
18#[get("/users")]
20pub async fn list_users(state: web::Data<AppState>, user: AuthenticatedUser) -> impl Responder {
21 if user.role != "superadmin" {
23 return HttpResponse::Forbidden().json(serde_json::json!({
24 "error": "Only SuperAdmin can access all users"
25 }));
26 }
27
28 let result = sqlx::query!(
29 r#"
30 SELECT id, email, first_name, last_name, role, organization_id, is_active, created_at
31 FROM users
32 ORDER BY created_at DESC
33 "#
34 )
35 .fetch_all(&state.pool)
36 .await;
37
38 match result {
39 Ok(rows) => {
40 let users: Vec<UserResponse> = rows
41 .into_iter()
42 .map(|row| UserResponse {
43 id: row.id.to_string(),
44 email: row.email,
45 first_name: row.first_name,
46 last_name: row.last_name,
47 role: row.role,
48 organization_id: row.organization_id.map(|id| id.to_string()),
49 is_active: row.is_active,
50 created_at: row.created_at,
51 })
52 .collect();
53
54 HttpResponse::Ok().json(serde_json::json!({
55 "data": users
56 }))
57 }
58 Err(e) => HttpResponse::InternalServerError().json(serde_json::json!({
59 "error": format!("Failed to fetch users: {}", e)
60 })),
61 }
62}