WP-01: domain contract and failing tests for auth and user management
Domain entities/ports, service stubs, 18 application unit tests with in-memory fakes, API integration tests for /api/auth and /api/users, Vitest specs for the auth store, login page and user form, Playwright auth/user-management flow. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
42
backend/crates/domain/src/ports.rs
Normal file
42
backend/crates/domain/src/ports.rs
Normal file
@ -0,0 +1,42 @@
|
||||
//! Ports implemented by the infrastructure layer.
|
||||
use async_trait::async_trait;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::auth::{AccessClaims, AuthEvent, RefreshToken};
|
||||
use crate::user::{User, UserUpdate};
|
||||
use crate::DomainError;
|
||||
|
||||
#[async_trait]
|
||||
pub trait UserRepository: Send + Sync {
|
||||
async fn find_by_id(&self, id: Uuid) -> Result<Option<User>, DomainError>;
|
||||
async fn find_by_email(&self, email: &str) -> Result<Option<User>, DomainError>;
|
||||
async fn list(&self) -> Result<Vec<User>, DomainError>;
|
||||
async fn count(&self) -> Result<u64, DomainError>;
|
||||
async fn count_active_admins(&self) -> Result<u64, DomainError>;
|
||||
async fn insert(&self, user: &User) -> Result<(), DomainError>;
|
||||
async fn update(&self, id: Uuid, update: &UserUpdate) -> Result<User, DomainError>;
|
||||
async fn set_password_hash(&self, id: Uuid, hash: &str) -> Result<(), DomainError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait RefreshTokenRepository: Send + Sync {
|
||||
async fn insert(&self, token: &RefreshToken) -> Result<(), DomainError>;
|
||||
async fn find_by_hash(&self, hash: &str) -> Result<Option<RefreshToken>, DomainError>;
|
||||
async fn revoke(&self, id: Uuid) -> Result<(), DomainError>;
|
||||
async fn revoke_family(&self, family: Uuid) -> Result<(), DomainError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait AuditLog: Send + Sync {
|
||||
async fn record(&self, event: &AuthEvent) -> Result<(), DomainError>;
|
||||
}
|
||||
|
||||
pub trait PasswordHasher: Send + Sync {
|
||||
fn hash(&self, password: &str) -> Result<String, DomainError>;
|
||||
fn verify(&self, password: &str, hash: &str) -> bool;
|
||||
}
|
||||
|
||||
pub trait AccessTokenIssuer: Send + Sync {
|
||||
fn issue(&self, user: &User) -> Result<String, DomainError>;
|
||||
fn verify(&self, token: &str) -> Result<AccessClaims, DomainError>;
|
||||
}
|
||||
Reference in New Issue
Block a user