The core:domain module is the heart of the application's business logic layer. It contains platform-independent business entities, use cases, and repository interfaces following Clean Architecture principles. This module has no dependencies on UI, framework, or data implementation details.
- Define core business models and entities
- Implement use cases (business logic operations)
- Define repository interfaces (contracts for data layer)
- Provide platform-agnostic utility functions
This module follows Clean Architecture and Domain-Driven Design principles:
core:domain (Business Logic - Pure Kotlin)
├── model/ # Business entities
├── db/ # Repository interfaces
├── usecase/ # Business logic operations
│ ├── note/ # Note operations (CRUD)
│ └── crypt/ # Encryption operations
├── repository/ # Repository implementations
└── util/ # Platform utilities
Domain entities representing core business concepts:
Note: Immutable data class representing a note with id, title, text, and timestampsPlatformSQLiteState: Represents database encryption statePlatformSQLiteThrowable: Domain-specific exception wrapper
Single-responsibility business operations following the Command Pattern:
CreateNoteUseCase: Creates a new note with generated IDSaveNoteUseCase: Updates existing note contentUpdateTitleUseCase: Updates note titleDeleteNoteUseCase: Removes a note
CheckPasswordUseCase: Validates database passwordChangePasswordUseCase: Changes database encryption passwordCheckSqlCipherVersionUseCase: Verifies SQLCipher availability
Database import/export lives in the feature:backup:domain module, which owns the backup use cases and
the platform-specific file transfer implementation.
Contracts for data access (implemented by data layer):
NoteDAO: Note data access operationsDatabaseHolder: Database lifecycle management
SafeRepo: Thread-safe repository wrapper managing database operations
Platform-specific implementations using expect/actual pattern:
CoroutineDispatchers: Platform-specific coroutine dispatchersplatformName: Platform detection (Android, iOS, JVM, Web)platformDate: Platform-specific date/time operationsrunBlockingAll: Platform-specific blocking coroutine execution
This module is Kotlin Multiplatform and supports:
- ✅ Android (androidTarget)
- ✅ iOS (iosArm64, iosSimulatorArm64)
- ✅ Desktop JVM (jvm)
- ✅ Web (wasmJs)
Platform-specific code is organized using expect/actual declarations in:
commonMain/- Shared codeandroidMain/- Android-specific implementationsiosMain/- iOS-specific implementationsjvmMain/- Desktop JVM implementationswasmJsMain/- Web implementations
kotlinx-coroutines- Asynchronous programmingkotlinx-datetime- Multiplatform date/time handlingandroidx-paging-common- Pagination supportnapier- Multiplatform logging
kotlin-test- Unit testing framework
- Clean Architecture: Domain layer isolated from external dependencies
- Use Case Pattern: Each business operation is a separate use case
- Repository Pattern: Abstract data access behind interfaces
- Dependency Inversion: Domain defines interfaces, data layer implements
- Immutability: Domain models are immutable data classes
- Operator Overloading: Use cases implement
operator fun invoke()for clean syntax
// Use case invocation (from ViewModel)
val createNoteUseCase = CreateNoteUseCase(noteDAO)
val noteId = createNoteUseCase(title = "My Note", text = "Content")
// Use cases are callable as functions due to invoke() operator
val saveNoteUseCase = SaveNoteUseCase(noteDAO)
saveNoteUseCase(noteId, "Updated content")Unit tests are located in commonTest/ and can run on all platforms:
# Run all tests
./gradlew :core:domain:test
# Platform-specific tests
./gradlew :core:domain:jvmTest
./gradlew :core:domain:iosSimulatorArm64TestSee CONTRIBUTING.md for general guidelines.
- Keep it pure: No framework or UI dependencies
- Use cases should be simple: Single responsibility, stateless
- Models are immutable: Use
data classwithvalproperties - Use
expect/actualonly when necessary - Write platform-agnostic tests in
commonTest/
- Used by:
core:presentation,core:data,ui:shared - Depends on: None (pure Kotlin)