Contacts Assessment App
A simplified Kotlin Multiplatform (KMP) contacts management app designed for technical interviews. This app mirrors GART architecture patterns and contains intentional bugs for candidates to identify and fix.
Project Overview
This is an Android-focused KMP app that displays contacts and groups with the following features:
- Bottom navigation with Groups and Contacts tabs
- Status badges for contacts (Active, Pending, Inactive)
- Nostr-style npub identifiers for contacts
- Avatar images loaded from network
- Room database with reactive Flow-based queries
- Clean Architecture with domain, data, and presentation layers
- ViewObjects (VOs) separating domain from presentation
- Dependency injection with Koin
Getting Started
Prerequisites
- Android Studio Ladybug (2024.2.1) or newer
- Android SDK 26+
- JDK 17 is auto-provisioned by the Gradle toolchain — no manual install needed
Build & Run
# Build debug APK
./gradlew assembleDebug
# On Windows, use:
gradlew.bat assembleDebug
# Install on connected device
adb install -r composeApp/build/outputs/apk/debug/composeApp-debug.apk
# Or run directly from Android Studio
Troubleshooting
| Problem | Fix |
|---|---|
Unsupported class file major version |
The toolchain should handle this automatically. If not, ensure JDK 17+ is installed. |
| Out of memory during build | Increase heap in gradle.properties: org.gradle.jvmargs=-Xmx3072M |
SDK location not found |
Create a local.properties file with sdk.dir=/path/to/your/Android/Sdk |
| Gradle sync fails in Android Studio | File -> Invalidate Caches -> Restart, then re-sync. |
Architecture
composeApp/src/
├── androidMain/kotlin/io/assessment/contacts/
│ ├── ContactsApplication.kt
│ ├── MainActivity.kt
│ └── di/DatabaseModule.kt # Android-specific Room setup
└── commonMain/kotlin/io/assessment/contacts/
├── App.kt
├── MainViewModel.kt
├── core/
│ ├── data/
│ │ ├── database/ # Room entities, DAOs, DatabaseSeeder
│ │ ├── datasource/ # Data sources
│ │ └── repository/ # Repository implementations
│ ├── domain/
│ │ ├── contact/ # Contact, ContactStatus, ContactError
│ │ ├── group/ # Group, GroupError
│ │ ├── result/ # Result type utilities
│ │ └── usecase/ # Use case interfaces
│ └── presentation/ # Shared presentation utilities
├── contacts/
│ ├── data/ # ContactMapper
│ ├── domain/ # ObserveContactsUseCase
│ ├── di/ # ContactsModule
│ └── presentation/ # ViewModel, Screen, State, ContactVO
├── groups/
│ ├── data/ # GroupMapper
│ ├── domain/ # ObserveGroupsUseCase
│ ├── di/ # GroupsModule
│ └── presentation/ # ViewModel, Screen, State, GroupVO
├── designsystem/ # Theme, Colors, Typography
├── navigation/ # NavigationRoot, BottomNavDestItem
└── di/ # App-level DI modules
Description
Languages
Kotlin
100%