Owner Nikunj

Question Title PRD V1.2

Question Title PRD V1.2

Functional Requirements for Question Title

  1. An MCQ’s question is its title. The title can be in one of three formats (title_format):

    • TEXT_MCQ — plain text.
    • IMAGE_MCQ — plain-text title + one image.
    • RICH_MCQ — rich content (PlateJS).
  2. Editor adds the title per the chosen format:

    • TEXT_MCQ — types plain text.
    • IMAGE_MCQ — types plain text and adds one image via ImageId (from the Image Bank). One image; the image is what makes it an IMAGE title.
    • RICH_MCQ — rich content (formatting, image).
  3. For RICH_MCQ, the system derives a plain-text title from the rich content.

  4. title is always plain text and always present — it is what is displayed in listing.

  5. Client rendering in MCQ Screen:

    • TEXT_MCQ — the title text.
    • IMAGE_MCQ — the title text with the image rendered inline below it.
    • RICH_MCQ — the rich content.
  6. Client rendering in Listing Screen:

    • the title text — in every format.

Technical Details (as built)

Implemented in PR #737 (feature/mcq-image-format-thumbnails). Design spec: keystone/docs/superpowers/specs/2026-06-02-mcq-question-format-thumbnails-design.md.

Naming: PRD vs code

The codebase keeps the existing field names — there is no title rename. PRD terms map to code as:

PRD termCode field
titlequestion
title_formatquestion_format (QuestionContentFormatEnum)
plain-text title (listing)question_preview (existing, auto-derived)

Enum (QuestionContentFormatEnum, int-valued, wire format = 1/2/3)

  • TEXT_MCQ = 1 (renamed from SIMPLE_MCQ)
  • RICH_MCQ = 2 (renamed from ADVANCED_MCQ)
  • IMAGE_MCQ = 3 (new)

Rename is key-only; values unchanged → no data migration, no API payload change.

thumbnails field

  • thumbnails: List[str] on MCQ db + projection models — holds image-bank short_uids (raw passthrough on read; no hydration into image objects).
  • Capped at MAX_MCQ_THUMBNAILS = 1 (list kept for future multi-image).

Validation

RuleEnforced atError code
len(thumbnails) ≤ 1, no duplicatesdb_model field_validator + av1 request schemaINVALID_PARAMETERS
thumbnails non-empty ⇒ question_format == IMAGE_MCQ (post-update state)av1 schema + db_model model_validator + serviceMCQ_INVALID_DATA
every short_uid live (is_deleted=False) in same course_idservice via image_bank_repo.get_by_short_uids (one batched query)ENTITY_NOT_FOUND

Surface & semantics

  • Write path = av1 (admin) only: POST create, PATCH update_by_id. v1/v2 are GET-only for MCQ.
  • Update semantics: thumbnails=None → unchanged; thumbnails=[] → cleared. On PATCH, format↔thumbnails rule is re-checked against the merged post-update state (flipping away from IMAGE_MCQ while thumbnails remain set → rejected).
  • question_preview derivation: TEXT_MCQ + IMAGE_MCQ use the plain-text branch; RICH_MCQ parses PlateJS.
  • IMAGE_MCQ allows 0-or-1 thumbnail at create (image may be added later via update).
  • No Typesense changes (MCQ has no search model).