diff --git a/crates/domain/src/errors.rs b/crates/domain/src/errors.rs index 17d04ed..14822ab 100644 --- a/crates/domain/src/errors.rs +++ b/crates/domain/src/errors.rs @@ -6,8 +6,12 @@ pub enum DomainError { Conflict(String), #[error("Unauthorized: {0}")] Unauthorized(String), + #[error("Forbidden: {0}")] + Forbidden(String), #[error("Validation error: {0}")] Validation(String), + #[error("Quota exceeded: {0}")] + QuotaExceeded(String), #[error("Internal error: {0}")] Internal(String), } diff --git a/crates/domain/src/events.rs b/crates/domain/src/events.rs index 63bf242..8353d20 100644 --- a/crates/domain/src/events.rs +++ b/crates/domain/src/events.rs @@ -1,7 +1,49 @@ -use uuid::Uuid; +use crate::value_objects::{DateTimeStamp, SystemId}; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub enum DomainEvent { - UserRegistered { user_id: Uuid }, - UserLoggedIn { user_id: Uuid }, + AssetIngested { + asset_id: SystemId, + owner_user_id: SystemId, + timestamp: DateTimeStamp, + }, + MetadataUpdated { + asset_id: SystemId, + updated_by: SystemId, + timestamp: DateTimeStamp, + }, + AssetDeleted { + asset_id: SystemId, + deleted_by: SystemId, + timestamp: DateTimeStamp, + }, + ShareCreated { + scope_id: SystemId, + shareable_id: SystemId, + created_by: SystemId, + timestamp: DateTimeStamp, + }, + ShareRevoked { + scope_id: SystemId, + revoked_by: SystemId, + timestamp: DateTimeStamp, + }, + SidecarSyncRequested { + asset_id: SystemId, + timestamp: DateTimeStamp, + }, + JobEnqueued { + job_id: SystemId, + job_type: String, + timestamp: DateTimeStamp, + }, + JobCompleted { + job_id: SystemId, + timestamp: DateTimeStamp, + }, + JobFailed { + job_id: SystemId, + error: String, + timestamp: DateTimeStamp, + }, } diff --git a/crates/domain/src/lib.rs b/crates/domain/src/lib.rs index 3df2e20..16d4b74 100644 --- a/crates/domain/src/lib.rs +++ b/crates/domain/src/lib.rs @@ -2,4 +2,5 @@ pub mod entities; pub mod errors; pub mod events; pub mod ports; +pub mod services; pub mod value_objects; diff --git a/crates/domain/src/services/metadata_resolver.rs b/crates/domain/src/services/metadata_resolver.rs new file mode 100644 index 0000000..4829705 --- /dev/null +++ b/crates/domain/src/services/metadata_resolver.rs @@ -0,0 +1 @@ +// Metadata resolver — will be implemented in Task 9 diff --git a/crates/domain/src/services/mod.rs b/crates/domain/src/services/mod.rs new file mode 100644 index 0000000..3233e22 --- /dev/null +++ b/crates/domain/src/services/mod.rs @@ -0,0 +1,3 @@ +pub mod metadata_resolver; +pub mod permission_service; +pub mod quota_checker; diff --git a/crates/domain/src/services/permission_service.rs b/crates/domain/src/services/permission_service.rs new file mode 100644 index 0000000..8ecaa70 --- /dev/null +++ b/crates/domain/src/services/permission_service.rs @@ -0,0 +1 @@ +// Permission service — will be implemented in Task 5 diff --git a/crates/domain/src/services/quota_checker.rs b/crates/domain/src/services/quota_checker.rs new file mode 100644 index 0000000..bc7de8e --- /dev/null +++ b/crates/domain/src/services/quota_checker.rs @@ -0,0 +1 @@ +// Quota checker — will be implemented in Task 7 diff --git a/crates/domain/tests/domain_tests.rs b/crates/domain/tests/domain_tests.rs index f696642..abe1467 100644 --- a/crates/domain/tests/domain_tests.rs +++ b/crates/domain/tests/domain_tests.rs @@ -1 +1,2 @@ +mod events; mod value_objects; diff --git a/crates/domain/tests/events.rs b/crates/domain/tests/events.rs new file mode 100644 index 0000000..47489e2 --- /dev/null +++ b/crates/domain/tests/events.rs @@ -0,0 +1,14 @@ +use domain::events::DomainEvent; +use domain::value_objects::{DateTimeStamp, SystemId}; + +#[test] +fn asset_ingested_serde_roundtrip() { + let event = DomainEvent::AssetIngested { + asset_id: SystemId::new(), + owner_user_id: SystemId::new(), + timestamp: DateTimeStamp::now(), + }; + let json = serde_json::to_string(&event).unwrap(); + let back: DomainEvent = serde_json::from_str(&json).unwrap(); + assert!(matches!(back, DomainEvent::AssetIngested { .. })); +} diff --git a/crates/presentation/src/errors.rs b/crates/presentation/src/errors.rs index 9d65efe..10bfa31 100644 --- a/crates/presentation/src/errors.rs +++ b/crates/presentation/src/errors.rs @@ -14,7 +14,9 @@ impl IntoResponse for AppError { DomainError::NotFound(msg) => (StatusCode::NOT_FOUND, msg.clone()), DomainError::Conflict(msg) => (StatusCode::CONFLICT, msg.clone()), DomainError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg.clone()), + DomainError::Forbidden(msg) => (StatusCode::FORBIDDEN, msg.clone()), DomainError::Validation(msg) => (StatusCode::UNPROCESSABLE_ENTITY, msg.clone()), + DomainError::QuotaExceeded(msg) => (StatusCode::PAYLOAD_TOO_LARGE, msg.clone()), DomainError::Internal(msg) => { tracing::error!("Internal error: {msg}"); (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error".to_string())