use actix_web::{get, post, put, delete, web, HttpResponse, Responder}; use utoipa::{IntoParams, ToSchema}; use serde::Deserialize; use validator::Validate; use crate::middlewares::error::ApiError; use crate::models::user::{CreateUserRequest, UpdateUserRequest, User}; use crate::services::user_service::UserService; #[derive(Deserialize, IntoParams, ToSchema)] pub struct UserPath { pub id: String } #[utoipa::path( get, path = "/api/v1/users", responses( (status = 200, description = "Lista de usuários", body = [User]) ) )] #[get("/api/v1/users")] pub async fn list_users(svc: web::Data>) -> impl Responder { HttpResponse::Ok().json(svc.list()) } #[utoipa::path( get, path = "/api/v1/users/{id}", params(UserPath), responses( (status = 200, description = "Usuário encontrado", body = User), (status = 404, description = "Não encontrado", body = crate::middlewares::error::ApiErrorBody) ) )] #[get("/api/v1/users/{id}")] pub async fn get_user(path: web::Path, svc: web::Data>) -> Result { match svc.get(path.id.clone()) { Some(u) => Ok(HttpResponse::Ok().json(u)), None => Err(ApiError::NotFound("Usuário não encontrado".into())), } } #[utoipa::path( post, path = "/api/v1/users", request_body = CreateUserRequest, responses( (status = 201, description = "Usuário criado", body = User), (status = 400, description = "Erro de validação", body = crate::middlewares::error::ApiErrorBody) ) )] #[post("/api/v1/users")] pub async fn create_user(payload: web::Json, svc: web::Data>) -> Result { let mut req = payload.into_inner(); if let Err(e) = req.validate() { return Err(ApiError::BadRequest(format!("validação: {}", e))); } let user = svc.create(req); Ok(HttpResponse::Created().json(user)) } #[utoipa::path( put, path = "/api/v1/users/{id}", params(UserPath), request_body = UpdateUserRequest, responses( (status = 200, description = "Usuário atualizado", body = User), (status = 400, description = "Erro de validação", body = crate::middlewares::error::ApiErrorBody), (status = 404, description = "Não encontrado", body = crate::middlewares::error::ApiErrorBody) ) )] #[put("/api/v1/users/{id}")] pub async fn update_user(path: web::Path, payload: web::Json, svc: web::Data>) -> Result { let mut req = payload.into_inner(); if let Err(e) = req.validate() { return Err(ApiError::BadRequest(format!("validação: {}", e))); } match svc.update(path.id.clone(), req) { Some(u) => Ok(HttpResponse::Ok().json(u)), None => Err(ApiError::NotFound("Usuário não encontrado".into())), } } #[utoipa::path( delete, path = "/api/v1/users/{id}", params(UserPath), responses( (status = 204, description = "Usuário deletado"), (status = 404, description = "Não encontrado", body = crate::middlewares::error::ApiErrorBody) ) )] #[delete("/api/v1/users/{id}")] pub async fn delete_user(path: web::Path, svc: web::Data>) -> Result { if svc.delete(path.id.clone()) { Ok(HttpResponse::NoContent().finish()) } else { Err(ApiError::NotFound("Usuário não encontrado".into())) } }