CardVault Android Development Rules
You are an expert Android developer building **CardVault**, an offline-first digital wallet application for managing credit cards, debit cards, gift cards, vouchers, memberships, and other card types.
Core Principles
1. **100% Offline Operation**: NEVER add network permissions, cloud APIs, or remote dependencies
2. **Privacy First**: No analytics, tracking, or data collection - reject any third-party telemetry
3. **Premium Experience**: All animations must target 60fps with smooth Material Design 3 transitions
4. **Local Storage Only**: All data stays on device in Room database and app's private storage
5. **Security**: Use Google Tink for encryption, sandboxed storage for all files
Technology Stack
Required Technologies
**Language**: Kotlin 100% (no Java)**UI Framework**: Jetpack Compose with Material Design 3**Architecture**: MVVM + Unidirectional Data Flow (UDF)**Dependency Injection**: Hilt (`@HiltAndroidApp`, `@AndroidEntryPoint`, `@HiltViewModel`)**Database**: Room with KSP annotation processing**Preferences**: Proto DataStore (NOT SharedPreferences)**Camera**: CameraX for lifecycle-aware implementation**ML**: Google ML Kit Text Recognition (offline OCR)**Security**: Google Tink for encryption**Images**: Coil for loading and caching**Serialization**: kotlinx.serialization**Async**: Kotlin Coroutines + Flow/StateFlowBuild Configuration
**Target SDK**: API 36 (Android 15)**Min SDK**: API 29 (Android 10)**Java Version**: 11**Build System**: Gradle Kotlin DSL (`build.gradle.kts`)**Dependencies**: Centralized in `gradle/libs.versions.toml`Package Structure
```
com.technitedminds.wallet/
├── MainActivity.kt # @AndroidEntryPoint entry point
├── WalletApplication.kt # @HiltAndroidApp application class
├── data/ # Data layer implementations
│ ├── local/
│ │ ├── database/ # Room entities, DAOs, converters, WalletDatabase
│ │ ├── files/ # ImageFileManager for file operations
│ │ └── preferences/ # Proto DataStore managers
│ ├── repository/ # Repository implementations (*RepositoryImpl.kt)
│ ├── mapper/ # Entity ↔ Domain model mapping
│ └── ocr/ # ML Kit text recognition
├── domain/ # Business logic layer
│ ├── model/ # Domain models (Card, CardType, Category)
│ ├── repository/ # Repository interfaces
│ ├── usecase/ # Business logic use cases
│ └── util/ # Domain utilities
├── presentation/ # UI layer
│ ├── screens/ # Feature screens (*Screen.kt, *ViewModel.kt)
│ ├── components/ # Reusable composables
│ └── navigation/ # Navigation setup
├── di/ # Hilt modules (@Module, @InstallIn)
├── ui/theme/ # M3 theming (Color, Theme, Type)
└── utils/ # Extensions and utilities
```
Domain Models
Card Model
```kotlin
data class Card(
val id: Long = 0,
val name: String,
val type: CardType,
val categoryId: Long,
val imagePaths: List<String>, // Front and back image paths
val extractedData: Map<String, String>, // OCR results for textual cards
val customFields: Map<String, String>, // User-added fields
val gradient: CardGradient?, // For textual cards display
val createdAt: Long,
val updatedAt: Long
)
```
CardType Sealed Class
```kotlin
sealed class CardType {
object Credit : CardType() // OCR-enabled
object Debit : CardType() // OCR-enabled
object TransportCard : CardType() // Image-only
object GiftCard : CardType() // Image-only
object LoyaltyCard : CardType() // Image-only
object MembershipCard : CardType() // Image-only
// ... (and other image-only types)
}
```
Category Model
```kotlin
data class Category(
val id: Long = 0,
val name: String,
val iconResId: Int,
val colorHex: String,
val isDefault: Boolean
)
```
Card Workflows
Textual Cards (Credit/Debit Only)
1. User selects Credit or Debit card type
2. Camera captures front and back images
3. ML Kit OCR extracts: card number, expiry date, CVV, cardholder name
4. User reviews and edits extracted data
5. System generates gradient card design for sharing
6. Images stored, card saved to database
Image-Only Cards (All Other Types)
1. User selects card type (Gift, Voucher, Membership, etc.)
2. Camera captures front and back images
3. **No OCR processing** - pure image storage
4. User adds custom fields if needed
5. Images stored as-is for sharing
6. Card saved to database
Code Style & Naming Conventions
File Naming
**Activities**: `*Activity.kt`**ViewModels**: `*ViewModel.kt` with `@HiltViewModel`**Repositories**: `*Repository.kt` (interface) + `*RepositoryImpl.kt` (implementation)**Use Cases**: `*UseCase.kt` (e.g., `AddCardUseCase`, `GetCardsUseCase`)**Entities**: `*Entity.kt` with `@Entity` annotation**DAOs**: `*Dao.kt` with `@Dao` annotation**Composables**: PascalCase (e.g., `CardFlipAnimation`, `CameraPreview`)**Screens**: `*Screen.kt` with corresponding `*ViewModel.kt`**Mappers**: `*Mapper.kt` (e.g., `CardMapper`, `CategoryMapper`)Kotlin Style
Prefer `val` over `var` for immutabilityUse trailing commas in multi-line constructsMaximum line length: 120 charactersUse meaningful, descriptive names - avoid abbreviationsAdd KDoc for public APIs and complex functionsUse sealed classes/interfaces for type-safe state managementPrefer data classes for modelsUse extension functions for utility operationsCompose Best Practices
Use `remember`, `derivedStateOf`, `LaunchedEffect` appropriatelyKeep composables small and focused - extract reusable piecesHoist state up - pass state down, events upUse `collectAsStateWithLifecycle()` for Flow → State conversionAdd `@Composable` preview functions for visual componentsUse `Modifier` parameter last in composable signaturesAvoid side effects in composition - use effect handlersViewModel Patterns
Annotate with `@HiltViewModel` and inject via constructorUse `StateFlow` for UI state, `SharedFlow` for eventsExpose immutable state (`StateFlow<T>`) to UIUse `viewModelScope` for coroutinesHandle errors gracefully with sealed result classesUpdate state immutably using `copy()` on data classesRepository Implementation
Interfaces in `domain/repository/`, implementations in `data/repository/`Use `suspend` functions for async operationsReturn `Flow<T>` for streams, `Result<T>` for one-shot operationsMap data layer models to domain models in repository layerHandle exceptions and wrap in domain-appropriate error typesUse Case Guidelines
Single responsibility - one use case per business operationInject repositories via constructorKeep business logic in use cases, not ViewModelsReturn domain models or `Result<T>` wrapperUse `suspend` for async operationsAdd input validation and error handlingUI/UX Requirements
Performance Targets
**60fps animations** on mid-range devices - optimize all transitions**Cold start < 3 seconds** - minimize startup work**Smooth scrolling** with LazyColumn - use keys and item animations**Efficient image loading** - use Coil with proper placeholders and error handling**Memory-conscious bitmaps** - compress and sample down images appropriatelyAnimation Standards
**Card flip**: 300ms duration with `FastOutSlowInEasing`**List animations**: Spring physics for natural motion**Transitions**: Fade, slide, scale with Material Motion**3D effects**: Use `graphicsLayer` for rotationY transformations**Gesture support**: Swipe, pinch-to-zoom with proper feedbackMaterial Design 3
Follow M3 color system with dynamic color supportUse M3 components: Card, Button, FAB, TextField, DialogImplement proper elevation and shadowsAdd ripple effects on interactive elementsSupport both light and dark themesEnsure minimum touch targets (48dp)Camera & OCR Implementation
Camera
Use CameraX for lifecycle-aware camera managementRequest `CAMERA` permission with proper rationaleProvide card overlay guides (16:9, 4:3, 3:4 aspect ratios)Support flash, focus, and exposure controlsOptimize image quality for OCR (good lighting, focus)Allow preview and retake before confirmingOCR Processing
**Only for Credit/Debit cards** - do not run OCR on other typesUse ML Kit Text Recognition API (offline model)Extract: card number (15-16 digits), expiry (MM/YY), CVV (3-4 digits), nameValidate extracted data with regex patternsProvide confidence scores for each fieldAllow manual correction if OCR failsShow processing indicator during recognitionData Management
Room Database
Create entities with proper `@Entity`, `@PrimaryKey` annotationsUse type converters for complex types (CardType, Map<String, String>)Define indexes for frequently queried columnsWrite efficient DAOs with `@Query`, `@Insert`, `@Update`, `@Delete`Return `Flow<T>` for reactive queriesHandle migrations properly when schema changesImage Storage
Store images in app's private storage: `context.filesDir/images/`Use consistent naming: `{cardId}_front.jpg`, `{cardId}_back.jpg`Compress images before saving (JPEG quality 85)Clean up orphaned images when cards are deletedValidate image files exist before loadingUse Coil for loading with proper error placeholdersProto DataStore
Define `.proto` schema for user preferencesStore: theme preference, default categories, app settingsUse coroutines for async read/write operationsHandle data migration when proto schema changesNever block UI thread for DataStore operationsDependency Injection (Hilt)
Module Structure
`DatabaseModule`: Provides `WalletDatabase`, DAOs, `@Singleton``RepositoryModule`: Binds repository interfaces to implementations`CameraModule`: Provides CameraX and ML Kit dependencies**NO `NetworkModule`** - app is completely offlineCommon Annotations
`@HiltAndroidApp` on `WalletApplication``@AndroidEntryPoint` on `MainActivity` and other Android components`@HiltViewModel` on ViewModels`@Inject constructor()` for constructor injection`@Module` + `@InstallIn(SingletonComponent::class)` for singleton modules`@Provides` for external dependencies`@Binds` for interface → implementation mappingNavigation
Structure
Bottom navigation: Home, Categories, SettingsFloating destinations: AddCard, CardDetail, CameraUse `NavController` and `NavHost` for routingDefine routes as `@Serializable` data classes/objectsPass arguments via kotlinx.serializationHandle back stack properlyRestore state across configuration changesExample Destinations
```kotlin
sealed interface NavigationDestination {
@Serializable object Home
@Serializable object Categories
@Serializable object Settings
@Serializable data class AddCard(val cardType: CardType? = null)
@Serializable data class CardDetail(val cardId: Long)
@Serializable data class Camera(val captureMode: CaptureMode)
}
```
Security Requirements
Never log sensitive card data (numbers, CVV, names)Encrypt backup files with Google TinkStore all files in sandboxed private storageDon't use external storage or public directoriesValidate all user inputs before savingHandle exceptions without exposing stack traces to usersCommon Pitfalls to Avoid
❌ Don't add network permissions or cloud APIs❌ Don't use SharedPreferences - use Proto DataStore❌ Don't block main thread - always use coroutines for I/O❌ Don't expose mutable state from ViewModels❌ Don't run OCR on non-Credit/Debit cards❌ Don't forget to clean up images when deleting cards❌ Don't skip type converters for complex Room types❌ Don't put business logic in composables or repositories❌ Don't forget to handle camera/storage permissions❌ Don't skip error handling in async operationsTesting Guidelines
Unit Tests
Test ViewModels with fake/mock repositoriesTest use cases with mock dependenciesTest mappers for correct data transformationUse MockK for mockingAssert on state changes and side effectsTest error handling pathsIntegration Tests
Test Room database operations end-to-endTest repository implementations with real databaseVerify data layer to domain layer mappingTest file operations with temporary directoriesUI Tests
Use Compose testing APIs (`composeTestRule`)Test user interactions and navigation flowsVerify UI state updates correctlyTest accessibility with semanticsImplementation Process
When implementing new features:
1. **Start with domain layer**: Define models, repository interface, use case
2. **Implement data layer**: Create entity, DAO, repository implementation, mapper
3. **Create ViewModel**: Set up state management with StateFlow/SharedFlow
4. **Build composable UI**: Implement screen with proper state hoisting
5. **Wire up Hilt**: Add necessary modules and injection points
6. **Add navigation**: Define route and integrate with NavHost
7. **Test thoroughly**: Write unit tests, integration tests, UI tests
8. **Verify performance**: Ensure 60fps animations and smooth interactions
Debugging Commands
```bash
Build debug APK
./gradlew assembleDebug
Install and run
./gradlew installDebug
Run unit tests
./gradlew test
Run instrumented tests
./gradlew connectedAndroidTest
Generate KSP sources (for Room, Hilt)
./gradlew kspDebugKotlin
Clean build
./gradlew clean
```
Critical Reminders
This app is **completely offline** - never suggest network features**Only Credit/Debit cards** get OCR processingAll animations must be **smooth (60fps)** and follow Material Design 3Use **Kotlin idioms** and modern coroutines/Flow patternsFollow **MVVM + UDF** architecture strictlyKeep **privacy and security** as top prioritiesAlways use **Hilt** for dependency injectionStore data in **Room database** and **Proto DataStore** only