Phase 2.2: MongoDB connection and models

This commit is contained in:
goose 2026-02-14 15:37:02 -03:00
parent 1cf927f527
commit 154c3d1152
13 changed files with 544 additions and 5 deletions

View file

@ -0,0 +1,88 @@
use serde::{Deserialize, Serialize};
use mongodb::{bson::{doc, oid::ObjectId, DateTime}, Collection};
use chrono::{Utc, TimeZone};
use validator::Validate;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
pub id: Option<ObjectId>,
#[serde(rename = "userId")]
pub user_id: String,
#[serde(rename = "email")]
pub email: String,
#[serde(rename = "passwordHash")]
pub password_hash: String,
#[serde(rename = "encryptedRecoveryPhrase")]
pub encrypted_recovery_phrase: String,
#[serde(rename = "recoveryPhraseIv")]
pub recovery_phrase_iv: String,
#[serde(rename = "recoveryPhraseAuthTag")]
pub recovery_phrase_auth_tag: String,
#[serde(rename = "tokenVersion")]
pub token_version: i32,
#[serde(rename = "familyId")]
pub family_id: Option<String>,
#[serde(rename = "profileIds")]
pub profile_ids: Vec<String>,
#[serde(rename = "createdAt")]
pub created_at: DateTime,
#[serde(rename = "updatedAt")]
pub updated_at: DateTime,
}
#[derive(Debug, Deserialize, Validate)]
pub struct RegisterUserRequest {
#[validate(email)]
pub email: String,
pub password_hash: String,
pub encrypted_recovery_phrase: String,
pub recovery_phrase_iv: String,
pub recovery_phrase_auth_tag: String,
}
#[derive(Debug, Deserialize, Validate)]
pub struct LoginRequest {
#[validate(email)]
pub email: String,
pub password_hash: String,
}
pub struct UserRepository {
collection: Collection<User>,
}
impl UserRepository {
pub fn new(collection: Collection<User>) -> Self {
Self { collection }
}
pub async fn create(&self, user: &User) -> mongodb::error::Result<()> {
self.collection.insert_one(user, None).await?;
Ok(())
}
pub async fn find_by_email(&self, email: &str) -> mongodb::error::Result<Option<User>> {
self.collection
.find_one(doc! { "email": email }, None)
.await
}
pub async fn find_by_user_id(&self, user_id: &str) -> mongodb::error::Result<Option<User>> {
self.collection
.find_one(doc! { "userId": user_id }, None)
.await
}
pub async fn update_token_version(&self, user_id: &str, version: i32) -> mongodb::error::Result<()> {
let now = DateTime::now();
self.collection
.update_one(
doc! { "userId": user_id },
doc! { "$set": { "tokenVersion": version, "updatedAt": now } },
None,
)
.await?;
Ok(())
}
}