# Quiz revamp progress ## Milestone 1 — custom tests and categories Implemented in `affd717` plus the follow-up review-fix commit: - Learner custom-test builder: multiple categories and descendants, exact available counts, 1–200 questions, study/exam modes, unused/incorrect/bookmarked filters, fixed saved membership and optional sharing. - Existing categories retain IDs/assignments; optional hierarchy, cycle guards, breadcrumbs and educator reparenting support added. - Central general-quiz visibility and sharing checks across web, attempts and mobile; ownerless-question revocation is NULL-safe and both Hide and Unshare revoke public access. - Explicit question selection rejects private/course/missing IDs. Peer deletion of private/manual questions is denied. - Web, mobile and expiry use one grading function. Duplicate/out-of-pool submissions are rejected; skips have recorded incorrect outcomes; reviews use selected questions only, and unfinished attempts do not return answer review. - Category UI handles validation arrays, refreshes reparented filters and offers relocation even when the visible question count is zero. Private quiz titles are keyboard-accessible links. - Category migration supports real offline SQL rendering and existing/fresh schemas. ### Verification Initial implementation received two independent read-only reviews (access/correctness and UI/migration). The parent applied the accepted fixes and added behavioral regressions. - Backend: **14 tests passed** inside the exact deployed backend image `sha256:77d9af981537a09396fb5a511f27b4efd00794443823db8eb522beb3aa70a5b9` (Python 3.11 and deployed library versions). Disposable SQLite only; network disabled; no production data. - Frontend: **13 tests passed in four suites** with `NODE_ENV=test npm test`; production build passed with `NODE_ENV=production npm run build`. - PostgreSQL 16: actual migration upgrade, FK enforcement, existing-row/question-assignment preservation, repeated upgrade, downgrade and re-upgrade passed in a disposable network-isolated container. Container/data cleaned up automatically. - Alembic offline SQL: explicit `5f8c1c2a9d40:c82d19e4a601` upgrade and reverse downgrade exercised without mocking inspection. - Changed Python syntax and `git diff --check` passed. - The same regression suite fails against frozen `affd717` as expected: unauthorized revocation/deletion, premature review answers, invalid mobile selections, duplicate scoring (200%) and offline SQL inspection are reproduced. The legacy-Hide test also catches its missing sharing-state response. All tests pass on the fixed code. The first Docker validation attempt failed before tests because a read-only mountpoint was absent; setup was corrected. One frontend regression initially used an ambiguous Create Quiz selector; the modal was labeled and the test scoped to it, then all tests passed. ### Release boundaries This milestone is source work on the feature branch, **not a production deployment or completion of the whole revamp**. Apply migrations explicitly before serving updated code against the existing production DB; startup does not automatically upgrade existing tables. Older tutor-context and question-image delivery authorization gaps identified by review remain a release blocker and have their own tracked privacy task. Already-downloaded offline content cannot be recalled by server revocation. No new AI provider calls or production database/service changes were performed. ## Login-only Turnstile removal User-requested removal covers both `/login` and the landing-page sign-in modal, the shared login client payload, and the backend password-login handler/schema. Registration and contact Turnstile are unchanged; no keys/configuration were removed. Verification: 18 backend tests passed in the exact deployed image, including login with a configured Turnstile secret but no challenge token, incorrect-password rejection, email verification, SSO-only mode, the eleventh-request rate limit and retained registration verification. All 17 frontend tests and the production build passed, including both login entry points with a configured site key and retained registration/contact widgets. The first backend run used reserved `.test` email addresses; only fixtures were corrected to `example.com`, not validation rules. This source change is committed/pushed with the feature work; it has not been deployed to production. ## Milestone 2 — runner and study tools (under verification) Implemented a wide white/blue question layout with category breadcrumbs, numbered answers, provisional study selections, explicit response confirmation, real response-distribution bars, question navigation and Review & Complete. The results screen reviews one question at a time. Full question/explanation text, images, notes, highlighting and tutor access are retained. Added a safe arithmetic calculator (no eval), keyboard shortcuts that do not interfere with text entry/dialogs, native focus-trapping tool dialogs, and educator-managed lab references with required population/specimen/units/source and explicit publication. No clinical reference ranges are fabricated or seeded without verification. Attempt mode is persisted server-side: a query flag cannot reveal active exam answers/statistics, and mismatched attempt/quiz/user IDs are rejected. Legacy attempts without stored mode resume as exam mode rather than exposing answers; their saved answers remain intact. The new `d94a26b8f302` migration must run before deployment. Combined verification after review fixes and login removal: **25 backend tests passed in the deployed image; 53 frontend tests and production build passed.** Actual PostgreSQL mode/lab upgrade, repeated upgrade, downgrade and re-upgrade passed; existing scores were preserved and the real lab ORM defaults/publication/FK were checked. Independent review identified a failed-resume overwrite path, nullable review-setting serialization, and missing Alembic lab-model registration. Fixes add retry-only resume recovery, re-read saved progress for reused attempts, explicit cache failure responses, autosave warnings, blocked navigation when suspension cannot save, nullable/fail-closed course review handling, and model registration verified in a fresh process. New tests cover each case. Follow-up independent review resolved all three findings and found no blocker in their affected paths; see [milestone-2-review.md](quiz-revamp/milestone-2-review.md). Milestone 2 is integrated at source level. Nothing has been deployed; linked articles/cards, AI authoring, discussions, and the existing related-content privacy release gate remain. Browser checks used a loopback-only fixture with synthetic accounts/questions and in-memory data, not production authentication. Desktop layout, provisional/confirmed answers, live fixture response counts, calculator arithmetic, honest empty lab references, and review confirmation were checked. At 390×844 the document width was exactly 390 and no question, option, image or toolbar overflowed; a taller narrow frame captures the full page. A browser-profile reset interrupted the check; re-login restored the saved attempt successfully. Proof images: [desktop](quiz-revamp/desktop-question.png), [study feedback](quiz-revamp/study-feedback.png), [mobile width](quiz-revamp/mobile-question.png). These are synthetic previews, not screenshots of deployed clinical content. ## Next Continue with the Orthobullets-inspired runner/results UI, question navigation and study tools; then article/subsection reading, linked flashcards, educator AI authoring and moderated comments. Complete related-content privacy work and end-to-end desktop/mobile validation before deployment.