Skip to content

Merge feature/modularization into Main - #4

Merged
ramyassaf merged 6 commits into
mainfrom
dev
May 27, 2026
Merged

Merge feature/modularization into Main#4
ramyassaf merged 6 commits into
mainfrom
dev

Conversation

@ramyassaf

Copy link
Copy Markdown
Owner

No description provided.

Ramy ASSAF added 6 commits May 26, 2026 16:08
Move from package-level Clean Architecture to Gradle module boundaries
so the dependency direction is enforced at build time:
:app -> :domain, :app -> :data, :data -> :domain.

Module ownership:
- :domain (Kotlin/JVM) — models, repository contracts, use cases,
  Resource and DomainError.
- :data (Android library + KSP) — Room, Retrofit, DTOs, repository
  implementation, technical exception mapping and the data-level
  Koin module (base URL inlined here).
- :app — Compose UI, navigation, ViewModels, presentation mapping
  and the app-level Koin module. ChiApplication loads both modules.

Tests follow ownership: use-case tests in :domain, mapper and
repository tests in :data, DAO instrumented tests in :data
androidTest, and ViewModel + Konsist architecture tests in :app.

Also: libs.versions.toml gains kotlinx-coroutines-core, :app drops
its direct Retrofit/OkHttp/Room/KSP dependencies, and .gitignore
ignores module-level build/ directories.
Move TestJokes and FakeJokeRepository into :domain testFixtures so
:data and :app tests consume them instead of carrying duplicates. Add
JokeDtos and JokeEntities in :data testFixtures for mapper and
repository tests, both derived from TestJokes.
Move from the legacy buildscript { classpath(...) } override to the
plugins DSL with version-catalog aliases:
- Drop the root buildscript block.
- Add alias(libs.plugins.kotlinJvm) apply false to the root plugins
  block alongside composeCompiler and devToolsKsp.
- :domain applies via alias(libs.plugins.kotlinJvm) and drops its
  redundant java { sourceCompatibility } block now that
  kotlin.jvmToolchain(17) drives both Kotlin and Java compile targets.

The old setup pinned KGP 2.3.21 / KSP 2.3.7 (vs the older versions
bundled with AGP 9) by adding them as classpath() entries in the root
buildscript, which required mirroring them as library coordinates
(kotlin-gradle-plugin, ksp-gradle-plugin) in [libraries] just to feed
classpath().

Google has recommended the plugins DSL with apply false at the root
and alias() in submodules since AGP 7 / Android Studio Arctic Fox
(2021), and the gradle/libs.versions.toml catalog became the Android
Studio default around AGP 8 (Giraffe). The plugins block resolves
plugin marker artifacts directly, so declaring kotlinJvm there
enforces the same KGP 2.3.21 onto the build classpath without the
buildscript override or the library-coordinate mirrors. The two now-
unused library aliases are removed; resolved KGP and KSP versions
are unchanged.
…port boundary

Each architecture rule now lives with the module it asserts about, so
`./gradlew :domain:test` or `:data:test` independently verifies that
module's invariants instead of leaning on :app to police everything.

Redistribution:
- :domain absorbs DomainLayerArchitectureTest and UseCaseArchitectureTest,
  plus the "no *Api in domain" and "any Repository interface lives in
  domain.repository" rules from the old RemoteApi / Repository suites.
- :data absorbs DataLayerArchitectureTest, plus "Api interfaces live in
  data.remote", "Retrofit annotations stay confined to data.remote",
  "RepositoryImpl lives in data.repository", and "RepositoryImpl
  implements a domain.repository contract".
- :app keeps ProjectArchitectureTest and gains AppLayerArchitectureTest
  with two rules: only ChiApplication and com.compose.chi.di may import
  com.compose.chi.data.* (presentation, navigation, theme and analytics
  must go through :domain), and :app must not reference retrofit2
  anywhere (broadened from the previous presentation-only guard).

:domain and :data gain testImplementation(libs.konsist) so the suites
can run there. Konsist.scopeFromProject() still walks the whole project
tree, so path / package matchers keep working from any module.

26 architecture test methods before, 26 after: every rule preserved,
two strengthened. The redundant RemoteApi and Repository test classes
in :app are deleted; their assertions live with their owners.
Three small follow-ups to the modularization work:

- Extract BASE_URL_JOKES into data/remote/NetworkConfig.kt (internal)
  so DI stays focused on wiring.
- Rename OfficialJokeApi.kt to JokeApi.kt to match the interface it
  declares.
- Align :app namespace and applicationId from com.example.chi to
  com.compose.chi to match where the code lives.
Update documentation after the three-module split.

- Refresh README architecture, project structure, testing, roadmap, and checklist sections
- Add modularization documentation covering module ownership, dependency direction, DI split, test fixtures, and architecture guardrails
- Update testing documentation to reflect the new :domain, :data, and :app test layout
- Update changelog with the Phase 5 modularization summary
- Clarify that :app depends on :data only as the Android composition root, while presentation code depends on domain abstractions
@ramyassaf
ramyassaf merged commit 449797a into main May 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant