feat(di): full Hilt migration — delete ServiceLocator, all 12 ViewModels injected#14
feat(di): full Hilt migration — delete ServiceLocator, all 12 ViewModels injected#14fabiodalez-dev wants to merge 4 commits into
Conversation
…idges the rest) A working proof-of-concept of the "root-cause" DI fix (the testability lever), done incrementally so it's safe to land before the full migration. - Hilt wired: @HiltAndroidApp (PinakesApplication), @androidentrypoint (MainActivity), hilt-android + hilt-android-compiler (kapt) + hilt-navigation-compose. - AppModule: an incremental-migration BRIDGE — it exposes to Hilt the SAME singletons the manual ServiceLocator already owns (session/stores/network/repositories), so a Hilt-injected ViewModel and a ServiceLocator-built one share one instance each (no auth-state / cache desync while the migration is half-done). - Home slice migrated end-to-end: HomeViewModel is now @hiltviewmodel @Inject (its hand-written ViewModelProvider.Factory is deleted); HomeScreen builds it with hiltViewModel(). The other 9 screens are untouched and keep using LocalServices. Why this matters: once every screen is on Hilt, the AppModule bridges become real @provides (or @Inject constructors), ServiceLocator is deleted, and repositories become unit-testable by swapping fakes via @TestInstallIn — which unblocks the CatalogRepository network tests (the original goal). Verified: assembleDebug builds (kapt validates the full Hilt graph — every binding resolves); testDebugUnitTest 37/37 green. NOTE: needs a device smoke-test (launch → Home renders) before merge — Hilt graph correctness is compile-checked, runtime wiring is not.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… ViewModels injected Finishes the Hilt trial into a full migration. The manual ServiceLocator + LocalServices CompositionLocal are gone; Hilt owns the whole dependency graph. - AppModule: real @provides @singleton for every store/network/db/dao/repository (no longer a bridge to ServiceLocator). - All 12 ViewModels are @hiltviewmodel @Inject and their hand-written ViewModelProvider .Factory classes are deleted; every screen builds its VM with hiltViewModel(). BookDetailViewModel reads its bookId nav-arg from an injected SavedStateHandle. - App-wide state (auth state, feature flags, theme) moves to a new AppViewModel (@hiltviewmodel) — replaces LocalServices. NavHost/MainScaffold use hiltViewModel(); MainActivity field-injects SessionStore/ThemeStore/AuthRepository. - Code that can't be constructor-injected reaches Hilt via an EntryPoint: the CatalogSyncWorker (WorkManager-created) and the Application's foreground-refresh observer. - Deleted di/ServiceLocator.kt and ui/common/LocalServices.kt. Why it matters: repositories/ViewModels are now unit-testable by swapping fakes via @TestInstallIn (the original goal — unblocks the CatalogRepository network tests). Verified: assembleDebug builds — kapt validates the ENTIRE Hilt graph (every binding across all 12 ViewModels + EntryPoints resolves); testDebugUnitTest 37/37 green. NOTE: still needs a device smoke-test (launch → each tab/screen renders, theme switch, book detail) before merge — Hilt graph correctness is compile-checked, runtime is not.
Auto-recommendation acceptance
1 auto-rec finding eligible at threshold ≥ 60. 1 auto-promoted via batch, 0 edited, 0 skipped. Promoted (batch)
Auto-recommendation acceptance: append-only audit. Promoted findings are now |
…F004) Fix groups (committed): - [FG-1] F004 — BookDetailScreen.kt, PinakesNavHost.kt: verified The Hilt migration moved book-id reading into BookDetailViewModel via SavedStateHandle, leaving the bookId parameter on BookDetailScreen and its nav-host extraction as dead pass-through. Removed both; kept the navArgument(ARG_BOOK_ID) declaration that feeds SavedStateHandle. Post-fix review: 1/1 groups verified complete; 0 partial; 0 reverted.
Code reviewBranch: Found 8 findings across all lanes:
Deep lane — correctness & securityPre-existing — report-only (2)Shown only when
Fix runsRun
|
| Finding | Group | Outcome | phase_9_finding |
|---|---|---|---|
| F004 | FG-1 | ✓ fixed and verified |
🤖 Generated with Adam's Claude Code Review Command
New release including the Hilt DI migration and the F004 dead-parameter cleanup.
- #11 CatalogSyncWorker: retry only TRANSIENT failures; give up (success) on permanent ones (401/403/app_disabled/validation/not_found) so the periodic chain isn't stuck retrying an unrecoverable condition. Classification is a pure isPermanentFailure() so it's unit-testable without Android/Hilt. - #13 CatalogSyncWorkerTest: rewritten — the old 'no-op on plain context' test was written for the pre-Hilt (ServiceLocator) worker and broke under #14's EntryPointAccessors migration. Now covers the real branch (permanent vs transient) via the pure function. - #9 HomeViewModel: don't flip loading=false on an empty cache emission — keep the skeleton until the first refresh resolves, so a cold start no longer flashes the 'empty library' state while the network is in flight. - #10 CI: build the release variant too (assembleRelease) so R8/minify is exercised in CI, not only at runtime. Merged the 7-PR stack (#8 navbar/reserve, #9 offline cache, #10 CI/R8, #11 WorkManager sync, #12 Sentry, #13 tests, #14 Hilt) into main; the libs.versions.toml conflict (#13 work-testing vs #14 Hilt libs) resolved as a union. Full build green: 67 unit tests, assembleDebug + assembleRelease.
Full migration of the app's DI from the manual
ServiceLocatorto Hilt. Stacked on the Sentry branch.What
ServiceLocator+LocalServicesdeleted. Hilt owns the whole graph.AppModule: real@Provides @Singletonfor every store / network / DB / DAO / repository.@HiltViewModel @Inject; their hand-writtenViewModelProvider.Factoryclasses are gone; every screen builds its VM withhiltViewModel().BookDetailViewModelreads itsbookIdnav-arg from an injectedSavedStateHandle.AppViewModel(@HiltViewModel), replacingLocalServices.NavHost/MainScaffoldusehiltViewModel();MainActivityfield-injects the stores.CatalogSyncWorker, the Application foreground-refresh observer) reaches Hilt via an@EntryPoint.Why it matters
Repositories/ViewModels are now unit-testable by swapping fakes via
@TestInstallIn— the original goal that unblocks theCatalogRepositorynetwork tests.Verified
assembleDebugbuilds — kapt validates the entire Hilt graph (every binding across all 12 ViewModels + the EntryPoints resolves).testDebugUnitTest37/37 green.Caveat
Hilt graph correctness is compile-checked; runtime wiring is not. Needs one device smoke-test (launch → each tab renders, theme switch, open a book) before merge.
Note for the test branch (#13)
#13'sCatalogSyncWorkerTestasserts the worker is a no-op under a non-PinakesApplicationcontext. This branch switches the worker to a Hilt@EntryPoint, so that test must be updated to a Hilt test (@HiltAndroidTest+HiltTestApplication) when the two branches reconcile.