You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Land assessment items uploaded through the internal/ricecooker API uniformly as QTI: store editor-shaped and arbitrary QTI directly, convert uploaded legacy/structured items to QTI via the #6003 machinery, validate against the schema, and map referenced media.
Complexity: High Target branch: unstable
Context
create_exercises (contentcuration/contentcuration/views/internal.py) builds items from structured fields and validates only assessment_id uniqueness; type and content go unchecked until publish.
Unwrap any Perseus custom interaction (data-type='perseus'): read its referenced data-perseus-path payload from the upload and restore it as a raw perseus_question, rather than storing the custom interaction.
Map media/file dependencies so they are present at publish.
Acceptance Criteria
create_exercises delegates to the AssessmentItem serializer/machinery; duplicated internal-endpoint and nodes logic is removed
The API accepts and persists QTI items (raw_data XML + media)
Uploaded legacy/structured items are converted to QTI on ingest; raw Perseus is preserved as-is
A Perseus custom interaction is unwrapped by reading its data-perseus-path payload and restoring the raw perseus_question
Referenced media is mapped and present at publish
Tests cover QTI upload (editor-shaped + arbitrary), legacy-converted-on-ingest, an invalid upload, and media mapping
References
contentcuration/contentcuration/views/internal.py
contentcuration/contentcuration/utils/nodes.py
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
Land assessment items uploaded through the internal/ricecooker API uniformly as QTI: store editor-shaped and arbitrary QTI directly, convert uploaded legacy/structured items to QTI via the #6003 machinery, validate against the schema, and map referenced media.
Complexity: High
Target branch: unstable
Context
create_exercises(contentcuration/contentcuration/views/internal.py) builds items from structured fields and validates only assessment_id uniqueness; type and content go unchecked until publish.utils/nodes.pyduplicate logic that theAssessmentItemViewSet/serializer ([QTI] Allow API endpoint to handle AssessmentItem.raw_data to store QTI data #5999) already owns; delegating to it cleans up that tech debt.raw_dataXML and reference media mapped viamap_files_to_assessment_item(utils/nodes.py).data-type='perseus') is a publish-time-only wrapper ([QTI] Publish mixed Perseus + QTI exercises as one QTI package #6006); if our own published QTI is re-imported, it must be unwrapped back to a rawperseus_question.The Change
create_exercisesto delegate to theAssessmentItemViewSet/serializer machinery ([QTI] Allow API endpoint to handle AssessmentItem.raw_data to store QTI data #5999), removing duplicated logic in the internal endpoint andnodesutils.QTIitems (raw_data XML + media) directly; validate each against the schema ([QTI] QTI 3.0 schema XML validation utilities #6005), rejecting non-compliant items with actionable errors.data-type='perseus'): read its referenceddata-perseus-pathpayload from the upload and restore it as a rawperseus_question, rather than storing the custom interaction.Acceptance Criteria
create_exercisesdelegates to the AssessmentItem serializer/machinery; duplicated internal-endpoint andnodeslogic is removeddata-perseus-pathpayload and restoring the rawperseus_questionReferences
contentcuration/contentcuration/views/internal.pycontentcuration/contentcuration/utils/nodes.pyAI usage