Commit Graph
98 Commits
Author SHA1 Message Date
hz 25c2188264 Schedule graphical CCS procedures 2026-08-14 17:54:03 -05:00
hz 325d27eec5 Add graphical CCS orders and finalization 2026-08-14 00:53:21 -05:00
hz 6108011f74 Refresh stale CCS exam attempts 2026-08-10 21:30:43 -05:00
hz 07516784d2 Add graphical CCS physical examination 2026-08-10 03:27:45 -05:00
hz 579e1e9be4 Refine CCS desktop shortcuts 2026-08-10 01:05:06 -05:00
hz 33b55753cb Expand CCS patient history 2026-08-09 23:59:28 -05:00
hz 2c7c5dd387 Refine graphical CCS interview flow 2026-08-06 04:58:15 -05:00
hz 38d62918d4 Resume stale graphical CCS interviews 2026-08-06 03:34:07 -05:00
hz a0dae8e478 Make graphical CCS dialogue choice first 2026-08-06 02:48:44 -05:00
hz 58dd370149 Add graphical duodenal ulcer interview 2026-08-05 23:14:51 -05:00
hz 7709d16018 Show legacy CCS cases in interactive scene 2026-08-05 20:46:55 -05:00
hz af2bbb673d Connect graphical CCS interviews to cases 2026-08-05 20:14:27 -05:00
hz c7f5006cb6 Restore distractor-specific follow-up questions 2026-08-01 18:06:52 -05:00
hz 8c5aa17d89 Add clinical progression ranks and records 2026-08-01 15:17:42 -05:00
hz 300b230c03 Add weekly consistency goals 2026-08-01 04:14:39 -05:00
hz ecd5da9162 Add daily study missions 2026-08-01 04:02:24 -05:00
hz 2bd2628009 Add study session goals and summaries 2026-08-01 02:34:58 -05:00
hz ddc36a8048 Add server-authoritative RZ Coin rewards 2026-08-01 01:28:38 -05:00
hz 8c439c6294 Add question bank mastery paths and gap questions 2026-07-31 23:46:46 -05:00
hz 5488dec2c7 Lock submitted simulation answers 2026-07-30 16:54:12 -05:00
hz 778da32e73 Fix exam simulation score prediction 2026-07-30 16:00:29 -05:00
hz ae6b37eb7d Make simulation block submission idempotent 2026-07-30 15:30:54 -05:00
hz 09502944ec Require production approval for question media 2026-07-30 04:16:18 -05:00
hz 0bd74fcabf Temporarily make slot machine spins free for testing
SpinCost set to 0 so spins don't require RZ Coins - revert to 50
once testing is done (marked with a TODO). The frontend already
reads spin cost from GET /api/credits/spin-config rather than
hardcoding it, so the "Cost per spin" display and the Spin button's
enabled state update automatically.
2026-07-30 03:39:44 -05:00
hz 1860e6ede6 Add an RZ Coin slot machine
Adds a spend-coins-for-a-random-reward mini-game reachable from the
shop. Backend mirrors the store's existing atomic/idempotent purchase
pattern (SpinAsync in CreditStore.cs) with a server-authoritative,
weighted reward roll and a rolling per-user spin-rate guard; odds are
served from GET /api/credits/spin-config so the client never hardcodes
numbers that could drift from the real payout table. The mockup's
"Streak Protector" reward was swapped for a real Exam Simulation Token
since streaks aren't currently a persisted, protectable concept.

Also fixes two latent bugs surfaced while building this:
- credits_service.gd's operation-id builder referenced a nonexistent
  AuthState.user_id (should be .username), throwing on every credit
  action.
- _post() silently no-op'd with no signal when signed out, which
  combined with a GDScript closure gotcha (lambdas capture outer
  locals by value, so reassigning inside one never reached the
  caller) meant a spin attempted while unauthenticated could hang
  forever instead of surfacing an error.
