Skip to content

Tags

What is live

The write schema still declares four tag types — subject, disease, keyword, system — but only three function.

Type Status Examples
subject Live Cardiology, Infectious Disease, Neonatology
disease Live Kawasaki Disease, Pneumonia, Type 1 Diabetes
system Live, but derived Counted transitively through category ancestry, not from a direct link on the question
keyword Retired GET /tags always returns an empty keywords list, whatever is in the table

keyword used to be the route to an organ system. The category tree carries that now, through QuestionCategory.system_id, so the tag type was retired.

subject and disease were retired alongside it and then deliberately restored: the tree mostly says the same thing, but they are still a vocabulary people filter by.

Filtering

Tag filtering is AND — a question must carry every tag asked for. The SQL groups by question and requires the distinct tag count to equal the number asked for.

Category filtering is OR within the set. See Categories.

The filters live together on /question-bank and in the session builder.

How classification is actually run

The README is stale on this

README.md documents an admin button and a POST /api/admin/classify endpoint backed by a Celery task called classify_questions. None of those exist in the current backend. There is no live endpoint and no Celery task that assigns subject, disease or system tags.

Classification today is done by management scripts, run by hand:

docker compose exec backend python -m scripts.classify_unfiled_questions
docker compose exec backend python -m scripts.assign_category_systems
docker compose exec backend python -m scripts.sanitize_tags
docker compose exec backend python -m scripts.convert_tags_to_categories

classify_unfiled_questions embeds the question, retrieves the nearest existing categories, and asks a model to pick one or decline. It never invents a category.

The rollback that does exist

GET  /api/v1/admin/classification-snapshots
POST /api/v1/admin/classification-snapshots/{snapshot_id}/rollback

These list and revert saved classification snapshots, and they work. Nothing in the backend writes those snapshot rows — the offline tooling does.

One task that sounds like it and is not

There is a real Celery task classify_question_difficulty, using the keyword model task. It labels difficulty — easy, medium, hard — not subject or disease tags, and nothing in the application calls it. It would have to be invoked directly.