Module Structure
Relevant source files
The following files were used as context for generating this wiki page:- README.md
- app/src/main/java/com/vocabri/VocabriApplication.kt
- app/src/main/java/com/vocabri/di/AppModule.kt
- data/src/main/java/com/vocabri/data/di/DataModule.kt
- build-logic/convention/src/main/kotlin/ProjectConventionPlugin.kt
- build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt
- build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt
- build-logic/convention/src/main/kotlin/com/vocabri/DetektConfiguration.kt
- build-logic/convention/src/main/kotlin/com/vocabri/SpotlessConfiguration.kt
- build-logic/convention/src/main/kotlin/com/vocabri/KoverConfiguration.kt
The Vocabri project is organized into a multi-module architecture to enforce a clean separation of concerns, enhance scalability, and facilitate code reuse. The structure follows modern Android development best practices, separating UI, business logic, and data access into distinct layers. This modularity is also designed to support future expansion, such as the planned iOS application, by isolating platform-agnostic code.
The project utilizes a layered architecture, with dependencies flowing from the presentation layer down to the data layer. Dependency injection is managed by Koin, which wires together components across these module boundaries. Build configurations are standardized using custom Gradle convention plugins located in the build-logic module.
Sources: README.md:29-39
High-Level Architecture
The project is divided into several key Gradle modules, each with a specific responsibility. The dependency flow is unidirectional, preventing lower layers from knowing about higher layers.
The diagram below illustrates the primary modules and their dependency relationships.
This diagram shows the dependency graph between the main modules of the Vocabri application.
Sources: README.md:29-39
Module Overview
| Module | Description |
|---|---|
app | The main Android application module. Contains Jetpack Compose UI, navigation, ViewModels, and the Koin appModule for UI-layer dependency injection. |
domain | Contains core business logic, including domain models, repository interfaces (contracts), and use cases. It is a pure Kotlin module with no Android framework dependencies. |
data | Implements the repository contracts defined in the domain module. It manages data sources, including the local SQLDelight database and remote APIs. |
core | A set of utility modules, such as core/logger for logging abstractions and core/utils for common helpers like an ID generator abstraction. |
shared | A Kotlin Multiplatform (KMP) module prepared for future iOS support. It contains code intended to be shared between Android and iOS. |
build-logic | Contains custom Gradle convention plugins to standardize build configurations, dependencies, and quality tools (Spotless, Detekt, Kover) across all other modules. |
Sources: README.md:29-39
Dependency Injection with Koin
The application uses Koin for dependency injection. Each major layer (app, data, domain) defines its own Koin module, which is then loaded at the application's entry point. This decouples the layers and makes components easily testable and replaceable.
The VocabriApplication class is responsible for initializing Koin and loading all the necessary modules from the different layers.
// app/src/main/java/com/vocabri/VocabriApplication.kt:40-48
class VocabriApplication : Application() {
// ...
override fun onCreate() {
// ...
startKoin {
// ...
modules(
dataModule,
domainModule,
appModule,
)
}
}
}
Sources: app/src/main/java/com/vocabri/VocabriApplication.kt:40-48
The following diagram shows the sequence of Koin module initialization.
This sequence diagram illustrates how VocabriApplication starts Koin and loads the modules from the data, domain, and app layers.
Sources: app/src/main/java/com/vocabri/VocabriApplication.kt:45-49
Key DI Modules
dataModule: Provides implementations for data-layer components like theVocabriDatabase,WordRepository,DebugRepository, and various data sources. It also binds theUuidIdGeneratorto theIdGeneratorinterface.
Sources: data/src/main/java/com/vocabri/data/di/DataModule.kt:34-58domainModule: Provides use cases such asAddWordUseCase,ObserveWordsUseCase, etc. (Defined in thedomainmodule, not shown in provided files but referenced).
Sources: app/src/main/java/com/vocabri/VocabriApplication.kt:47appModule: Provides ViewModels (MainViewModel,DictionaryViewModel, etc.) and Android-specific components like theResourcesRepositoryimplementation. It dynamically createsDictionaryDetailsViewModelinstances for eachPartOfSpeech.
Sources: app/src/main/java/com/vocabri/di/AppModule.kt:31-50
Build System (build-logic)
The project uses build-logic with custom Gradle convention plugins to manage build configurations consistently across all modules. This avoids duplicating build script logic in each module's build.gradle.kts file.
The root ProjectConventionPlugin applies a common set of quality tool plugins to all subprojects.
// build-logic/convention/src/main/kotlin/ProjectConventionPlugin.kt:29-36
class ProjectConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
applySpotless()
applyDetekt()
applyKover()
applyKoverExclusions()
}
}
}
Sources: build-logic/convention/src/main/kotlin/ProjectConventionPlugin.kt:29-36
Convention Plugins
| Plugin | Applied Logic | Source File |
|---|---|---|
AndroidApplicationConventionPlugin | Applies com.android.application and common Kotlin Android plugins. | AndroidApplicationConventionPlugin.kt |
AndroidLibraryConventionPlugin | Applies com.android.library and common Kotlin Android plugins. | AndroidLibraryConventionPlugin.kt |
ProjectConventionPlugin | Applies Spotless, Detekt, and Kover configurations to all subprojects. | ProjectConventionPlugin.kt |
This structure is visualized below:
This diagram shows how the ProjectConventionPlugin orchestrates the application of various code quality tools across the project.
Sources: build-logic/convention/src/main/kotlin/ProjectConventionPlugin.kt:32-35, build-logic/convention/src/main/kotlin/com/vocabri/SpotlessConfiguration.kt, build-logic/convention/src/main/kotlin/com/vocabri/DetektConfiguration.kt, build-logic/convention/src/main/kotlin/com/vocabri/KoverConfiguration.kt
Module Details
app Module
This is the entry point for the Android application. It is responsible for the UI layer, built with Jetpack Compose, and holds the ViewModels that interact with the domain layer's use cases. Its AndroidManifest.xml declares VocabriApplication as the application class and MainActivity as the main launcher activity.
Sources: app/src/main/AndroidManifest.xml:24-25, 34-40, README.md:30
data Module
This module handles all data operations. It provides concrete implementations of the repositories defined in the domain layer. It uses SQLDelight for local database persistence, with the database being named vocabri.db. It also defines stubs for remote data sources, indicating a design prepared for future network integration.
- Database:
VocabriDatabaseis created usingAndroidSqliteDriver. - Repositories:
WordRepositoryImplandDebugRepositoryImplare provided. - Data Sources:
WordLocalDataSourceImpland a stubWordRemoteDataSourceStubare defined.
Sources: data/src/main/java/com/vocabri/data/di/DataModule.kt:36-44, 51-55, README.md:32, 57-59
shared Module
This module is a Kotlin Multiplatform module, currently targeting Android and prepared for iOS. It contains shared business logic and network clients (Ktor) that can be compiled for multiple platforms, promoting code reuse and consistency between the Android and future iOS apps.
Sources: README.md:34, 46