Overview
Build the reusable legacy→QTI conversion — structured single/multiple selection, input, true/false → <qti-assessment-item> XML. This is the pure conversion utility; wiring it into the API endpoint (dual-read) is #6030, and the one-time global backfill is #6007.
Complexity: Medium
Target branch: unstable
Context
The Change
- Provide a reusable legacy→QTI conversion producing
<qti-assessment-item> XML from a structured item (single/multiple selection, input, true_false).
- Make it lossless: prompt, choices/answers, correctness, hints, and media survive.
- Leave
perseus_question items untouched — out of scope here.
- Surface items that fail conversion, rather than silently dropping them.
Acceptance Criteria
Out of scope
- Hint conversion, this will be added in follow up
AI usage
Architecture decided with the maintainer across an iterative session: blanket QTI type with the item XML in raw_data; XSD-authoritative validation across all sources; a legacy→QTI global migration with an API-layer dual-read; ricecooker upload delegating to the AssessmentItem serializer; and a Perseus custom-interaction contract confirmed against the QTI 3.0 specification. Claude mapped the existing publish/validation/ricecooker code, proposed the breakdown, and drafted each issue; the maintainer steered every decision and reviewed throughout.
Overview
Build the reusable legacy→QTI conversion — structured single/multiple selection, input, true/false →
<qti-assessment-item>XML. This is the pure conversion utility; wiring it into the API endpoint (dual-read) is #6030, and the one-time global backfill is #6007.Complexity: Medium
Target branch: unstable
Context
question/answerswith legacy types; the existing pydantic models already generate QTI for choice + text-entry — the legacy-expressible set.The Change
<qti-assessment-item>XML from a structured item (single/multiple selection, input, true_false).perseus_questionitems untouched — out of scope here.Acceptance Criteria
<qti-assessment-item>XML from each supported legacy type (single/multiple selection, input, true_false)Out of scope
AI usage