feat: round-trip QTI AssessmentItem raw_data through save and sync#6028
Merged
rtibbles merged 3 commits intoJul 3, 2026
Conversation
rtibbles
requested changes
Jul 3, 2026
rtibbles
left a comment
Member
There was a problem hiding this comment.
Need to do the QTI constant properly - upgrade to le-utils 0.2.18.
Ships the QTI question type constant so AssessmentItem code can reference exercises.QTI instead of a hardcoded string.
Store the editor's authored QTI XML on AssessmentItem (type='QTI', full item XML in raw_data) and round-trip it byte-for-byte through the save and sync API paths. - Persist raw_data verbatim, bypassing legacy answers/hints JSON coercion for QTI items - Validate raw_data against the QTI 3.0 schema on save, rejecting invalid items through the sync error channel - Extract src/srcset/href/data file references from QTI XML into the existing File claim/create/delete flow Fixes learningequality#5999
caa1817 to
397f1f7
Compare
rtibbles
requested changes
Jul 3, 2026
rtibbles
left a comment
Member
There was a problem hiding this comment.
Looking good - just one final thought about strengthening the validation - assessments have two paths, the QTI + raw_data path, or the other.
QTI items must only edit raw_data; non-QTI items must not edit raw_data. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends
AssessmentItemto store and round-trip an editor-authored QTI item's full XML inraw_data(type='QTI'), rather than the structuredquestion/answers/hintsfields legacy types use.QTIas a validAssessmentItem.typeraw_dataverbatim (no whitespace trimming) and skips the legacyanswers/hintsJSON-shape coercion for QTI itemsraw_dataagainst the QTI 3.0 schema during sync save, rejecting invalid XML per-item through the existing sync error channelsrc/srcset/href/datachecksum references from the QTI XML and wires them into the existingset_filesclaim/create/delete flow (mirrors the markdown-scan path legacy types already use)question/answers/hints, and a non-QTI item cannot editraw_dataScoped to the sync API save path only, per the issue — ricecooker/internal API and QTI export/publish are unaffected.
References
Fixes #5999
Related: #5970 (QTI editor), #4877 (existing type validation)
Reviewer guidance
contentcuration/contentcuration/viewsets/assessmentitem.py:validate()raises from withinis_valid()(notcreate()/update()) specifically so a QTI schema error attributes to one item in the sync error channel instead of tripping the batch's broadexcept Exception— worth confirming that reasoning holdsget_filenames_from_qti_itemparsesraw_datawith the QTI validator's existingsecure_parser()(XXE/entity-expansion hardened) — reused rather than re-implementedvalidate()now also rejects cross-type field edits (QTI item touchingquestion/answers/hints, or non-QTI item touchingraw_data), per review feedback asking to close that gaptest_qti_assessmentitem_full_round_tripcovers byte-for-byte round-trip on create/update plus file extraction/removalFileThumbnailTestCasefailures onunstableare unrelated to this change (reproduced against unmodifiedunstable)AI usage
Implemented with Claude Code from a maintainer-approved plan, using TDD per task. Wiring up schema validation broke an earlier whitespace round-trip test — the test padded
raw_datawith leading whitespace, which placed content before the XML declaration and is itself invalid XML. Fixed the test to pad trailing whitespace only, which still exercisestrim_whitespace=Falsewithout producing invalid input.@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Status: 🟡 Waiting for feedback · updated 2026-07-03 16:16 UTC