Files
bikeApp/android

BikeSetup Android App

Android client for the BikeSetup backend. Built with Kotlin, Jetpack Compose, and Ktor.

Stack

  • UI: Jetpack Compose + Material 3 (dark theme default)
  • Architecture: MVVM with ViewModels, single-activity
  • Navigation: Jetpack Navigation Compose
  • DI: Koin
  • Networking: Ktor client (OkHttp engine) with automatic cookie jar for session auth
  • Serialization: Kotlinx Serialization
  • Testing: JUnit, MockK, coroutine test utilities, Robolectric, Compose UI test APIs

Project Structure

com.bikeloam.app/
├── data/
│   ├── model/          # Auth, Catalog, Build, Review DTOs
│   ├── network/        # Ktor HttpClient + BikeApiClient
│   └── repository/     # BikeRepository (Result-wrapped API calls)
├── di/
│   └── AppModule.kt    # Koin module wiring
├── navigation/
│   └── BikeAppNavGraph.kt
└── ui/
    ├── screen/         # 10 Composable screens
    ├── theme/          # Material3 theme + colors
    └── viewmodel/      # 9 ViewModels (MVVM)

Setup

  1. Install Android SDK and set the path in local.properties:

    sdk.dir=/path/to/your/Android/Sdk
    
  2. Generate the Gradle wrapper jar (if missing):

    gradle wrapper
    

    Or open the project in Android Studio.

  3. Start the backend server:

    cd ..
    npm run dev
    
  4. Build the app:

    ./gradlew assembleDebug
    
  5. Install on an emulator or device:

    ./gradlew installDebug
    
  6. Run JVM unit tests:

    ./gradlew testDebugUnitTest
    

API Configuration

The debug build points to http://10.0.2.2:3000 (emulator localhost). For a physical device, update BASE_URL in app/build.gradle.kts to your machine's LAN IP (e.g., http://192.168.1.x:3000).

buildConfigField("String", "BASE_URL", "\"http://YOUR_IP:3000\"")

Features

  • Splash + Auth Gate: On cold start, checks /api/auth/me. Authenticated users skip Login.
  • Authentication: Register / Login / Logout via cookie-based JWT sessions.
  • Catalog Browsing: Fetches frames, forks, shocks, and tires from /api/catalog.
  • Build Management: Create builds with component selection dropdowns. View build details with resolved component names.
  • Ride Reviews: Submit post-ride reviews with 110 sliders and issue checkboxes.
  • AI Recommendations: Fetches setup recommendations from /api/ai/recommend.

Tests

Unit tests live under app/src/test/java/com/bikeloam/app/ and cover the repository, all ViewModels, network layer, and Compose screens:

  • BikeRepositoryTest
  • NetworkClientTest
  • SplashViewModelTest
  • LoginViewModelTest
  • RegisterViewModelTest
  • HomeViewModelTest
  • BuildListViewModelTest
  • CreateBuildViewModelTest
  • BuildDetailViewModelTest
  • ReviewViewModelTest
  • RecommendationViewModelTest
  • LoginScreenTest (Compose UI Robolectric)
  • HomeScreenTest (Compose UI Robolectric)

Use MainDispatcherRule for coroutine dispatcher replacement in ViewModel tests. Run the full JVM suite with:

./gradlew testDebugUnitTest

Architecture Notes

  • Session cookies are handled automatically by Ktor's HttpCookies plugin.
  • No local.properties should be committed (it's .gitignored).
  • Network security config allows cleartext HTTP for development (10.0.2.2).

Next Steps / Known Limitations

  • No individual GET /api/builds/:id endpoint exists on the backend; the detail screen fetches the full list and filters by ID.
  • Component images are not yet loaded (Coil is included but image URLs aren't resolved from the backend yet).
  • Add offline caching (Room) for catalog and builds if desired.