Eliminate timer races and stale callbacks across game session lifecycle
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 6
- Avg merge
- 3d 12h
- Merged PRs (30d)
- 7
Description
## Problem
Answer processing spans unmanaged timeouts in both `QuestionCard` and the game modes. A challenge can expire during the 600 ms answer delay, yet the callback captured before expiry can still record the result and grant rewards. Rapid navigation/restart can also leave 400/800 ms callbacks alive, allowing stale sessions to mutate the new session or update an unmounted component.
## Proposed scope
- Model question/session lifecycle explicitly (`idle`, `answering`, `feedback`, `complete`).
- Make result recording idempotent per question/session.
- Cancel all pending timers on question change, restart, expiry, and unmount.
- At commit time, verify the current session token and deadline rather than relying on stale React closures.
- Decide whether an answer selected before zero but committed after zero counts, and encode that rule consistently.
## Acceptance criteria
- No score, reward, progress, badge, speech, or question mutation occurs after session completion/unmount.
- One question can produce at most one result even under double clicks and timer races.
- Restarted sessions cannot receive callbacks from the previous session.
- The score screen totals remain stable after appearing.
- Fake-timer tests cover expiry during feedback, restart during feedback, navigation, and rapid input.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.