pdf-quiz-generator/backend/scripts
Daniel 3279e14bb2 refactor: remove the LMS
There will be no courses. What was there: one draft called "jk" with two empty
lessons, and 4,000 lines of code around it — courses, modules, lessons,
enrolments, per-lesson progress, SCORM, BigBlueButton, completion certificates,
three React pages, a router, two models.

Its real cost was everywhere else. Every query that measured practice had to
remember `Quiz.course_id.is_(None)`, and forgetting it in one place would have
silently mixed course attempts into a learner's analytics; the bank predicate
carried a subquery to exclude a course's own questions from every search,
recommendation and share; quiz access had a second, parallel rule about
enrolment. All of that is gone, so the remaining rules say what they mean.

`quizzes.allow_review` goes with it. It was only ever enforced for a course
quiz, so it had become a promise nothing keeps — the public session page was
still offering "no answer review" about sessions that review fine.

The fixtures' question 5 lived in a course quiz and stood for "a question that
exists but is not in your bank". There is no such thing now — a question is in
the bank unless it is deleted — so the counts it kept out of the numbers are
back in, and the tests that turned on it now turn on deletion or on the
attempt that actually holds a question.

Files the LMS uploaded stay on disk and stay protected: LEGACY_LMS_PREFIXES in
app/utils/upload_access.py is what keeps them unreachable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TqXevQJhxFrM7jJg82cgZN
2026-09-12 23:27:51 +02:00
..
abp-2024-outline.json feat: exams are a group you can build, with the board's own blueprint 2026-09-11 20:27:48 +02:00
article_pipeline.py feat: a session prepared for you, and a model that can see when the one on the job cannot 2026-09-12 15:46:04 +02:00
assign_category_systems.py feat: an organ system is a fact about a topic, not about a keyword 2026-09-12 04:32:25 +02:00
backfill_question_figures.py feat: AMBOSS exam chrome, review as a study session, and no silent submissions 2026-09-12 07:37:58 +02:00
bind_exam_tags.py
classify_unfiled_questions.py
convert_jpeg2000_figures.py fix: WebP figures, the openai SDK removed, and a voice a site can add to 2026-09-12 17:13:05 +02:00
convert_tags_to_categories.py
fix_blueprint_collisions.py fix: one topic per idea, and one ABP domain per topic 2026-09-12 07:42:00 +02:00
fix_lab_formatting.py
generate_articles.py
index_question_images.py fix: choosing is answering; figures say only what an educator wrote 2026-09-12 00:19:35 +02:00
link_articles.py feat: settings as places with addresses; repair nested cross-references 2026-09-11 12:46:13 +02:00
mdm_pass.py fix: 'No therapy is required' is an answer, not a placeholder 2026-09-11 13:58:02 +02:00
merge_duplicate_categories.py feat: AMBOSS exam chrome, review as a study session, and no silent submissions 2026-09-12 07:37:58 +02:00
merge_duplicate_conditions.py
migrate_uploads_to_s3.py
nest_symptoms_by_system.py
nest_systems.py
number_board_reviews.py feat: session analysis after a quiz, and a merged TODO for the rest 2026-09-11 03:07:05 +02:00
parent_keywords_to_systems.py feat: an organ system is a fact about a topic, not about a keyword 2026-09-12 04:32:25 +02:00
promote_primary_categories.py
prose_pass.py fix: the imperative detector only ever saw sentence starts 2026-09-11 13:16:05 +02:00
purge_unused_figures.py
reindex_article_search.py feat: search that looks at what an article says 2026-09-12 15:57:42 +02:00
rename_study_plans.py
reorganize_topics.py fix: one topic per idea, and one ABP domain per topic 2026-09-12 07:42:00 +02:00
restore_subject_disease_tags.py fix: put the disciplines and diseases back, and order Performance as shown 2026-09-12 05:39:22 +02:00
retire_question_tags.py feat: retire the tags, and stop settings from hiding from the page that 2026-09-12 05:06:58 +02:00
retitle_figures.py feat: cross-link the articles, and strip what the analysis page replaced 2026-09-11 03:44:44 +02:00
rewrite_catalogue_summaries.py feat: a session prepared for you, and a model that can see when the one on the job cannot 2026-09-12 15:46:04 +02:00
rollback_tag_category_conversion.py
sanitize_categories.py
sanitize_tags.py
seed_abp_blueprint.py feat: exams are a group you can build, with the board's own blueprint 2026-09-11 20:27:48 +02:00
seed_illustrations.py
seed_lab_references.py
seed_sample_content.py refactor: remove the LMS 2026-09-12 23:27:51 +02:00
seed_showcase_articles.py feat: a session prepared for you, and a model that can see when the one on the job cannot 2026-09-12 15:46:04 +02:00
seed_study_plans.py feat: study-plan blocks as modules, sessions that know their block 2026-09-11 04:31:21 +02:00
settle_tied_primaries.py content: every article has a high-yield view, and three ties that were not ties 2026-09-12 18:16:59 +02:00
settle_topic_questions.py fix: the ear to ENT, gynecology to its own branch, and Surgery back into medicine 2026-09-12 08:06:59 +02:00
tag_source_quizzes.py
triage_question_images.py fix: WebP figures, the openai SDK removed, and a voice a site can add to 2026-09-12 17:13:05 +02:00
write_missing_views.py content: every article has a high-yield view, and three ties that were not ties 2026-09-12 18:16:59 +02:00