domain: add cross-cutting value objects (SystemId, DateTimeStamp, Checksum, StructuredData)
This commit is contained in:
@@ -5,7 +5,7 @@ use domain::{
|
||||
entities::User,
|
||||
errors::DomainError,
|
||||
ports::{PasswordHasher, TokenIssuer, UserRepository},
|
||||
value_objects::{Email, PasswordHash, Role, UserId},
|
||||
value_objects::{Email, PasswordHash, SystemId},
|
||||
};
|
||||
|
||||
pub struct InMemoryUserRepository {
|
||||
@@ -28,7 +28,7 @@ impl Default for InMemoryUserRepository {
|
||||
|
||||
#[async_trait]
|
||||
impl UserRepository for InMemoryUserRepository {
|
||||
async fn find_by_id(&self, id: &UserId) -> Result<Option<User>, DomainError> {
|
||||
async fn find_by_id(&self, id: &SystemId) -> Result<Option<User>, DomainError> {
|
||||
Ok(self.users.lock().await.get(&id.to_string()).cloned())
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ impl UserRepository for InMemoryUserRepository {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete(&self, id: &UserId) -> Result<(), DomainError> {
|
||||
async fn delete(&self, id: &SystemId) -> Result<(), DomainError> {
|
||||
self.users.lock().await.remove(&id.to_string());
|
||||
Ok(())
|
||||
}
|
||||
@@ -65,15 +65,15 @@ pub struct StubTokenIssuer;
|
||||
|
||||
#[async_trait]
|
||||
impl TokenIssuer for StubTokenIssuer {
|
||||
async fn issue(&self, user_id: &UserId, _role: &Role) -> Result<String, DomainError> {
|
||||
async fn issue(&self, user_id: &SystemId, _role: &str) -> Result<String, DomainError> {
|
||||
Ok(format!("token:{user_id}"))
|
||||
}
|
||||
async fn verify(&self, token: &str) -> Result<(UserId, Role), DomainError> {
|
||||
async fn verify(&self, token: &str) -> Result<(SystemId, String), DomainError> {
|
||||
let id_str = token.strip_prefix("token:").ok_or_else(|| {
|
||||
DomainError::Unauthorized("Invalid stub token".to_string())
|
||||
})?;
|
||||
let uuid = uuid::Uuid::parse_str(id_str)
|
||||
.map_err(|_| DomainError::Unauthorized("Bad UUID in stub token".to_string()))?;
|
||||
Ok((UserId::from_uuid(uuid), Role::User))
|
||||
Ok((SystemId::from_uuid(uuid), "user".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::sync::Arc;
|
||||
use domain::{entities::User, errors::DomainError, ports::UserRepository, value_objects::UserId};
|
||||
use domain::{entities::User, errors::DomainError, ports::UserRepository, value_objects::SystemId};
|
||||
|
||||
pub struct GetProfile {
|
||||
repo: Arc<dyn UserRepository>,
|
||||
@@ -8,7 +8,7 @@ pub struct GetProfile {
|
||||
impl GetProfile {
|
||||
pub fn new(repo: Arc<dyn UserRepository>) -> Self { Self { repo } }
|
||||
|
||||
pub async fn execute(&self, user_id: &UserId) -> Result<User, DomainError> {
|
||||
pub async fn execute(&self, user_id: &SystemId) -> Result<User, DomainError> {
|
||||
self.repo.find_by_id(user_id).await?
|
||||
.ok_or_else(|| DomainError::NotFound(format!("User {user_id} not found")))
|
||||
}
|
||||
@@ -34,7 +34,7 @@ mod tests {
|
||||
async fn get_profile_returns_not_found() {
|
||||
let repo = Arc::new(InMemoryUserRepository::new());
|
||||
let uc = GetProfile::new(repo);
|
||||
let result = uc.execute(&UserId::new()).await;
|
||||
let result = uc.execute(&SystemId::new()).await;
|
||||
assert!(matches!(result, Err(DomainError::NotFound(_))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ impl LoginUser {
|
||||
if !valid {
|
||||
return Err(DomainError::Unauthorized("Invalid credentials".to_string()));
|
||||
}
|
||||
let token = self.issuer.issue(&user.id, &user.role).await?;
|
||||
let token = self.issuer.issue(&user.id, "user").await?;
|
||||
Ok((user, token))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use domain::{
|
||||
entities::User,
|
||||
errors::DomainError,
|
||||
ports::{PasswordHasher, UserRepository},
|
||||
value_objects::{Email, UserId},
|
||||
value_objects::{Email, SystemId},
|
||||
};
|
||||
|
||||
pub struct RegisterUser {
|
||||
@@ -25,7 +25,7 @@ impl RegisterUser {
|
||||
return Err(DomainError::Conflict(format!("Email {} is already registered", email.as_str())));
|
||||
}
|
||||
let hash = self.hasher.hash(password).await?;
|
||||
let user = User::new(UserId::new(), email, hash);
|
||||
let user = User::new(SystemId::new(), email, hash);
|
||||
self.repo.save(&user).await?;
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user