Problem
The streak qualifies a day as "practiced" only when a single activity session reaches MIN_STREAK_DURATION_MS = 120_000 (2 min). See zeeguu/api/endpoints/helpers/activity_sessions.py:23-31.
This means two 1-minute sessions on the same day do not qualify, even though the user practiced for 2 minutes total. Realistic patterns where this hurts:
- A short replay of a past audio lesson + a short article read.
- Several brief listens spread across the day (commute, break, evening).
- An exercise round + a short lesson.
Proposal
Qualify the streak based on cumulative time across all of today's activity sessions in the user's learned language, rather than per-session duration.
Rough sketch:
- On any session update, sum today's
UserListeningSession + UserReadingSession + UserExerciseSession durations for the user (filtered to the relevant language via the _session_language rule already in activity_sessions.py).
- If the sum >=
MIN_STREAK_DAILY_MS (still 120_000, or possibly raised), call update_streak_if_needed.
Scope notes
- The MIN_STREAK_DURATION_MS constant becomes per-day, not per-session.
- One query per session-update is fine (sessions are short and
(user_id, start_time) is indexed) — should not be a measurable cost.
- No frontend change required; this is purely backend qualification logic.
Related
Surfaced while wiring useListeningSession into PastLessons.js (web) so history-replay listening time is recorded. With that in place, the data is now there — but a user who replays for ~90 seconds still won't get streak credit until cumulative-day qualification is implemented.
Problem
The streak qualifies a day as "practiced" only when a single activity session reaches
MIN_STREAK_DURATION_MS = 120_000(2 min). Seezeeguu/api/endpoints/helpers/activity_sessions.py:23-31.This means two 1-minute sessions on the same day do not qualify, even though the user practiced for 2 minutes total. Realistic patterns where this hurts:
Proposal
Qualify the streak based on cumulative time across all of today's activity sessions in the user's learned language, rather than per-session duration.
Rough sketch:
UserListeningSession+UserReadingSession+UserExerciseSessiondurations for the user (filtered to the relevant language via the_session_languagerule already inactivity_sessions.py).MIN_STREAK_DAILY_MS(still 120_000, or possibly raised), callupdate_streak_if_needed.Scope notes
(user_id, start_time)is indexed) — should not be a measurable cost.Related
Surfaced while wiring
useListeningSessionintoPastLessons.js(web) so history-replay listening time is recorded. With that in place, the data is now there — but a user who replays for ~90 seconds still won't get streak credit until cumulative-day qualification is implemented.