CSC/ECE 517 Spring 2026 - E2619. Student Quizzes Frontend

From Expertiza_Wiki
Revision as of 14:51, 24 April 2026 by Atmai (talk | contribs)
Jump to navigation Jump to search

E2619: Student Quizzes — Design Document

Introduction

Expertiza is an educational web application collaboratively developed and maintained by students and faculty at NCSU. As an open-source project built on the Ruby on Rails platform, its code is accessible on GitHub. The platform enables students to provide peer reviews and refine their work based on feedback.

This design document describes the implementation of the E2619 Student Quizzes project, covering both the frontend (React/TypeScript) and backend (Ruby on Rails API). The project builds on the E2607 questionnaire rendering code and extends it with quiz-specific capabilities: directing students to quizzes/reviews, scoring quiz responses, specifying correct answers, and handling fill-in-the-blank questions.

Project Overview

Quizzes in Expertiza are designed to ensure that reviewers comprehend the material they are evaluating. When an assignment includes quizzes (require_quiz = true), submitting teams create quizzes based on their submissions. Reviewers must complete the quizzes before reviewing to demonstrate their understanding. If a reviewer performs poorly, their review can be discounted to maintain quality.

Prior State of the Codebase

The existing implementation provided:

  • Backend: Models for QuizQuestionnaire, QuizItem,
 QuizQuestionChoice, QuizResponseMap, Response,
 and Answer. Basic CRUD for questionnaires and questions existed.
 Response#aggregate_questionnaire_score calculated scores using
 answer * weight only, with no correctness check.
  • Frontend: Questionnaire editor (create/edit/delete), student task list, review
 tableau display, and assignment configuration. The questionnaire editor supported the
 "Quiz" type but had no UI to specify correct answers for quiz items.

Gaps Addressed

Area Gap Status
Student Task View No mechanism to direct a student to a quiz, a review, or both based on require_quiz ✅ Implemented
Quiz Scoring aggregate_questionnaire_score did not check correctness ✅ Implemented
Correct Answer Specification No UI to mark correct answers for quiz items ✅ Implemented
Fill-in-the-Blank (TextField) No correct answer support for text questions ✅ Implemented (single answer, case-insensitive match)
Quiz Taking Interface No student-facing page to take a quiz ✅ Implemented
 (reuses existing review form in quiz mode)
Quiz Response Map Creation No endpoint to create a QuizResponseMap for a student before taking a quiz ✅ Implemented via
 POST /quiz_response_maps

Design

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                     Frontend (React/TS)                     │
│                                                             │
│  AssignedReviews ──→ [Take Quiz] ──→ TeammateReview         │
│       │               (quiz mode)        │                  │
│       │                                  └──→ [redirect]    │
│       └──→ [Start/Open Review] ──→ TeammateReview           │
│                                     (review mode)           │
│  QuestionnaireEditor ──→ correct_answer fields per type     │
└──────────────────────────┬──────────────────────────────────┘
                           │ REST API
┌──────────────────────────┴──────────────────────────────────┐
│                     Backend (Rails API)                     │
│                                                             │
│  QuizResponseMapsController  (POST /quiz_response_maps)     │
│  ResponsesController         (create / update / submit)     │
│  ResponseMapsController      (index — filters quiz maps)    │
│  Response model              (aggregate_questionnaire_score) │
│  StudentTask model           (quiz gateway fields)          │
└─────────────────────────────────────────────────────────────┘

Implemented Features

1) Student Task View — Quiz/Review Gateway

The StudentTask model was extended with four fields computed per participant:

  • require_quiz — whether the assignment requires a quiz
  • has_quiz_questionnaire — whether a Quiz-type questionnaire is assigned
  • quiz_questionnaire_id — the id of that questionnaire
  • quiz_taken — true only when a submitted Response exists
 against the student's QuizResponseMap

The frontend AssignedReviews component uses these fields to gate each review row. If require_quiz && has_quiz_questionnaire && !quiz_taken, a yellow "Take Quiz" button is shown instead of the review button.

2) Quiz Gateway Flow

When a student clicks "Take Quiz":

  1. The frontend calls POST /quiz_response_maps with the assignment id and
 user id.
  1. The backend finds (or creates) a QuizResponseMap where
 reviewer_id == reviewee_id (self-referential — the student quizzes
 themselves) and reviewed_object_id is the quiz questionnaire id.
  1. The frontend navigates to the existing TeammateReview page with
 questionnaire_type=Quiz and a redirect_after parameter
 encoding the review URL.
  1. After the student submits the quiz, the page shows the score and automatically
 redirects to the actual review after 1.2 seconds.

Quiz maps are distinguished from review maps by the invariant reviewer_id == reviewee_id. No STI type column is needed.

3) Quiz Scoring

Response#aggregate_questionnaire_score now detects quiz responses by checking map.reviewer_id == map.reviewee_id.

For quiz item types whose student answer is stored in the comments column (because the numeric answer column is unused for text/choice items):

question_type Student answer location Scoring method
TextField answers.comments Case-insensitive exact match
 vs item.correct_answer → 1 or 0 × weight
MultipleChoiceRadio answers.comments Case-insensitive
 exact match vs item.correct_answer → 1 or 0 × weight
MultipleChoiceCheckbox answers.comments Case-insensitive
 exact match vs item.correct_answer → 1 or 0 × weight
Checkbox / Scale answers.answer (integer)
 answer * weight (unchanged)

The final score is returned in the PATCH /responses/:id/submit response body as total_score and displayed to the student before the redirect.

4) Correct Answer Specification (Frontend)

The QuestionnaireItemsFieldArray component renders a "Correct answer" row for every item when the questionnaire type is "Quiz":

  • Checkbox — a checkbox (is correct / is not correct)
  • Scale — a numeric input bounded to the item's weight range
  • Multiple choice / Multiple choice checkbox — a dropdown pre-populated from the
 item's alternatives
  • Text field — a free-text input (case-insensitive match at scoring time)

The correct_answer string column was added to the items table and is persisted through QuestionnairesController and exposed in Item#as_json only for quiz items.

5) Review Map Filtering

ResponseMapsController#index was updated to skip quiz maps using a two-layer guard:

  1. next if map.reviewer_id == map.reviewee_id — reliably excludes quiz maps
  regardless of id coincidences between questionnaire ids and assignment ids.
  1. next unless assignment — belt-and-suspenders fallback.

UML Design