Skip to content

Study streak system#16

Merged
bootuz merged 8 commits into
mainfrom
feature/streak-system
Jun 5, 2026
Merged

Study streak system#16
bootuz merged 8 commits into
mainfrom
feature/streak-system

Conversation

@bootuz
Copy link
Copy Markdown
Owner

@bootuz bootuz commented Jun 5, 2026

Summary

Sub-project 2 of 2 for the streak system. Adds a daily study streak (consecutive days with ≥1 review) to the "Today" home header and the session-complete summary, derived purely from the review logs persisted in sub-project 1.

⚠️ Stacked on PR #15 (feature/review-log-sync) — it provides ReviewLogRepository.observeLogs(). This PR is based on that branch so the diff shows only the streak work; merge #15 first, then this retargets to main.

  • Pure core: StreakCalculator (current + longest from civil-day indices) + a DST-safe localEpochDay bucketing helper (Calendar-based — minSdk 24 rules out java.time; the civil-day trick keeps 23h/25h DST days from breaking a streak).
  • StreakProvider: observeStreak() (live, reactive) for the home header; streakIncludingToday() (race-proof vs. the fire-and-forget log append) for the post-session summary.
  • Wiring: StudyQueueViewModel (outer-combine, leaving the existing aggregation untouched) + StudyViewModel; a 🔥 chip in the Today header and a streak badge in the summary's reserved slot.
  • Hard reset on a missed day (encouraging framing), longest shown only in the summary, no streak-freeze/milestones in v1. Derived — nothing stored.

Test plan

  • StreakCalculatorTest (rules: empty, only-today, consecutive, alive-through-yesterday, missed-day reset, longest-persists) + DayBucketingTest (same-day, consecutive, DST spring-forward).
  • StreakProviderTest — consecutive days, empty→0, streakIncludingToday forces today.
  • StudyQueueViewModelTest — live currentStreak from fake logs; existing aggregation tests untouched.
  • StudyViewModelTest — finishing a real session sets currentStreak == 1; empty-queue session does NOT fabricate today (regression test for the must-fix below).
  • Full unit-test suite green; :app:assembleDebug BUILD SUCCESSFUL; screens compile-verified + previews.
  • Manual smoke (pending emulator): study a card → "🔥 1" in the Today header + "🔥 1 day streak" badge; next day → "🔥 2".

Notes

Final holistic review caught one bug: load()'s empty-queue path reused the "force today" streak read, which could fabricate a streak just from opening a deck with nothing due. Fixed — the empty-queue path now uses the real (non-synthetic) streak; only a finished review forces today. Regression test added.

🤖 Generated with Claude Code

@bootuz bootuz changed the base branch from feature/review-log-sync to main June 5, 2026 08:20
@bootuz bootuz merged commit f856742 into main Jun 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant