61 lines
2.3 KiB
Rust
61 lines
2.3 KiB
Rust
|
|
//! Application layer - Use cases and orchestration logic
|
||
|
|
//!
|
||
|
|
//! This module implements business use cases by coordinating domain entities and
|
||
|
|
//! infrastructure services. It contains the application logic that orchestrates
|
||
|
|
//! domain behavior without implementing domain rules directly.
|
||
|
|
//!
|
||
|
|
//! # Architecture Principles
|
||
|
|
//!
|
||
|
|
//! - **Depends on Domain layer**: Uses domain entities, value objects, and traits
|
||
|
|
//! - **Framework-independent**: No dependencies on HTTP, database, or other infrastructure
|
||
|
|
//! - **Use case driven**: Each module represents a specific business use case
|
||
|
|
//! - **Testable in isolation**: Can be tested with mock infrastructure implementations
|
||
|
|
//!
|
||
|
|
//! # Planned Submodules
|
||
|
|
//!
|
||
|
|
//! - `relay`: Relay control use cases
|
||
|
|
//! - `get_status`: Retrieve current state of one or all relays
|
||
|
|
//! - `toggle_relay`: Switch relay on/off with validation
|
||
|
|
//! - `bulk_control`: Control multiple relays (all on, all off, pattern)
|
||
|
|
//! - `update_label`: Manage relay labels with persistence
|
||
|
|
//! - `get_health`: Check device health and connectivity
|
||
|
|
//!
|
||
|
|
//! # Use Case Pattern
|
||
|
|
//!
|
||
|
|
//! Each use case follows this pattern:
|
||
|
|
//! 1. Accept domain types as input (validated at boundary)
|
||
|
|
//! 2. Orchestrate domain entities and services
|
||
|
|
//! 3. Return domain types or application-specific results
|
||
|
|
//! 4. Depend on traits (RelayController, RelayLabelRepository), not concrete types
|
||
|
|
//!
|
||
|
|
//! # Example Use Case Structure
|
||
|
|
//!
|
||
|
|
//! ```rust,ignore
|
||
|
|
//! pub struct ToggleRelay {
|
||
|
|
//! controller: Arc<dyn RelayController>,
|
||
|
|
//! repository: Arc<dyn RelayLabelRepository>,
|
||
|
|
//! }
|
||
|
|
//!
|
||
|
|
//! impl ToggleRelay {
|
||
|
|
//! pub async fn execute(&self, relay_id: RelayId) -> Result<Relay, ApplicationError> {
|
||
|
|
//! // 1. Read current state
|
||
|
|
//! let current = self.controller.read_relay_state(relay_id).await?;
|
||
|
|
//!
|
||
|
|
//! // 2. Toggle state (domain logic)
|
||
|
|
//! let new_state = current.toggle();
|
||
|
|
//!
|
||
|
|
//! // 3. Write new state
|
||
|
|
//! self.controller.write_relay_state(relay_id, new_state).await?;
|
||
|
|
//!
|
||
|
|
//! // 4. Return updated relay
|
||
|
|
//! Ok(Relay::new(relay_id, new_state))
|
||
|
|
//! }
|
||
|
|
//! }
|
||
|
|
//! ```
|
||
|
|
//!
|
||
|
|
//! # References
|
||
|
|
//!
|
||
|
|
//! - Architecture: `specs/constitution.md` - Hexagonal Architecture principles
|
||
|
|
//! - Use cases: `specs/001-modbus-relay-control/plan.md` - Implementation plan
|
||
|
|
//! - Domain types: [`crate::domain`] - Domain entities and value objects
|