Skip to content

[QTI] Convert legacy assessment items to QTI on the fly to avoid frontend backward compatibility handling #6003

Description

@rtibbles

Overview

Build the reusable legacy→QTI conversion (structured single/multiple selection, input, true/false → <qti-assessment-item> XML) and serve it through the API layer (dual-read) so the frontend only ever receives QTI. The one-time global backfill is #11.

Complexity: High
Target branch: unstable

Context

  • Legacy items store structured question/answers with legacy types; the existing pydantic models already generate QTI for choice + text-entry — the legacy-expressible set.
  • A uniform QTI model removes publish-time format branching and the editor's legacy-edit path ([QTI] Support legacy assessment item types in the QTI Editor #5980 becomes unnecessary).
  • The transitional conversion lives in the API layer (dual-read), not the database — no schema change.

The Change

  • Provide a reusable legacy→QTI conversion producing <qti-assessment-item> XML from structured items.
  • During a short transition window, the API endpoint converts legacy items to QTI on read, so the frontend only ever receives QTI.
  • Leave perseus_question items as raw Perseus — out of scope here; handled by mixed publishing (Browserify #8).

Acceptance Criteria

  • A reusable conversion produces <qti-assessment-item> XML from each supported legacy type (single/multiple selection, input, true_false)
  • The conversion is lossless: prompt, choices/answers, correctness, hints, and media survive
  • Each converted item validates against the QTI 3.0 XSD (Ant's backend plus setting up front end files #2)
  • During the transition window the API endpoint returns QTI for a still-legacy row (dual-read)
  • Items that fail conversion are surfaced, not silently dropped
  • Tests cover conversion per legacy type and the API dual-read

References

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for Task.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions