rust-port/wifi-densepose-rs/docs/ddd/README.md
This documentation describes the Domain-Driven Design (DDD) architecture for the WiFi-DensePose Rust port. The system uses WiFi Channel State Information (CSI) to perform non-invasive human pose estimation, translating radio frequency signals into body positioning data.
The Pose Estimation Domain represents the core business logic that provides unique value. This domain translates WiFi CSI signals into DensePose-compatible human body representations. The algorithms for modality translation (RF to visual features) and pose inference constitute the competitive advantage of the system.
Each bounded context contains aggregates that enforce invariants and maintain consistency:
Events flow between bounded contexts through an event-driven architecture:
CsiFrameReceived -> SignalProcessed -> PoseEstimated -> (MotionDetected | FallDetected)
Each aggregate root has a corresponding repository for persistence:
CsiFrameRepositorySessionRepositoryDeviceRepositoryPoseEstimateRepositoryCross-aggregate operations are handled by domain services:
PoseEstimationService - Orchestrates CSI-to-pose pipelineCalibrationService - Hardware calibration workflowsAlertService - Motion and fall detection alerts +------------------+
| Pose Domain |
| (Core Domain) |
+--------+---------+
|
+--------------+---------------+
| | |
+---------v----+ +------v------+ +-----v-------+
| Signal Domain| | Streaming | | Storage |
| (Upstream) | | Domain | | Domain |
+---------+----+ +------+------+ +------+------+
| | |
+--------------+----------------+
|
+--------v--------+
| Hardware Domain |
| (Foundation) |
+-----------------+
| Upstream | Downstream | Relationship |
|---|---|---|
| Hardware | Signal | Conformist |
| Signal | Pose | Customer-Supplier |
| Pose | Streaming | Published Language |
| Pose | Storage | Shared Kernel |
Each bounded context follows hexagonal (ports and adapters) architecture:
+--------------------+
| Application |
| Services |
+---------+----------+
|
+---------------+---------------+
| |
+---------v---------+ +---------v---------+
| Domain Layer | | Domain Layer |
| (Entities, VOs, | | (Aggregates, |
| Domain Events) | | Repositories) |
+---------+---------+ +---------+---------+
| |
+---------v---------+ +---------v---------+
| Infrastructure | | Infrastructure |
| (Adapters: DB, | | (Adapters: API, |
| Hardware, MQ) | | WebSocket) |
+-------------------+ +-------------------+
The system separates read and write operations:
ProcessCsiFrame, CreateSession, UpdateDeviceConfigGetCurrentPose, GetSessionHistory, GetDeviceStatusFor audit and replay capabilities, CSI processing events can be stored as an event log:
pub enum DomainEvent {
CsiFrameReceived(CsiFrameReceivedEvent),
SignalProcessed(SignalProcessedEvent),
PoseEstimated(PoseEstimatedEvent),
MotionDetected(MotionDetectedEvent),
FallDetected(FallDetectedEvent),
}
wifi-densepose-rs/
crates/
wifi-densepose-core/ # Shared kernel
src/
domain/
entities/
value_objects/
events/
wifi-densepose-signal/ # Signal bounded context
src/
domain/
application/
infrastructure/
wifi-densepose-nn/ # Pose bounded context
src/
domain/
application/
infrastructure/
wifi-densepose-api/ # Streaming bounded context
src/
domain/
application/
infrastructure/
wifi-densepose-db/ # Storage bounded context
src/
domain/
application/
infrastructure/
wifi-densepose-hardware/ # Hardware bounded context
src/
domain/
application/
infrastructure/
Leverage Rust's type system to encode domain invariants:
// Newtype pattern for domain identifiers
pub struct DeviceId(Uuid);
pub struct SessionId(Uuid);
pub struct FrameId(u64);
// State machines via enums
pub enum DeviceState {
Disconnected,
Connecting(ConnectionAttempt),
Connected(ActiveConnection),
Streaming(StreamingSession),
Error(DeviceError),
}
// Validated value objects
pub struct Frequency {
hz: f64, // Invariant: always > 0
}
impl Frequency {
pub fn new(hz: f64) -> Result<Self, DomainError> {
if hz <= 0.0 {
return Err(DomainError::InvalidFrequency);
}
Ok(Self { hz })
}
}
Domain errors are distinct from infrastructure errors:
#[derive(Debug, thiserror::Error)]
pub enum SignalDomainError {
#[error("Invalid CSI frame: {0}")]
InvalidFrame(String),
#[error("Signal quality below threshold: {snr} dB")]
LowSignalQuality { snr: f64 },
#[error("Calibration required for device {device_id}")]
CalibrationRequired { device_id: DeviceId },
}