Compare commits

..

3 Commits

4 changed files with 9 additions and 0 deletions

1
Cargo.lock generated
View File

@@ -1352,6 +1352,7 @@ dependencies = [
"async-trait", "async-trait",
"chrono", "chrono",
"email_address", "email_address",
"futures",
"thiserror 2.0.18", "thiserror 2.0.18",
"uuid", "uuid",
] ]

View File

@@ -24,6 +24,7 @@ resolver = "2"
[workspace.dependencies] [workspace.dependencies]
tokio = { version = "1.0", features = ["full"] } tokio = { version = "1.0", features = ["full"] }
futures = "0.3"
dotenvy = "0.15" dotenvy = "0.15"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"

View File

@@ -9,5 +9,6 @@ chrono = { workspace = true }
async-trait = { workspace = true } async-trait = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
futures = { workspace = true }
email_address = "0.2.9" email_address = "0.2.9"

View File

@@ -173,6 +173,12 @@ pub trait EventPublisher: Send + Sync {
async fn publish(&self, event: &DomainEvent) -> Result<(), DomainError>; async fn publish(&self, event: &DomainEvent) -> Result<(), DomainError>;
} }
pub trait EventConsumer: Send + Sync {
/// Returns a stream of domain events. Implementations decide whether this
/// is push-based (NATS) or poll-based (DB queue) — callers don't care.
fn consume(&self) -> futures::stream::BoxStream<'_, Result<DomainEvent, DomainError>>;
}
#[async_trait] #[async_trait]
pub trait PasswordHasher: Send + Sync { pub trait PasswordHasher: Send + Sync {
async fn hash(&self, plain_password: &str) -> Result<PasswordHash, DomainError>; async fn hash(&self, plain_password: &str) -> Result<PasswordHash, DomainError>;