Ezike/StarWarsSearch-MVI
46.9
Weak · 21 September 2026
3.4k
lines of production code
Kotlin
primary language
4
measurements over time
What this system is
This is an Android application for browsing and searching Star Wars character data, featuring a clean architecture with separate layers for presentation, domain, and data. The system implements a state-driven UI using a state machine pattern and Hilt for dependency injection, supporting offline caching and remote data fetching. It includes reusable core components, test utilities, and a centralized navigation module to manage screen transitions.
How it got here
2020 — Architecture and build system initialization
18 changes.
The project was initialized with a Clean Architecture and MVI pattern, supported by a comprehensive Gradle build system migration to Kotlin DSL. This period established the foundational infrastructure, including Hilt dependency injection, state management components, and modular library structures for caching, remote data, and testing utilities.
2021–2022 — architecture modularization and feature expansion
5 changes.
This period focused on restructuring the application's architecture by introducing dedicated modules for navigation, caching, and remote data handling. It also expanded the user interface with a new character detail screen, supported by new data models and automated development tooling.
Features
Added build configuration and ignore files for cache, remote, and testUtils libraries
New library modules for cache, remote, and test utilities have been initialized with standard build configuration files. Each module now includes a .gitignore file to exclude build artifacts, a consumer-rules.pro file, and a proguard-rules.pro file containing default ProGuard configuration comments. These changes establish the structural foundation for these libraries within the project.
libraries · high confidence
Added character detail screen with support for films, species, and planets
Users can now view a detailed profile for a character, including their associated films, species, and homeworld. This new screen fetches and displays character data via a new data layer, presenting the information through dedicated UI components for each data type, with error handling and retry mechanisms for each section.
character-detail · high confidence
Automated ktlint setup script added
A new shell script (.scripts/install\_ktlint.sh) has been added to automate the installation of ktlint via Homebrew and configure Git pre-commit and pre-push hooks, as well as apply ktlint rules to IntelliJ IDEA.
.scripts · high confidence
Introduce Kotlin library and Spotless formatting plugins
Added new Gradle build scripts to standardize Kotlin library modules and enforce code formatting. The new kotlin-library plugin configures Java 11 compatibility, enables explicit API mode for Kotlin modules, and includes Coroutines. The spotless plugin enforces consistent formatting for Kotlin, XML, and Gradle files.
buildSrc/src/main/kotlin/plugin · high confidence
Introduce state management infrastructure for the presentation layer
Added a new state machine architecture to the presentation module, introducing base interfaces and classes (including StateMachine, RenderStrategy, and SubscriptionManager) that enable components to subscribe to state updates and process view intents. This change provides a structured way to handle UI state transitions and user interactions within the app's interface.
presentation · high confidence
Introduces a generic RemoteModelMapper interface for data mapping
A new generic interface, RemoteModelMapper, has been added to the remote library's mapper package. This interface defines a standard contract for converting remote models (M) into local entities (E), including a default implementation for mapping lists of models. This change supports the broader refactoring of the application's data layer by providing a reusable abstraction for remote-to-local data transformation.
libraries/remote/src/main/java/com/ezike/tobenna/starwarssearch/remote/mapper · high confidence
Introduces cache model classes and mapper interface for Star Wars character data
The cache library now includes new data classes for persisting Star Wars character information. Specifically, \CharacterCacheModel\ and \CharacterDetailCacheModel\ are added as Room entities for the \SEARCH\_HISTORY\ and \CHARACTER\_DETAIL\ tables, respectively. Additionally, a generic \CacheModelMapper\ interface is introduced to handle mapping between model and entity types.
libraries/cache/src/main/java/com/ezike/tobenna/starwarssearch/cache/mapper, libraries/cache/src/main/java/com/ezike/tobenna/starwarssearch/cache/model · high confidence
Introduces local caching for character details and search history
Adds a new Room-based local cache layer for the Star Wars search feature. The change introduces a database schema and data access objects (DAOs) to persist character details and recent search history locally on the device. This enables the app to store and retrieve cached data, supporting offline access and faster loading of previously viewed character details and search history.
libraries/cache/src/main/java/com/ezike/tobenna/starwarssearch/cache/room · high confidence
Introduces reusable core UI components and string handling
Adds a new core module containing a reusable EmptyStateView for displaying empty or error states with customizable title, caption, and retry actions, along with an AppString sealed interface for managing string resources and literals in the UI.
core · high confidence
New test utilities for coroutine and flow testing
Added new test utilities in the testUtils library to simplify testing asynchronous code. This includes a MainCoroutineRule for managing the main coroutine dispatcher in tests, a FlowRecorder helper for capturing and asserting emitted flow values, and extension functions for asserting thrown exceptions and checking iterable contents.
libraries/testUtils · high confidence
Project initialization with Apache 2.0 license and build scripts
The repository was initialized with the Apache License 2.0, a README.md outlining the project's architecture (MVI, Clean Architecture, Dagger Hilt), and a process.md detailing the technical decisions. Additionally, a setup.sh script was added to configure ktlint, and the Gradle wrapper scripts (gradlew, gradlew.bat) were updated to include Apache 2.0 headers and improved path resolution logic.
(repo-wide) · high confidence
Behavioural changes
Added HTTP and network error handling interceptors
The remote library now includes two new OkHttp interceptors to improve network reliability. The HttpsInterceptor automatically upgrades HTTP requests to HTTPS, ensuring secure communication. The NoInternetInterceptor catches common network exceptions (such as timeouts, connection failures, and unknown hosts) and wraps them in a user-friendly error message indicating an internet connection issue.
libraries/remote/src/main/java/com/ezike/tobenna/starwarssearch/remote/interceptor · high confidence
Added Hilt dependency injection module for remote layer
A new Hilt module (RemoteModule) was added to the remote library's dependency injection setup. This module provides a Moshi instance configured with Kotlin reflection support and a Retrofit instance, enabling Hilt-based dependency injection for remote data fetching components.
libraries/remote/src/main/java/com/ezike/tobenna/starwarssearch/remote/di · high confidence
Introduce dedicated navigation module with Hilt integration
The app now uses a dedicated 'navigation' module to centralize routing logic. This includes a new SearchScreenNavigator that handles transitions to the character detail screen, with dependency injection provided via a new NavigationModule that binds the navigator and supplies a back-navigation action. The module also defines the root navigation graph, which includes the search and detail screens and passes character data between them.
navigation · high confidence
Introduced Dagger/Hilt module for cache database and DAOs
A new Hilt module (CacheModule) was added to the cache library's dependency injection layer. This module provides the singleton instances for the StarWarsDatabase, SearchHistoryDao, and CharacterDetailDao, enabling the application to access cached character details and search history through the Hilt container.
libraries/cache/src/main/java/com/ezike/tobenna/starwarssearch/cache/di · medium confidence
Introduced state-driven architecture for the character search screen
The character search screen now uses a state machine and reducer pattern to manage UI states, replacing the previous implementation. This change introduces a \SearchScreenStateMachine\ that processes intents (like search queries and history updates) and reduces them into UI states, allowing the \SearchFragment\ to simply observe and render the current state. This includes handling search results, loading states, errors, and recent search history.
_character\search · high confidence
Introduces Hilt dependency injection and navigation setup
The app now uses Hilt for dependency injection, evidenced by the new ApplicationClass annotated with @HiltAndroidApp and MainActivity with @AndroidEntryPoint. An AppModule is added to provide the NavController for navigation, indicating a shift towards a more modular and testable architecture.
app/src/main/java · medium confidence
Introduces RemoteFactory for deferred OkHttp initialization
A new RemoteFactory class has been added to the remote library, implementing deferred initialization of the OkHttp client via Dagger's Lazy injection. This change, which also includes HTTPS and no-internet interceptors along with configurable timeouts, replaces the previous approach to network client creation.
libraries/remote/src/main/java/com/ezike/tobenna/starwarssearch/remote · medium confidence
Refactored Android presentation layer with new state management components
The Android presentation module was restructured to improve state management and component lifecycle handling. New classes including ComponentManager, UIComponent, and AssistedCreator were introduced to manage view states and intents more effectively. The ComponentManager now handles subscription and disposal of components, while the UIComponent abstracts rendering and intent dispatch. These changes aim to simplify state representation and reduce complex boolean logic in view states.
presentation-android · medium confidence
Updated ProGuard configuration file reference
The ProGuard rules file now references build.gradle.kts instead of build.gradle, reflecting the project's migration to the Kotlin DSL for Gradle build scripts.
app · medium confidence
Dependencies
Centralized dependency and build configuration
The project has introduced a centralized build configuration system in the buildSrc module. AppDependencies.kt now defines all library versions (including Kotlin 1.9.23, Hilt 2.51, and various AndroidX/Network libraries) and their corresponding Gradle dependencies, replacing scattered version declarations. BuildType.kt standardizes debug/release build type properties, while Extensions.kt provides reusable Gradle DSL helpers for applying plugins and managing dependencies. This change simplifies dependency management and ensures consistent build settings across the project.
buildSrc/src/main/kotlin · high confidence
Gradle wrapper upgraded to version 8.3
The project's Gradle wrapper has been upgraded from version 6.5 to 8.3. This update brings the build system to a newer version, which may affect build performance, compatibility with newer Android Gradle Plugin versions, and requires the Gradle wrapper to be updated for consistent builds across the team.
gradle · high confidence
Migrate project to Gradle Kotlin DSL and modernize build configuration
The project's build system has been migrated from Groovy to Kotlin DSL (build.gradle.kts), introducing a centralized dependency management structure in buildSrc. This update includes enabling ViewBinding, activating the Gradle configuration cache, and switching Jetifier from enabled to disabled. Additionally, the project now uses Java 11 for compilation and applies standard Gradle plugin conventions across all modules.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 47 → 47 (-0.5)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 100 → 100 (-0.2)
- Architecture 99 → 93 (-5.7)
- Maturity 45 → 43 (-2.1)
- Readiness 57 → 57 (+0.0)
- Security 85 → 95 (+9.7)
- Domain Modelling 32 → 31 (-0.9)
Resolved (10)
- Boundary-crossing change coupling: CharacterDetailFragment.kt ↔ BaseComponentManager.kt (character-detail/src/main/java/com/ezike/tobenna/starwarssearch/characterdetail/ui/CharacterDetailFragment.kt)
- Boundary-crossing change coupling: CharacterDetailFragment.kt ↔ ComponentManager.kt (character-detail/src/main/java/com/ezike/tobenna/starwarssearch/characterdetail/ui/CharacterDetailFragment.kt)
- Coverage not included — suite not readable by the collector
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- High: security finding (details withheld)
- High: security finding (details withheld)
- No exposed public API
- Test reliability not included
- The prerequisites list (Android Studio Jellyfish, Gradle 8.3, Kotlin 1.9.23) is correct for Android Studio 12.x but the project uses Android Studio 12.x and Gradle 8.2.0; the listed Gradle version is one step ahead of what is actually used. (README.md)
- single-maintainer — knowledge-concentration (bus factor) risk
New (10)
- Dependency hygiene PARTLY measured — Maven/Gradle declarations read, no dependency graph resolved
- Documentation: no usage examples (README.md)
- High: security finding (details withheld)
- High: security finding (details withheld)
- Medium: security finding (details withheld)
- Medium: security finding (details withheld)
- No ADRs found
- No dependency advisory monitoring
- TodoComment (character-detail/src/test/java/com/ezike/tobenna/starwarssearch/characterdetail/presentation/CharacterDetailViewStateReducerTest.kt)
- Workflow token permissions not restricted
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
Ezike/StarWarsSearch-MVI was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit f091dc9b19b0a4b5b38d27c5331a4d70388f970d — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-fa71c66cabd8.