Progress calculations: mastery, retention, streak #38

Open
opened 2026-09-26 13:58:40 +00:00 by belvedere · 0 comments
Collaborator

Objective: Derive the numbers the user cares about, from the review log.

Files:

  • Create: lib/first_thousand_words/study/progress.ex
  • Create: test/first_thousand_words/study/progress_test.exs

Steps:

  1. Define the lexicon of progress precisely, in one place:
    • new — never reviewed
    • learning — interval < 1 day
    • young — 1 ≤ interval < 21 days
    • mastered — interval ≥ 21 days
  2. Retention: correct answers / total, over a window (7d and all-time).
  3. Streak: consecutive days with ≥1 review, computed in the user's timezone — a
    UTC-based streak will break at the wrong hour for a UK user (Europe/London).
  4. Implement as Ash calculations/aggregates where possible so they compose with filters.

Verify: fixture-driven tests, including a streak spanning a DST boundary.

Refs: plan §5 (Tracking)

**Objective:** Derive the numbers the user cares about, from the review log. **Files:** - Create: `lib/first_thousand_words/study/progress.ex` - Create: `test/first_thousand_words/study/progress_test.exs` **Steps:** 1. Define the lexicon of progress precisely, in one place: - **new** — never reviewed - **learning** — interval < 1 day - **young** — 1 ≤ interval < 21 days - **mastered** — interval ≥ 21 days 2. Retention: correct answers / total, over a window (7d and all-time). 3. Streak: consecutive days with ≥1 review, computed in the user's **timezone** — a UTC-based streak will break at the wrong hour for a UK user (Europe/London). 4. Implement as Ash calculations/aggregates where possible so they compose with filters. **Verify:** fixture-driven tests, including a streak spanning a DST boundary. **Refs:** plan §5 (Tracking)
Sign in to join this conversation.
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
nickkeers/first-thousand-words#38
No description provided.