The SUPER-role "preview results" QA tooling seeds a completed
ExamSimulation with scripted (not real) answers, flagged IsSample.
The dashboard's readiness lookup picked whichever completed
simulation was most recent regardless of that flag, so running the
QA preview on an account could override its real Exam Readiness card
with a synthetic pass probability. Recent-activity/weekly-activity
queries got the same exclusion since they read from the same
collection for the same reason.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Backend half of the dashboard stat-card redesign. Three new data
points the old DashboardResponse had no way to compute:
- Week-over-week rating deltas: UserRating/CcsUserRating only ever
stored the current Elo (mutated in place, UpdatedUtc just means
"last touched"), so there was no way to know what a rating was 7
days ago. Added UserRatingSnapshot (new collection, unique on
UserId+DateUtc) and UserRatingSnapshotService, a BackgroundService
following AnswerStatisticsMaintenanceService's exact shape (a
PeriodicTimer plus a Mongo lease so replicas behind the HPA don't
race), writing one snapshot per user per day. No historical
backfill - deltas are simply null for a user's first ~7 days after
this ships, which the DTO represents honestly via nullable ints
rather than a fake "+0".
- Percentile rank: DashboardStore now counts how many users have a
higher OverallElo/Elo than the current user out of the total.
- Exam Readiness + projected pass rate: reuses the existing, tested
IRT-based ExamSimulationScore.PassProbability (a real normal-CDF
estimate of scoring >=200, computed in ExamSimulationScoring.Calculate)
rather than inventing a new prediction model. DashboardStore pulls
the latest completed simulation's score directly and maps
PassProbability to a High/Medium/Low label via tunable thresholds.
- Average Score's "+6% vs last 100" needed no new data source at all -
just one more slice (Skip(100).Take(100)) over the QuestionAttempts
already loaded for FirstAttemptAccuracy.
Added DashboardStore.Percentile/ReadinessLabel as pure static helpers
(matching the existing Percentage/CalculateCurrentStreak pattern) and
unit tests for both. Full backend suite: 165 passed, 0 failed.
Adds a full flashcards system: FSRS-based scheduling, cloze/basic
card types, CSV import/export, media storage, and study UI, wired
into navigation and the dashboard alongside existing question flows.