A tour of the codebase by location. The project is split into a
framework-agnostic core (core/) and client apps (apps/).
Dependency direction (inward): UI → Infrastructure → Use Cases → Domain.
pomotoro/
├── core/ # Framework-agnostic core engine
│ ├── domain/ # Business logic & entities
│ ├── usecases/ # Application services (orchestrates domain)
│ └── infra/ # Infrastructure (repos, event bus, audio, timer tick)
├── apps/ # Client applications (thin wrappers over core)
│ ├── tauri-app/ # Tauri desktop client (commands, plugins, UI emission)
│ ├── react-ui/ # React + TypeScript frontend (Vite)
│ ├── pomotoro-cli/ # CLI client (planned)
│ └── cosmic-de/ # Cosmic DE applet (planned)
├── assets/ # Sounds (notifications/, background/)
├── scripts/ # install-deps.sh, CI helpers
├── docs/ # This documentation
├── Cargo.toml # Workspace root
├── justfile # All dev/build/test commands
├── rustfmt.toml
├── CLAUDE.md · GEMINI.md # AI assistant context
└── README.md
Pure business logic. No external dependencies, no I/O.
mod.rs— module exportstimer.rs—Timerentitystate_machine.rs— state transitionstransitions.rs— transition business rulesrepository.rs—TimerRepositorytraitid.rs—TimerIderror.rs— timer errorsREADME.md— in-source notes
mod.rs— module exportstask.rs—Taskentitybuilder.rs—TaskBuilderrepository.rs—TaskRepositorytraitcycle_service.rs— task cycling logicstatus.rs—TaskStatusenumid.rs—TaskIdtest_builder.rs— test fixture builder
mod.rs— module exportsconfig.rs— rootConfigrepo.rs—ConfigRepositorytraitgeneral.rs— general settings (theme, auto-start, screen blocking, tray)audio.rs— audio settingsappearance.rs— UI appearance settingsnotification.rs— notification settings
mod.rs— module exportsaudio_srv.rs—AudioServicetraitasset.rs—AudioAssetcategory.rs—AudioCategorylibrary.rs—AudioLibraryerror.rs— audio errors
mod.rs— common typeserrors.rs— base error typesserde_utils.rs— serialization helpers
Central registry of emit/listen string constants shared with the frontend.
mod.rscommands.rs— Tauri command namesui_listeners.rs— event names emitted to the UI (e.g.screen_blocker:activate)
Application services that orchestrate the domain.
start_timer_phase, resume_timer_phase, pause_timer_phase,
reset_timer_phase, reset_timer_to_idle, skip_timer_phase,
complete_timer_phase, progress_phase, update_timer_secs,
clear_active_task.
create_task, update_task, update_task_settings, reset_task_settings,
delete_task, reset_task, reset_tasks, get_task, search_tasks,
switch_task, switch_active_task, complete_task.
get_config, update_config, reset_config, export_config,
import_config.
play_audio, notification_audio, manage_library.
bootstrap.rs— use-case construction / DIlib.rs— crate exports
SQLite persistence (Diesel + r2d2), the in-memory event bus, adapters, and event handlers. Zero Tauri dependencies — reusable by any client.
database/—connection.rs(r2d2 pool),models.rs,sqlite_config_repository.rstimer/—sqlite_repository.rs,sqlite_service.rs,timer_dto.rs+event_handlers/task/—sqlite_repository.rs+event_handlers/(created, updated, deleted, status_changed, completed, reset, active_changed, registry)config/— adapter +event_handlers/(config_updated, config_reset, registry)audio/—audio_service_adapter.rs,library_service.rs,asset_provider.rs,audio_service_wrapper.rs,event_handlers.rsnotifications/—service.rs+event_handlers.rsevents/—mem_event_bus.rs,event_handler.rs,event_subscriber.rs,app_emitter.rs,logging_emitter.rs,app_started_handler.rs,audio_events.rs
bootstrap.rs—AppStatewiring / dependency injectionschema.rs— Diesel schema (generated viadiesel print-schema)bin/test_db.rs— DB inspection binarylib.rs— crate exports
app/— application-level integration testscore/— shared test infrastructurecontext/— test context buildersdatabase/— test database utilitiesfixtures/— test data fixtures (e.g.config_fixtures.rs)mocks/— mock implementations
Thin shell over core/infra. Owns window, tray, and Tauri command registration.
main.rs/lib.rs— entry point +invoke_handler!registrationcommands/—#[tauri::command]handlers (timer, task, config, audio, notification, screen blocker)adapters/—emitter.rs(Tauri event emission),notification_service.rstray.rs— system tray + tray-icon countdowncapabilities/,icons/,gen/— Tauri config assets
Feature-sliced: each feature owns its types.ts, model/ (Zustand store),
components/, and pages/. Cross-feature imports go through @/lib/.
app/— rootApp.tsx,EventBus.ts, app-wide stores (useScreenBlocker, …)components/—layout/+ui/(Row, Section, Toggle, NumberInput, SelectInput, …)lib/—tauri.ts(typedinvokeCmdbridge + command/event maps),logger,errors, duration helperspages/—timer/,tasks/,settings/
apps/pomotoro-cli/— CLI clientapps/cosmic-de/— Cosmic desktop applet
Cargo.toml/Cargo.lock— workspace + per-crate manifests (core/{domain,usecases,infra},apps/tauri-app)justfile— canonical command runner (just dev,just test,just ci, …)rustfmt.toml— formatting configapps/tauri-app/tauri.conf.json— Tauri bundler configcore/infra/diesel.toml— Diesel ORM configapps/react-ui/{package.json, vite.config, tsconfig}— frontend toolchainassets/sounds/{notifications,background}/— audio assets
README.md— project READMEdocs/— this documentation tree (seedocs/README.mdfor the index)CLAUDE.md/GEMINI.md— AI assistant context
- Timer changes:
core/domain/src/timer/·core/usecases/src/timer/·core/infra/src/adapters/timer/ - Task changes:
core/domain/src/task/·core/usecases/src/task/·core/infra/src/adapters/task/ - Event changes:
core/domain/src/event_names/·core/infra/src/adapters/events/·apps/react-ui/src/app/EventBus.ts - A new Tauri command:
apps/tauri-app/src/commands/+ registration inlib.rs+ the matching entry inapps/react-ui/src/lib/tauri.ts
- DI wiring:
core/infra/src/bootstrap.rs - Event bus:
core/infra/src/adapters/events/mem_event_bus.rs - DB connection pool:
core/infra/src/adapters/database/connection.rs