Skip to content
CAI
Software that uses CAICheck a score

krokers/exchange-rates-mvvm

58.1

Adequate · 21 September 2026

1.6k

lines of production code

Java

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is an Android application designed to retrieve and display currency exchange rates and historical data. It implements a clean architecture with distinct domain, data, and presentation layers, utilizing dependency injection and reactive programming patterns. The core functionality involves fetching currency information from remote APIs and local databases, then exposing this data through use cases to the UI.

Features

Added data layer for retrieving and caching currency exchange rates

A new data module has been introduced to handle currency data, featuring a \CachingCurrencyRepository\ that checks a local Realm database before fetching from a remote API. The implementation includes a \CurrencyDataSource\ interface with \DatabaseCurrencyDataSource\ for local storage and \RetrofitCurrencyDataSource\ for remote calls, along with DTOs and mappers to support this dual-source caching strategy.

data · high confidence

Added domain use cases for currency data retrieval

The application now supports retrieving currency exchange rates, a saved date for the last read, and historical currency series data. Three new domain use cases have been introduced: GetCurrenciesUseCase fetches current exchange rates for a specific date; GetCurrenciesRatesDate retrieves the date of the last successfully read exchange rates; and GetCurrencySeriesUseCase fetches historical series data for a given currency code and date range. These changes enable the UI to display basic currency information and persist the last known exchange rate date.

domain/src/main/java/eu/rampsoftware/er/domain/usecases · medium confidence

Initial presentation layer with dependency injection and UI components

The presentation module introduces the core UI structure, including activities for listing and viewing currency details, along with their corresponding ViewModels. Dependency injection is configured using Dagger2, with an ApplicationComponent managing singleton-scoped dependencies like the CurrencyRepository and network modules, while activity-scoped subcomponents inject specific ViewModels and use cases into the respective Activities. The UI includes a custom SwipeRefreshLayout to fix progress indicator visibility, a ValueSwitcher widget for date navigation, and layout bindings that connect the CurrencyListViewModel and CurrencyDetailsViewModel to their respective XML layouts.

presentation · high confidence

Architecture

Added base classes for use cases

The domain layer now includes four new abstract base classes—CommandUseCase, NoArgCommandUseCase, QueryUseCase, and NoArgQueryUseCase. These provide a standardized structure for use cases, handling scheduler-based execution (work and observation) and abstracting the core run logic, which simplifies the implementation of new use cases.

domain/src/main/java/eu/rampsoftware/er/domain · high confidence

Behavioural changes

Introduces base interfaces for thread execution

Added new base interfaces for thread execution: PostExecutionThread, which provides a Scheduler for post-execution threading, and ThreadExecutor, which extends the standard Executor interface. These interfaces establish the foundation for managing background and post-execution thread handling within the domain layer.

domain/src/main/java/eu/rampsoftware/er/domain/executor · high confidence

Introduces data boundary interfaces and models for currency and preferences

Adds new data boundary classes and interfaces that define how the application retrieves and persists currency data and user preferences. Specifically, it introduces the CurrencyData and SingleValue models, along with the CurrencyRepository and PreferencesData interfaces, enabling the domain layer to fetch currency series and persist scalar preferences.

databoundary · medium confidence

Test coverage

Added tests for the GetCurrencySeries use case

Added unit tests for the GetCurrencySeries use case, including a new TestDisposableObserver helper class. The tests verify that the use case correctly handles invalid parameters (null or empty dates and currency codes) and confirms that the underlying repository's getSeries method is invoked with the correct arguments.

domain/src/test · high confidence

Dependencies

Centralized dependency management and modular project structure

The project has been refactored into a multi-module architecture (presentation, domain, data, databoundary) with all dependency versions and library coordinates centralized in a new \dependencies.gradle\ file. This change introduces specific library versions including RxJava 2.0.5, Retrofit 2.1.0, Dagger 2.9, and Android Support Library 25.2.0, while also adding build tools like Retrolambda and Realm. The \settings.gradle\ file was updated to include the new modules, and the root \build.gradle\ was modified to apply the centralized dependency configuration.

(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

Score

  • CAI 55 → 58 (+2.7)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 100 → 100 (+0.0)
  • Architecture 100 → 84 (-16.0)
  • Maturity 66 → 66 (+0.0)
  • Readiness 24 → 35 (+10.6)
  • Security 100 → 100 (+0.0)

Resolved (6)

  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • No exposed public API
  • Test reliability not included
  • The 'Architecture' section describes Clean Architecture modules (presentation, domain, data) but does not explain how the data layer interacts with the presentation layer or what happens when the external service fails. (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)
  • No ADRs found
  • No assertions: thatExceptionThrownOnMissingInitialData (presentation/src/test/java/eu/rampsoftware/er/viewmodel/CurrencyDetailsViewModelTest.java)
  • No assertions: thatExceptionThrownOnNullInitialData (presentation/src/test/java/eu/rampsoftware/er/viewmodel/CurrencyDetailsViewModelTest.java)
  • No direct assertions: thatPreconditionFailsIfCurrencyCodeIsEmpty (domain/src/test/java/eu/rampsoftware/er/domain/usecases/GetCurrencySeriesUseCaseTest.java)
  • No direct assertions: thatPreconditionFailsIfCurrencyCodeIsNull (domain/src/test/java/eu/rampsoftware/er/domain/usecases/GetCurrencySeriesUseCaseTest.java)
  • No direct assertions: thatPreconditionFailsIfDateFromIsNull (domain/src/test/java/eu/rampsoftware/er/domain/usecases/GetCurrencySeriesUseCaseTest.java)
  • No direct assertions: thatPreconditionFailsIfDateRangeEmpty (domain/src/test/java/eu/rampsoftware/er/domain/usecases/GetCurrencySeriesUseCaseTest.java)
  • No direct assertions: thatPreconditionFailsIfDateToIsNull (domain/src/test/java/eu/rampsoftware/er/domain/usecases/GetCurrencySeriesUseCaseTest.java)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

krokers/exchange-rates-mvvm 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 01f7caff3696e11940f42b954629b7cb01873baa — 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.