application: auth bounded context (register, login)

This commit is contained in:
2026-07-12 01:49:34 +02:00
parent 848d4752e2
commit 2976600d12
14 changed files with 480 additions and 1 deletions

View File

@@ -0,0 +1,46 @@
use domain::events::DomainEvent;
use domain::models::User;
use domain::{DomainResult, Email, Password};
use super::commands::RegisterCommand;
use super::deps::AuthDeps;
/// Register a new local user.
///
/// Flow: validate email/password -> check duplicate -> hash password ->
/// create User (first user gets admin) -> save -> publish event -> return User.
pub async fn execute(deps: &AuthDeps, cmd: RegisterCommand) -> DomainResult<User> {
// Validate inputs via domain value objects
let email = Email::new(&cmd.email)?;
let password = Password::new(&cmd.password)?;
// Check for duplicate
if deps.user_query.find_by_email(email.as_ref()).await?.is_some() {
return Err(domain::DomainError::UserAlreadyExists(cmd.email));
}
// Hash password
let hash = deps.auth_service.hash_password(password.as_ref())?;
// Create user; first user gets admin
let mut user = User::new_local(email, hash);
if deps.user_query.count_users().await? == 0 {
user.promote_to_admin();
}
// Persist
deps.user_command.save(&user).await?;
// Publish event
deps.event_publisher
.publish(DomainEvent::UserRegistered {
user_id: user.id(),
})
.await?;
Ok(user)
}
#[cfg(test)]
#[path = "tests/register.rs"]
mod tests;