Focust Architecture Overview

July 7, 2026 · View on GitHub

Purpose: One-page system overview for developers
Audience: Developers joining the project
Detail Level: Architecture + modules, no implementation


System Architecture

High-Level Diagram

┌─────────────── Frontend (Vue 3 + TypeScript) ───────────────┐
│  Settings Window              Break Windows (Multi-Monitor) │
│  ├─ Pinia Stores              ├─ Countdown Timer            │
│  ├─ Settings Panels           ├─ Suggestion Display         │
│  └─ Status Display            └─ Audio Playback             │
└────────────────────┬────────────────────────────────────────┘
                     │ Tauri IPC (25 Commands + 5 Backend Events)
┌────────────────────┴─── Backend (Rust + Tauri 2) ───────────┐
│  Scheduler Manager          Platform Integration            │
│  ├─ BreakScheduler          ├─ System Tray                  │
│  ├─ AttentionTimer          ├─ Global Hotkeys               │
│  └─ SharedState             ├─ Idle Detection               │
│                             └─ DND Monitoring               │
│  Config System              Core                            │
│  ├─ TOML Load/Save          ├─ Audio (Rodio)                │
│  └─ Partial Merge           ├─ Themes                       │
│                             └─ Suggestions                  │
└─────────────────────────────────────────────────────────────┘

Module Breakdown

Backend (Rust) - src-tauri/src/

ModulePurposeKey Components
cmd/Tauri command handlers (25 commands)audio, autostart, config, payload, scheduler, suggestions, system, window
config/TOML config with partial loadingAppConfig, AdvancedSettings, load/save/merge
scheduler/Event-driven scheduling engineBreakScheduler, AttentionTimer, SharedState, Command routing
monitors/Environment monitoringIdleMonitor, DndMonitor, AppWhitelistMonitor, Orchestrator
platform/System integrationTray, hotkeys, notifications, i18n, window creation
core/Business logic typesAudio, Schedule, Suggestions, Theme, Time
utils/UtilitiesError handling, logging (tracing)

Frontend (Vue 3) - src/

ModulePurposeKey Components
views/Main application viewsSettingsApp.vue, PromptApp.vue
stores/Pinia state managementconfigStore, schedulerStore, suggestionsStore
components/Reusable componentssettings/ (lazy panels), ui/, icons/
types/Type systemgenerated/ (ts-rs), guards.ts, factories.ts
composables/Vue composition functionsuseToast, useComputed
i18n/Internationalizationen-US, zh-CN locales
utils/Utility functionssafeClone, handleError

Data Flow

1. Configuration Flow

User Edit (Settings UI)

configStore.draft (Pinia)

invoke("save_config")

Backend: save_config() → TOML file

SchedulerManager: UpdateConfig command

BreakScheduler + AttentionTimer recalculate

2. Scheduler Flow

BreakScheduler: Calculate next break

Wait until break time (tokio::select!)

Send notification (optional)

Execute break: emit("scheduler-event", payload)

Frontend: schedulerStore.handleSchedulerEvent()

Create break windows (one per monitor)

User finishes → invoke("prompt_finished")

BreakScheduler: Update state, calculate next

3. Monitor Flow

Orchestrator: Sequential monitor checking

IdleMonitor: Check system idle time
DndMonitor: Check Do Not Disturb state
AppWhitelistMonitor: Check active processes

Convert MonitorResult → Pause/Resume reason

SchedulerManager: Add/Remove pause reason (bitflags)

If all clear → Resume schedulers
If any active → Pause schedulers

IPC Communication

Commands (Frontend → Backend)

CommandModulePurpose
play_audio, play_builtin_audio, stop_audioaudioAudio control
is_autostart_enabled, set_autostart_enabledautostartAutostart management
get_config, save_config, pick_background_imageconfigConfig CRUD
store_prompt_payload, get_prompt_payload, remove_prompt_payloadpayloadPrompt payload management
prompt_finished, pause_scheduler, postpone_break, request_break_status, resume_scheduler, skip_break, trigger_eventschedulerScheduler control
get_suggestions, save_suggestionssuggestionsSuggestion CRUD
exit_application, open_config_directory, open_log_directory, restart_applicationsystemFile explorer, app lifecycle
close_all_prompt_windowswindowWindow management

Events (Backend → Frontend)

EventPayloadPurpose
scheduler-statusSchedulerStatusStatus updates (paused, next event)
scheduler-eventPromptPayloadBreak/attention trigger
scheduler-paused()Paused notification
scheduler-resumed()Resumed notification
postpone-limit-reached()Max postpones reached

Key Design Patterns

1. Dual Scheduler Architecture

BreakScheduler: Handles mini/long breaks with intervals
AttentionTimer: Handles time-based attention reminders
SharedState: Central authority for pause reasons (bitflags)

Why: Separate concerns, independent timing logic, unified pause management

2. Bitflags for Pause Reasons

bitflags! {
    pub struct PauseReasons: u8 {
        const USER_IDLE     = 1 << 0;
        const DND           = 1 << 1;
        const MANUAL        = 1 << 2;
        const TIMED_MANUAL  = 1 << 3;
        const APP_EXCLUSION = 1 << 4;
    }
}

Why: Multiple pause reasons coexist, resume only when all cleared

3. Partial Config Loading

Problem: New app versions add fields → old configs break
Solution: Parse as generic TOML, merge valid fields with defaults
Why: Seamless upgrades, no data loss, backward compatibility

4. Event-Driven Monitoring

Windows/Linux: DND monitor uses platform events (WNF/D-Bus)
macOS: Polling (no native event API)
Why: Minimize CPU usage, responsive state changes

5. Type-Safe IPC (ts-rs)

#[derive(Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export, rename_all = "camelCase")]
pub struct AppConfig { }

Why: Compile-time type checking, refactoring safety, IDE support

6. Session Protection

SharedState: Tracks break/attention sessions
Monitors: Check in_any_session() before acting
Why: Prevent monitors from interfering with active prompts


Technology Choices

DecisionChoiceRationale
Config FormatTOMLHuman-readable, comments, type-safe
State ManagementPiniaVue 3 official, TypeScript support
SchedulingEvent-drivenLow CPU, responsive, testable
Error HandlingResult<T,E> + anyhowLibrary uses Result, app uses anyhow
Async Runtimetauri::async_runtimeAvoid Tokio Runtime errors
Type Syncts-rsAuto-generate TS types from Rust
LoggingtracingStructured, file output, levels
AudiorodioCross-platform, multi-format
TestingVitest + Cargo testNative support, ecosystem

Testing Strategy

Test Layers

Layer 4: End-to-End (User scenarios)
Layer 3: Integration (Manager + Monitor coordination)
Layer 2: State Machine (BreakScheduler + AttentionTimer logic)
Layer 1: Unit (SharedState + Config + Core types)

Coverage: 273 tests, 100% pass rate
Key Tests: 143 scheduler tests (8 stress tests), 30 config tests


Platform Support

PlatformStatusNotes
Windows✅ Fully testedPrimary development platform
Linux✅ DesignedEvent-driven DND (D-Bus), tested in CI
macOS✅ DesignedDND polling

Platform-Specific Code: #[cfg(target_os = "...")] in platform/dnd/


Resources

  • Config Reference: docs/CONFIGURATION.md