119 lines
3.7 KiB
Markdown
119 lines
3.7 KiB
Markdown
# 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`:
|
||
```properties
|
||
sdk.dir=/path/to/your/Android/Sdk
|
||
```
|
||
|
||
2. Generate the Gradle wrapper jar (if missing):
|
||
```bash
|
||
gradle wrapper
|
||
```
|
||
Or open the project in Android Studio.
|
||
|
||
3. Start the backend server:
|
||
```bash
|
||
cd ..
|
||
npm run dev
|
||
```
|
||
|
||
4. Build the app:
|
||
```bash
|
||
./gradlew assembleDebug
|
||
```
|
||
|
||
5. Install on an emulator or device:
|
||
```bash
|
||
./gradlew installDebug
|
||
```
|
||
|
||
6. Run JVM unit tests:
|
||
```bash
|
||
./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`).
|
||
|
||
```kotlin
|
||
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 1–10 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:
|
||
|
||
```bash
|
||
./gradlew testDebugUnitTest
|
||
```
|
||
|
||
## Architecture Notes
|
||
|
||
- **Session cookies** are handled automatically by Ktor's `HttpCookies` plugin.
|
||
- **No `local.properties`** should be committed (it's `.gitignore`d).
|
||
- **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.
|