Ubisam-MobileGit/tasks/034-favorite-star-count-not-incrementing.md
choiminyeong 6dbb37d067 TASK-034: fix favorite star count not incrementing after a successful star
toggleFavorite's ALL-list success branch updated favoriteAction to
Starred but never touched starsCount, so a row kept showing its
pre-star count even after the server had actually accepted it. Now
increments starsCount by 1 in the same update. Also guards against a
repeat tap on an already-Starred row (the ALL list can't tell a
repo's already-starred state on load, so the star stays tappable)
double-incrementing the displayed count.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 16:37:17 +09:00

4.9 KiB

TASK-034: Star count doesn't increment after a successful favorite

Status: implemented; all required checks pass; live-installed, awaiting the human product owner's confirmation Owner: Claude Reviewer: Codex

Outcome

Following TASK-033's OAuth scope fix, the human product owner confirmed starring itself now works ("별표 눌러서 즐겨찾기는 되는데") but reported the displayed star count doesn't go up ("카운팅은 안올라가네"). toggleFavorite's ALL-list success branch updated only favoriteAction (to Starred) and never touched starsCount, so a row kept showing whatever count the last full list load had returned, even after a star that the server had actually accepted. Fixed by incrementing the row's starsCount in the same state update that marks it Starred. While fixing this, found and closed a related gap: a repeat tap on an already-Starred row (the ALL list has no way to know a repository's already-starred state on initial load, so the star stays tappable) would have re-called star() and double-incremented the client-displayed count each time — now a no-op.

Scope

  • Included: feature/repositories/RepositoryListViewModel.kt (toggleFavorite only), matching test additions in RepositoryListViewModelTest.kt.
  • Excluded: No change to the FAVORITES-list unstar path (removing the row entirely already made its count irrelevant, no bug there). No change to how the initial list load populates starsCount (that already came from Gitea's own response, unaffected). No attempt to fetch the server's authoritative post-star count instead of incrementing client-side (see Design notes).

Design notes

  • Optimistic +1, not a re-fetch: Gitea's star endpoint (PUT, 204 No Content) doesn't return the new count, so getting the authoritative number back would mean a second network call (re-fetching the repository) purely to update one number — not worth it for a value the app already knows how to derive from something it just confirmed itself (the star succeeded, so the count is exactly one higher than what was last displayed).
  • The repeat-tap guard closes a real double-count bug, not just a hypothetical one: because the ALL list can't determine a repository's already-starred state on load (an existing, accepted limitation from TASK-018/TASK-030), a Starred row's star icon stays enabled and tappable — nothing before this fix stopped a second tap from calling star() again and incrementing the displayed count a second time for a repository the user only starred once. The guard checks the row's own favoriteAction before doing anything, so it also saves a redundant network call, not just a redundant +1.

Acceptance criteria

  • Starring a repository from the ALL list increments its displayed star count by exactly 1.
  • Tapping an already-Starred row again does not call star() a second time and does not change the displayed count further.
  • Unstarring from the FAVORITES list is unaffected (row removal, no count to update).
  • Build, unit tests, and lint pass.
  • Live confirmation from the human product owner that the count now visibly increments on tap — installed on the device but not yet re-tested in this exact session.

Required checks

./gradlew compileDebugKotlin compileDebugUnitTestKotlin
./gradlew testDebugUnitTest
./gradlew assembleDebug lintDebug

Evidence

  • RepositoryListViewModel.kt: toggleFavorite's ALL-list success branch now updates starsCount = it.starsCount + 1 alongside favoriteAction = Starred; new early-return guard when the row's favoriteAction is already Starred.
  • RepositoryListViewModelTest.kt: repo() test helper gained a starsCount parameter; two new tests — starring increments the displayed count by 1; a repeat tap after a successful star is a no-op (no second star() call, count stays at 1).
  • ./gradlew compileDebugKotlin compileDebugUnitTestKotlin: BUILD SUCCESSFUL.
  • ./gradlew testDebugUnitTest: BUILD SUCCESSFUL, all unit tests passing (including the two new ones above).
  • ./gradlew assembleDebug lintDebug: BUILD SUCCESSFUL, 0 lint errors.
  • Installed on the human product owner's device over wireless adb (adb install -r, streamed install succeeded); not yet re-tested live in this exact session.

Known limitations

  • Still optimistic, not authoritative: if Gitea's real count differs from this app's local increment for any reason (e.g. another client starred the same repo around the same time), the displayed number stays off until the next full list reload. Considered an acceptable tradeoff given the alternative (a second network call per star) for a rarely-contended personal count.
  • The underlying "can't tell if already starred on initial load" limitation (TASK-018/TASK-030) is unchanged — this task only stops it from causing a visible count bug, it doesn't resolve the limitation itself.

Review findings

None yet — pending Codex/human review.