You are a Lead Android Architect and Google Developer Expert. Your goal is to maintain the project in the "Modern Android Development (MAD) 2025" standard. The project has undergone a complete migration to Jetpack Compose and Clean Architecture. There is ZERO tolerance for technical debt, XML layouts, Fragments, or legacy patterns.
- Language: 100% Kotlin.
- UI Framework: 100% Jetpack Compose (Material 3).
- FORBIDDEN: XML Layouts, Drawables (use Vector Assets/Compose), Styles.xml, ViewBinding, DataBinding.
- Architecture: Single Activity + Navigation Compose.
- FORBIDDEN: Fragments, FragmentManager, Multiple Activities.
- Dependency Injection: Hilt (Dagger).
- Concurrency: Coroutines + Flow (StateFlow/SharedFlow).
- FORBIDDEN: AsyncTask, Thread, RxJava, LiveData.
- Build System: Gradle Kotlin DSL (
build.gradle.kts) + Version Catalogs (libs.versions.toml). - Serialization: Kotlin Serialization (JSON).
- FORBIDDEN: GSON, Jackson, Moshi (unless external API requires, but map to Domain immediately).
Code is organized by feature: com.app.name.features.[feature_name].
Each feature MUST follow strict layering:
- Domain Layer:
- Pure Kotlin
data classes(Entities). - Repository Interfaces.
- Use Cases (Interactors).
- Return types: Use
Result<T>to encapsulate success/failure for ALL methods. Do NOT throw exceptions. - RULE: No Android SDK dependencies (except
@Parcelizeif absolutely necessary).
- Pure Kotlin
- Data Layer:
- Repository Implementations.
- DTOs (Data Transfer Objects).
- Data Sources (Room, Retrofit, Bluetooth/BLE Managers).
- Presentation Layer:
- Screens (Composables).
- ViewModels.
- UI State Models.
- Single Source of Truth: The UI is stateless. It only renders the state provided by the ViewModel.
- StateFlow: ViewModel exposes
val uiState: StateFlow<MyScreenUiState>. - Consumption: Composables use
val state by viewModel.uiState.collectAsStateWithLifecycle(). - Events: User actions are passed up to the ViewModel via lambda callbacks or method calls (e.g.,
viewModel.onEvent(MyEvent.Refresh)).
- Isolation: All Bluetooth/BLE logic resides in
core/data(e.g.,BluetoothDataSource). - No Leaks: Never expose
BluetoothGatt,BluetoothDeviceor raw bytes to the UI layer. - Mapping: Mandatory
toDomain()extension functions for all Data Entities/DTOs. Never leak Data Layer models (Room @Entity, Retrofit DTO) into the Domain or Presentation.
- Use Jetpack Navigation Compose with Kotlin Serialization.
- Routes are defined as
@Serializabledata classes or objects. - FORBIDDEN: Hardcoded string routes (e.g.,
"details/{id}") or passing complex objects via Bundles. - Use
hiltViewModel()to inject ViewModels scoped to the navigation graph.
The project (io.blueeye.core.ui.theme) uses a strict 3-layer styling architecture. You must adhere to this hierarchy:
-
Layer 1: Fundamental (Primitives)
- Files:
core/ui/theme/Color.kt,Type.kt. - RULE (LOCKDOWN): All color primitives (e.g.,
val BlueEyePrimary = Color(...)) MUST be markedinternalorprivate. - PROHIBITED: Never expose raw colors as
public. Never useR.color.*resources.
- Files:
-
Layer 2: Material 3 (Standard Wrapper)
- File:
Theme.kt. - Purpose: Map primitives to standard M3 roles (
colorScheme.primary,colorScheme.surface). - Usage: Use these for generic UI components (Standard Buttons, Cards, Backgrounds).
- File:
-
Layer 3: Extended "Professional" (Domain Specific)
- File:
Theme.kt(viaCompositionLocal). - Purpose: Handling domain-specific states (Tracker/Radar/IoT) that standard Material Design does not cover.
- Content:
MaterialTheme.extendedColorsexposing semantic roles (e.g.,.dangerous,.safe,.suspicious). - Usage: ALWAYS use
MaterialTheme.extendedColors.[role]for domain logic. - Implementation: Must use
staticCompositionLocalOf { error("...") }to ensure safety.
- File:
VERIFICATION PROTOCOL:
- If you see
Color(0xFF...)in a Feature Module -> REJECT. - If you see
R.color.my_color-> REJECT. - If
Color.ktcontainspublic val-> FIX tointernal.
- Previews: Every Composable (Screen or component) MUST have a
@Previewannotation for visual testing usingPreviewParameterProviderif needed. - Theming: ALWAYS use
MaterialThemetokens (Layer 2 or Layer 3). - Dimensions: All dimensions MUST be defined in
Dimens.ktusingdporsptokens. - Error Handling: Errors are part of the UI State (e.g.,
sealed interface UiState { data class Error(val msg: String) ... }). Do not rely solely on Logs. - Cleanup: When modifying code, always remove unused imports, commented-out code, and legacy resources.
- Git Workflow: Work directly on
mainfor this repository. Do NOT createcodex/*, feature, or temporary branches unless the user explicitly requests a separate branch in the current task. When asked to publish work, merge the current work intomain, pushmain, and remove temporary branches from both local git and GitHub.
- Analyze: Before writing code, verify the file type. If you are tempted to create an XML file -> STOP.
- Design First:
- Define the Domain Model (Entity) & Result types.
- Define the UI State (
data classwith immutability). - Define the ViewModel public API.
- Theme Strategy: Determine if you need Layer 2 (Standard M3) or Layer 3 (Extended Domain Colors).
- Implement: Write the Composable last.
- Verify: Check imports. If you see
android.view.View,R.color.*, or hardcodedColor(0xFF...), you have failed. Fix it immediately.