[REFACTOR] Improve Local Major Subscription Management#105
Conversation
* Migrate SharedPreference to DataStore to manage local-side major subscription status
- Define DataStore (PreferenceDataStore) with SharedPreference Migration configuration, and register it to dependency graph.
* Improve Local-side management of Major Subscription status, as well as its method to perform server-side synchronization.
- Utilize DataStore and expose stored value(s) via Flow<T>. (Full migration would be performed as a next ticket.)
- Separate Local-side subscription management and server-side synchronization.
> Server-side synchronization would be performed on background, managed by WorkManager.
> Introduce new local values (SubscriptionPending and UnsubscriptionPending) to be accessed and used to perform server-side synchronization.
> Necessary CoroutineWorker and WorkManager job request (OneTimeWork) have been defined and declared.
- Appropriate modifications have been made on consumer-side to receive and process subscription status over Flow.
* Update dependency graph to provide new PreferenceDataStore and MajorSubscriptionUpdate CoroutineWorker to necessary consumers. * (CHORE) Update Build gradle to provide necessary library dependency (DataStore.)
There was a problem hiding this comment.
Code Review
This pull request migrates the application's subscription preferences from SharedPreferences to PreferenceDataStore and introduces a background worker (MajorSubscriptionUpdate) to synchronize major topic subscriptions with the server. Feedback on these changes highlights a critical early return bug in the worker that skips unsubscription logic when there are no new subscriptions, as well as a lack of exception handling. Additionally, the migration implementation in AppSubscriptionPreferenceRepositoryImpl lacks a fallback for the old preference key, which would cause existing users to lose their subscribed major. Finally, a guard check is recommended in NoticeByMajorViewModel to prevent redundant synchronization tasks when a user selects their already subscribed major.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- `MajorSubscriptionUpdate`: Worker has lack of exception handling, which could ignore background work completely in certain edge case (unexpected Exception thrown). Also, early return condition might skip the unsubscribing the pending majors, if SubscriptionPending list is empty. - `RemoteSubscriptionPreferenceRepositoryImpl`: SharedPreference migration logic applied to PreferenceDataStore is a `String` type value while up-to-date value for managing local-side Major Subscription status is Set<String> (updated with consideration of future business rule updates). Therefore, additional self-healing logic is applied to safely take pre-existing subscription value.
π Summary (κ°μ)
π Related Issue (κ΄λ ¨ μ΄μ)
π Type of Change (λ³κ²½ μ¬ν)
FEAT: New feature (μλ‘μ΄ κΈ°λ₯)FIX: Bug fix (λ²κ·Έ μμ )REFACTOR: Code refactoring (no functional change) (μ½λ 리ν©ν λ§)DESIGN: UI/UX changes (λμμΈ λ³κ²½)!HOTFIX: Critical fix (μΉλͺ μ μΈ λ²κ·Έ μμ )CHORE: Build/Config/CI (λΉλ/μ€μ /CI)β¨ Key Changes (ν΅μ¬ λ³κ²½ μ¬ν)
SharedPreferencetoPreferenceDataStore.Flow<T>and process it.AppSubscriptionPreferenceRepositoryis architected with consideration of future scalability.πΈ Screenshots / Video (μ€ν¬λ¦°μ· λλ λμμ)
π§ͺ Test Plan (ν μ€νΈ κ³ν)
NoticeByMajorScreen-> Select Major -> Check selected major is applied -> Check server-side synchronization is performed.β Checklist (체ν¬λ¦¬μ€νΈ)