feat(android): add API client, tRPC bridge, and offline support

- Add Retrofit with kotlinx-serialization converter for tRPC endpoints
- Create TRPCApiService with type-safe wrappers for all procedures
- Implement AuthInterceptor for JWT injection from EncryptedSharedPreferences
- Add ErrorHandler with exponential backoff retry logic and ApiResult sealed class
- Create 11 serializable data models matching backend enums
- Add JSON file-based cache with TTL invalidation (CacheManager)
- Implement repositories: User, DarkWatch, VoicePrint, Alert, Subscription
- Add offline sync: PendingRequestQueue, OfflineWorker, SyncManager
- Create manual DI modules: NetworkModule, DatabaseModule, RepositoryModule
- Add WorkManager for background offline request processing
- Add ConnectivityManager-based network monitoring for auto-sync
- Configure build system with KSP for Room, kotlinx-serialization plugin
- Update build config with environment-specific API URLs
- Write 19 new unit tests for ErrorHandler, CacheManager, TRPCResponse, SyncManager
This commit is contained in:
2026-05-25 20:41:53 -04:00
parent a90534e164
commit 3ccaeaa2e3
36 changed files with 1942 additions and 19 deletions

View File

@@ -17,6 +17,12 @@ okhttp = "4.12.0"
gson = "2.10.1"
lottieCompose = "6.4.0"
coroutinesTest = "1.7.3"
retrofit = "2.11.0"
retrofitKotlinxSerializationConverter = "1.0.0"
kotlinxSerializationJson = "1.7.3"
work = "2.9.1"
truth = "1.4.4"
mockwebserver = "4.12.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -43,8 +49,16 @@ okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhtt
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
lottie-compose = { group = "com.airbnb.android", name = "lottie-compose", version.ref = "lottieCompose" }
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutinesTest" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
retrofit-kotlinx-serialization-converter = { group = "com.jakewharton.retrofit", name = "retrofit2-kotlinx-serialization-converter", version.ref = "retrofitKotlinxSerializationConverter" }
okhttp-logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
okhttp-mockwebserver = { group = "com.squareup.okhttp3", name = "mockwebserver", version.ref = "mockwebserver" }
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" }
work-testing = { group = "androidx.work", name = "work-testing", version.ref = "work" }
truth = { group = "com.google.truth", name = "truth", version.ref = "truth" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }