chore: scaffold multi-module project, version catalog, and build-logic
Foundation milestone (REDI-78, REDI-79):
- Multi-module skeleton: :app, :core:{domain,data,presentation,design-system},
:feature:characters:{domain,data,presentation,presentation-compose,presentation-views},
:feature:about:presentation, plus the :build-logic composite build.
- gradle/libs.versions.toml as the single source of truth ([versions]/[libraries]/
[bundles]/[plugins]); no inline versions in any build file.
- Convention plugins: architecture.android.{application,library,feature,feature.views},
domain.module, compose, koin, ktor, kotlinx.serialization.
- Pure-Kotlin domain modules; presentation-compose uses android.feature;
presentation-views uses android.feature.views (ViewBinding on, Compose off);
the UI-agnostic :presentation has neither Compose nor Views deps.
- Toolchain: AGP 9.0.1, Kotlin 2.3.20, Gradle 9.1.0, compileSdk 36, minSdk 24, Java 17.
- Minimal MainActivity placeholder; CI (assembleDebug) via GitHub Actions.
Verified: ./gradlew projects lists the full tree and ./gradlew assemble is green.
This commit is contained in:
52
README.md
Normal file
52
README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Android Architecture Showcase
|
||||
|
||||
A single runnable **Android-only (Jetpack Compose)** reference app that demonstrates good
|
||||
architecture conventions — each in its own module/example. Teaching repo: every module is meant to
|
||||
be minimal but complete and idiomatic.
|
||||
|
||||
> **Status:** built milestone-by-milestone from the
|
||||
> [Linear backlog](https://linear.app/adrian-kuta/project/android-architecture-showcase-b5ecdeddda6c).
|
||||
> **Foundation** (scaffold, version catalog, `build-logic` convention plugins) is complete and the
|
||||
> project assembles green. Full architecture docs land with the *Quality & Docs* milestone.
|
||||
|
||||
## Stack
|
||||
|
||||
Multi-module Gradle + `build-logic` convention plugins · Koin (constructor DSL) · Ktor ·
|
||||
KotlinX Serialization · Coil · Kermit · type-safe Compose Navigation. Data comes from the no-key
|
||||
[Rick & Morty API](https://rickandmortyapi.com/).
|
||||
|
||||
What it will showcase: **MVI** as the primary presentation pattern (flagship *characters* feature),
|
||||
an **MVVM** contrast screen, and the same MVI `ViewModel` driven by **two renderers** — Jetpack
|
||||
Compose and classic **XML + ViewBinding + RecyclerView** — proving the presentation logic is
|
||||
UI-toolkit-agnostic.
|
||||
|
||||
## Module structure
|
||||
|
||||
```
|
||||
:app → wires everything; single Activity, Compose host
|
||||
:build-logic → Gradle convention plugins (the only place versions/config live)
|
||||
:core:domain → Result/error types, shared domain models (pure Kotlin)
|
||||
:core:data → Ktor HttpClient factory, safe-call helpers
|
||||
:core:presentation → UiText, ObserveAsEvents, DataError → UiText
|
||||
:core:design-system → AppTheme + reusable composables
|
||||
:feature:characters:domain → models + repository interface (pure Kotlin)
|
||||
:feature:characters:data → DTOs, mappers, data source, repository impl
|
||||
:feature:characters:presentation → MVI ViewModel/State/Action/Event (UI-agnostic: no Compose, no Views)
|
||||
:feature:characters:presentation-compose → Compose renderer
|
||||
:feature:characters:presentation-views → Views/XML renderer (same ViewModel)
|
||||
:feature:about:presentation → MVVM contrast screen
|
||||
```
|
||||
|
||||
**Dependency rules:** `presentation → domain ← data`; `domain` depends only on `:core:domain`;
|
||||
features never depend on other features; `:app` wires the graph.
|
||||
|
||||
## Build & run
|
||||
|
||||
```bash
|
||||
./gradlew assembleDebug # build the APK
|
||||
./gradlew projects # print the module tree
|
||||
./gradlew check # tests + lint (added in the Quality & Docs milestone)
|
||||
```
|
||||
|
||||
Requires JDK 17+ (the Gradle build pins a Java 17 toolchain) and the Android SDK
|
||||
(`compileSdk 36`, `minSdk 24`).
|
||||
Reference in New Issue
Block a user