feat: deduplicate markLessonComplete with 500ms guard window#746
Merged
RUKAYAT-CODER merged 1 commit intoJun 30, 2026
Conversation
- Add module-level completionInProgress Set to block duplicate calls within a 500ms window (e.g. video-end + manual skip firing together) - Optimistic state update fires on first call; subsequent calls within the window return early without mutating state or triggering an API call - Add _completionTimers Map (exported) for clean timer teardown in tests - Add 6 unit tests covering all acceptance criteria: - Two rapid calls result in a single state mutation - Guard clears after 500ms so a third call succeeds normally - overallProgress increments exactly once per burst - Guard is scoped per lessonId and per courseId independently Fixes duplicate completion records and double-incremented progress counters when multiple triggers fire for the same lesson.
|
@mrteeednut007-dotcom Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Contributor
|
Thank you for contributing to the project. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deduplicate markLessonComplete with 500 ms guard window
Problem
In the video player, lesson completion fires from two sources — video end and manual skip. When
both triggers fire within milliseconds of each other (e.g. a user skips a short lesson right as
it ends), markLessonComplete was called twice in rapid succession. This caused:
Solution
Added a module-level completionInProgress Set that acts as a per-lesson deduplication guard:
normally and the key is added to the set
API call
blocked by each other
Changes
guard logic at the top of markLessonComplete
criteria
Tests
All 11 tests pass (npm test):
┌──────────────────────────────────────┬────────┐
│ Test │ Covers │
├────────────────────────────────────────────────┼─────────────────────────────┤
│ Second call within 500 ms is ignored │ AC1 — single state mutation │
├────────────────────────────────────────────────┼─────────────────────────────┤
│ Two rapid calls → 1 mutation (state assertion) │ AC1 — no double update │
├────────────────────────────────────────────────┼─────────────────────────────┤
│ Call after 500 ms proceeds normally │ AC2 — third call works │
├────────────────────────────────────────────────┼─────────────────────────────┤
│ overallProgress increments exactly once │ AC3 — no double increment │
├────────────────────────────────────────────────┼─────────────────────────────┤
│ Guard is per lessonId │ Isolation │
├────────────────────────────────────────────────┼─────────────────────────────┤
│ Guard is per courseId │ Isolation │
└────────────────────────────────────────────────┴─────────────────────────────┘
close #628