2026-07-30 00:29:49 -05:00
hz da641a8d1d Add Rz Coin utility store 2026-07-29 18:34:54 -05:00
hz c14ac1d65b Require reference ranges for published question labs 2026-07-29 01:28:37 -05:00
hz 845907e825 Show rank tier and ELO alongside RZ points in the coins badge
Adds a server-computed tier/division (Bronze..Diamond, III-I) to the
ratings profile endpoint and surfaces it next to the numeric ELO in the
shared header badge, matching the coin balance display already there.
2026-07-29 00:25:26 -05:00
hz 89dbe3e31a Initialize credit earning ledger arrays 2026-07-28 20:52:20 -05:00
hz dd203b24f9 Allow SUPER accounts to earn Rz Coins 2026-07-28 20:36:15 -05:00
hzandClaude Sonnet 5 6f41906101 Gate Rz Coins on correct-first-try-within-time-limit; match coin-flight animation to it
Credits were previously awarded on any first attempt regardless of
correctness or timing. The award now requires the first-ever attempt
to be correct (record.Attempt.IsCorrect) and submitted before the
adaptive per-question timer expired (new MetTimeLimit request field,
computed client-side from the same elapsed/target comparison that
already drives the visible countdown bar). The coin-flight animation
in question_player.gd now only plays when both conditions are met
(BlockSessionService.submit_core_attempt's existing "mastered" flag
plus met_time_limit), so the effect never promises a coin that isn't
actually earned.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-07-28 20:17:07 -05:00
hz 22b0df7aed Add isolated question completion credits 2026-07-28 18:40:49 -05:00
hzandClaude Sonnet 5 74398133f7 Exclude sample exam simulations from the dashboard's readiness score
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]>
2026-07-26 14:47:07 -05:00
hz 447f080552 Add ready question production promotion 2026-07-26 01:17:55 -05:00
hz 34d283e213 Add rating snapshots, percentile, and exam readiness to the dashboard API
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.
2026-07-26 00:39:11 -05:00
hz 500477b612 Add dashboard performance trends 2026-07-25 22:43:34 -05:00
hz edcc0def5d Fix CCS category order search 2026-07-23 23:14:38 -05:00
hz b9d4687b1b Fix dynamic Elo clamp updates 2026-07-23 23:01:52 -05:00
hz 32c455bba0 Improve dynamic question learning loop 2026-07-23 16:50:53 -05:00
hz fae38d2ded Adapt dynamic question difficulty to learner Elo 2026-07-23 16:18:44 -05:00
hz b1b83dae05 Fix dynamic mastery first-attempt upsert 2026-07-23 15:25:06 -05:00
hz 92c5688b55 Upgrade dynamic questions to authored parity 2026-07-23 14:11:18 -05:00
hz 403944b249 Assign IDs when promoting dynamic blueprints 2026-07-23 13:40:53 -05:00
hz 8390d795e5 Publish dynamic questions during UAT deploy 2026-07-23 13:30:22 -05:00
hz fcbc288a49 Add data-driven dynamic question mode 2026-07-23 12:33:23 -05:00
hz 8e216eac32 Rebuild CCS case workflow 2026-07-23 04:43:02 -05:00
hz d69a1fd0e3 Sync text zoom preference through the account instead of local settings
Local user://settings.cfg meant zoom level didn't follow a student
across devices/browsers. Question bank and CCS text scale now live on
the user's study profile in Mongo (QuestionTextScale/CcsTextScale),
synced through a new PUT /api/profile/me/text-scale endpoint and the
existing preferences GET/cache already used for study preferences.

Both question_player.gd and ccs_service.gd read the synced value at
startup and react to AccountProfileService.profile_changed so a value
pulled down after login (or changed from another session) applies
without a restart. Backend validates the 0.85-1.35 range and updates
only the field(s) provided via a targeted $set, so it can't clobber
the other scale or the unrelated study-profile preferences.
2026-07-23 03:59:02 -05:00
hz c62eff8846 Auto-flag questions with media at write time, not just via one-time sweep
The flag-media-questions CLI command only caught questions that
existed in the DB when it ran once. Any question created, imported,
or edited afterward could add media without ever being flagged for
review, since nothing gated new writes going forward. CreateAsync,
UpdateAsync, and UpsertManyByExternalIdAsync now all run new/updated
questions through ApplyMediaReviewGate, which flags any question that
has media and isn't already flagged.
2026-07-23 03:29:57 -05:00
hz 9f62444a63 Add a review-flag state for questions, independent of publish status
Flagged questions disappear from every student-facing surface (search,
exam simulation sampling, the missed-question review queue, bookmarks,
direct fetch) while staying published - flagging and unpublishing are
now separate, reversible actions with their own audit trail (who
flagged it, when, why). Backend-only for now: SUPER-only flag/unflag/
list endpoints, no client UI. Includes a one-time CLI sweep
(flag-media-questions) to flag every existing question with an image
so they can be reviewed.
2026-07-22 22:42:19 -05:00
hz 7f76ca0fdc Add system (curated) vs. user-uploaded flashcards
System decks/notes are owned by a reserved sentinel user id, reusing
all existing per-user store/index plumbing unchanged. Regular users
see them under a separate "Official Decks" section, can study them
with fully independent per-user FSRS progress (lazily materialized on
first visit), but can never edit or archive them - enforced both in
the client (no Edit/Archive controls) and server-side (ownership guard
on every mutating endpoint). Includes a small idempotent seed command
(`dotnet run -- seed-flashcards`) for testing, since there's no in-app
authoring UI yet.
2026-07-22 15:52:19 -05:00