Streaks, Stats, and Gamification (TryRamadan)
Use this skill when changing streak logic, badges, excused vs non-excused, or the "Show streak and achievements" preference so behavior and copy stay consistent with the documented flows.
1. Fasting streak
- •Definition: Consecutive calendar days ending on "today" where each day is either completed (full fast) or broken with excused reason (illness, travel, menstruation, medical). Excused days do not break the streak; they extend it.
- •Helpers:
getStreakDays(progress, todayOverride?),calculateStreak(progress, todayOverride?)insrc/hooks/useLocalStorage.ts. PasstodayOverride(e.g. from display timezone) so streak uses the same "today" as the rest of the app (see ramadan-calendar-and-fasting-logic skill). - •Breaking the streak: Skipped day ("I didn't fast today"), broken with non-excused reason (e.g. "Ate by mistake", "Other"), or day left untracked — streak resets when looking backward from today.
- •Copy: Neutral, no guilt. Tooltip: "Consecutive days you completed the full fast or had an excused break (e.g. illness, travel). Excused days don't reset your streak — that's okay."
2. Excused reasons
- •IDs:
['illness','travel','menstruation','medical']. Stored infastingLogasbrokenReason. Used bygetExcusedFastDays(progress); streak and longest-streak calculations treat these as streak-preserving. - •Longest streak:
getLongestStreak(progress)— longest run of consecutive days where each is completed or excused (any order).
3. Non-fasting achievements
- •Journal streak: Consecutive days (ending today) with at least one journal entry —
getJournalStreak(entries). - •Mindful eating streak: Consecutive days with both suhoor and iftar logged —
getMindfulEatingStreak(foodLogs, mealPlans). - •UI: Progress page shows "Non-fasting wins" (journal streak, both meals logged) when present. Badges (streak-5, streak-10, etc.) and "Current streak" / "Badges" sections respect
showStreakAndAchievements.
4. Preference: Show streak and achievements
- •Key:
preferences.showStreakAndAchievements(defaulttrue). Whenfalse, Dashboard hides streak card and milestone celebration; Progress hides Current streak, Longest streak, and Badges section; Settings still shows streak in "Data Management" preview. - •Data: Toggling this preference does not change progress or streak calculation; it only hides/shows UI. Streak must use same "today" as Dashboard (todayOverride) to avoid showing 0 after toggle (see Regression: BUG-STRK-001).
5. Tests and doc
- •Tests:
src/test/loggingAndTracking.test.ts(streak, excused days, todayOverride); Regression: BUG-STRK-001. - •Doc:
docs/STREAKS-STATS-GAMIFICATION-FLOWS.md(building/breaking streak, copy tone, disabling streak, non-fasting wins).