Location: domain/src/timer/
Key Components:
Timer- Main timer entityTimerState- Current state (duration, phase, status)Phase- Work or BreakTimerStatus- Idle, Running, PausedStateTransitions- State machine logic
Key Methods:
start()- Begin timer sessionpause()- Pause current sessionreset()- Reset to initial stateskip_phase()- Move to next phasetick()- Update timer (called every second)
Events Emitted:
TimerStartedTimerPausedTimerResetPhaseCompletedPhaseSkippedWorkPhaseStarted/CompletedBreakPhaseStarted/Completed
Location: domain/src/task/
Key Components:
Task- Task entity with title, description, statusTaskId- Unique identifier (UUID)TaskStatus- Pending, InProgress, CompletedTaskSettings- Per-task timer configurationEffectiveSettings- Resolved settings (task + defaults)
Key Methods:
Task::builder()- Create new taskcomplete_session()- Increment session countupdate_status()- Change task statusapply_settings()- Set custom timer config
Repository Interface:
trait TaskRepository {
async fn create(&self, task: Task) -> Result<Task>
async fn update(&self, task: Task) -> Result<Task>
async fn delete(&self, id: TaskId) -> Result<()>
async fn find_by_id(&self, id: TaskId) -> Result<Option<Task>>
async fn find_all(&self) -> Result<Vec<Task>>
async fn search(&self, query: &str, status: Option<TaskStatus>) -> Result<Vec<Task>>
}Location: domain/src/config/
Components:
Config- Root configuration objectGeneralConfig- Theme, auto-start, etc.AudioConfig- Volume, enabled soundsNotificationConfig- Position, enabledTaskDefaults- Default timer durationsAppearanceConfig- UI preferences
Repository Interface:
trait ConfigRepository {
async fn get(&self) -> Result<Config>
async fn update(&self, config: Config) -> Result<Config>
async fn reset(&self) -> Result<Config>
}Location: domain/src/audio/
Components:
AudioAsset- Individual sound fileAudioCategory- Background or NotificationAudioLibrary- Collection of assetsPlaybackRequest- Play audio commandAudioService- Audio playback interface
Service Interface:
trait AudioService {
async fn play(&self, request: PlaybackRequest) -> Result<PlaybackHandle>
async fn stop(&self, handle: PlaybackHandle) -> Result<()>
async fn set_volume(&self, handle: PlaybackHandle, volume: f32) -> Result<()>
}Location: domain/src/shared_kernel/
EntityId<T>- Type-safe entity identifiersTimestamp- Time trackingTimerConfiguration- Work/break durationsTag- Categorization tagsEvent- Base event traitEventPublisher- Event publishing interface
Duration- Time duration wrapperPhase- Work | Break enumTransitionType- Manual | AutomaticTransitionResult- State change outcome
TaskCyclingStrategy- How to select next taskSessionCount- Number of completed sessionsPriority- Task priority level
User Action → Timer Domain → Event Published → Handlers
↓
State Change
↓
Return Result
Task Operation → Repository → Event Published → Side Effects
↓
Database Update
↓
Return Updated Entity
- Timer must be idle to start
- Can only pause when running
- Phase skip advances to next phase
- Work sessions followed by breaks
- Automatic transitions configurable
- Only one task active at a time
- Tasks track session completion
- Status changes trigger events
- Deleted tasks cannot be recovered
- Task settings override defaults
- Config always has valid defaults
- Import merges with existing config
- Reset restores factory defaults
- Audio volume: 0.0 to 1.0 range
- Root: Timer
- Includes: TimerState, Phase, Status
- Boundary: Timer operations only
- Root: Task
- Includes: TaskSettings, Status
- Boundary: Individual task operations
- Root: Config
- Includes: All config sections
- Boundary: Configuration as a whole
- Manages task cycling strategies
- Selects next task based on rules
- Handles exhausted queue scenarios
- Manages timer tick intervals
- Handles system timer integration
- Provides timer state persistence
pub enum Error {
NotFound(String),
ValidationError(String),
InvalidState(String),
OperationFailed(String),
}- InvalidTransition
- AlreadyRunning
- NotRunning
- InvalidDuration
- TaskNotFound
- DuplicateTask
- InvalidStatus
- CyclingExhausted