Skip to main content

shared/domain/account/
model.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use sqlx::FromRow;
4use utoipa::ToSchema;
5
6use crate::domain::query::IntoBsonDocument;
7
8use super::super::serde::{
9    deserialize_datetime, deserialize_object_id, deserialize_object_id_as_string,
10    serialize_object_id_as_string,
11};
12
13#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, sqlx::Type)]
14pub enum AccountStatus {
15    Active,
16    Suspended,
17    Locked,
18    InvalidCredentials,
19}
20
21#[derive(Default, Debug, Clone, PartialEq, Eq, Deserialize, Serialize, FromRow, ToSchema)]
22#[schema(example = json!({"id": Some(String::default()), "user_id": String::default(), "password": String::default(), "verified": "false", "locked": "false", "created_at": "2026-02-19T22:42:23.467Z"}))]
23pub struct Account {
24    #[serde(
25        rename = "_id",
26        default,
27        skip_serializing_if = "Option::is_none",
28        deserialize_with = "deserialize_object_id_as_string"
29    )]
30    pub id: Option<String>,
31
32    #[sqlx(rename = "userId")]
33    #[serde(
34        rename = "userId",
35        default,
36        serialize_with = "serialize_object_id_as_string",
37        deserialize_with = "deserialize_object_id"
38    )]
39    pub user_id: String,
40
41    pub password: String,
42    pub locked: bool,
43    pub verified: bool,
44
45    #[sqlx(rename = "createdAt")]
46    #[serde(rename = "createdAt", deserialize_with = "deserialize_datetime")]
47    pub created_at: DateTime<Utc>,
48}
49
50impl Account {
51    pub fn user(user_id: &str) -> Self {
52        Self {
53            user_id: user_id.into(),
54            created_at: Utc::now(),
55            ..Default::default()
56        }
57    }
58}
59impl Account {
60    pub fn with_password(mut self, password: &str) -> Self {
61        self.password = password.into();
62        self
63    }
64}
65
66impl IntoBsonDocument for Account {
67    fn into_bson_document(self) -> Result<mongodb::bson::Document, mongodb::bson::ser::Error> {
68        let mut doc = mongodb::bson::to_document(&self)?;
69
70        for key in &["createdAt"] {
71            if let Some(mongodb::bson::Bson::String(s)) = doc.get(*key).cloned()
72                && let Ok(dt) = chrono::DateTime::parse_from_rfc3339(&s)
73            {
74                doc.insert(
75                    *key,
76                    mongodb::bson::Bson::DateTime(mongodb::bson::DateTime::from_millis(
77                        dt.timestamp_millis(),
78                    )),
79                );
80            }
81        }
82
83        Ok(doc)
84    }
85}