Skip to main content

ironflow_api/entities/
user.rs

1//! User request and response DTOs.
2
3use chrono::{DateTime, Utc};
4use ironflow_store::entities::User;
5use serde::{Deserialize, Serialize};
6use uuid::Uuid;
7use validator::Validate;
8
9/// Response DTO for a user (never exposes password hash).
10#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
11#[derive(Debug, Serialize)]
12pub struct UserResponse {
13    /// User ID.
14    pub id: Uuid,
15    /// Email address.
16    pub email: String,
17    /// Display username.
18    pub username: String,
19    /// Whether the user is an admin.
20    pub is_admin: bool,
21    /// Creation timestamp.
22    pub created_at: DateTime<Utc>,
23    /// Last update timestamp.
24    pub updated_at: DateTime<Utc>,
25}
26
27impl From<User> for UserResponse {
28    fn from(user: User) -> Self {
29        Self {
30            id: user.id,
31            email: user.email,
32            username: user.username,
33            is_admin: user.is_admin,
34            created_at: user.created_at,
35            updated_at: user.updated_at,
36        }
37    }
38}
39
40/// Request body for creating a user (admin only).
41#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
42#[derive(Debug, Deserialize, Validate)]
43pub struct CreateUserRequest {
44    /// Email address.
45    #[validate(email)]
46    pub email: String,
47    /// Display username.
48    #[validate(length(min = 3, message = "username must be at least 3 characters"))]
49    pub username: String,
50    /// Plaintext password (min 8 characters).
51    #[validate(length(min = 8, message = "password must be at least 8 characters"))]
52    pub password: String,
53    /// Whether the new user should be an admin.
54    pub is_admin: bool,
55}
56
57/// Request body for updating a user's role (admin only).
58#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
59#[derive(Debug, Deserialize)]
60pub struct UpdateRoleRequest {
61    /// New admin status.
62    pub is_admin: bool,
63}