DeutschLernen/docs/features/quiz-system.md
Lasse Rune Hansen 76e8af4987 Add complete solution: documentation, frontend, and project files
- Add comprehensive documentation in docs/ (architecture, features, roadmap)
- Add german-app-frontend with Vite, TypeScript, ESLint configuration
- Add AGENTS.md and .gitignore

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-05-31 18:20:53 +02:00

16 KiB

Feature: Quiz System

Status: Planned
Priority: High
Complexity: High
Estimate: 6-10 hours
Assignee: -
Created: May 31, 2025
Target Completion: -
PR: -
Related Features: Infrastructure Setup, Lesson Management, User Authentication, AI Services (TTS)


📌 Overview

Purpose

Implement a comprehensive quiz system that tests users' understanding of lesson material through various question types, with automatic scoring and progress tracking.

User Story

As a learner, I want to take quizzes after each lesson to test my understanding and receive immediate feedback on my performance.

Acceptance Criteria

  • Each lesson has an associated quiz
  • Quiz contains 10-15 questions of various types
  • Question types: Multiple Choice, Fill-in-the-Blank, Listening Comprehension, Matching
  • Static difficulty (same questions for all users)
  • 80% passing score required to complete lesson
  • Unlimited retakes allowed
  • Score is recorded in UserProgress table
  • Quiz results show which questions were correct/incorrect

📋 Requirements

Functional Requirements

ID Requirement Priority
FR-001 Create/Read/Update/Delete quizzes (Admin) High
FR-002 Associate quizzes with lessons High
FR-003 Support multiple question types High
FR-004 Support MCQ questions High
FR-005 Support fill-in-the-blank questions High
FR-006 Support listening comprehension questions High
FR-007 Support matching questions High
FR-008 Calculate quiz score and passing status High
FR-009 Record quiz attempts in UserProgress High
FR-010 Return detailed results with correct/incorrect answers Medium
FR-011 Allow unlimited retakes Medium
FR-012 Configurable passing score (default 80%) Medium

Non-Functional Requirements

  • Performance: Quiz loading < 300ms
  • Performance: Quiz submission < 500ms
  • Security: Only authorized admins can create/edit quizzes
  • Data Integrity: Quiz-question relationships must be maintained

🏗️ Technical Design

Components Involved

  • Backend: QuizzesController, QuizService, QuestionService
  • Database: Quizzes, Questions tables
  • Models: Quiz, Question, QuizDto, QuestionDto, AnswerDto, QuizResult
  • External: Coqui TTS (for listening questions audio)
  • Frontend: QuizPage, QuizTab, McqQuestion, FillInBlank, ListeningQuestion, MatchingQuestion components

Data Flow

1. User completes lesson activities
2. User navigates to quiz for the lesson
3. Backend retrieves quiz and questions for the lesson
4. Frontend displays quiz to user
5. User answers all questions
6. Frontend sends answers to backend
7. Backend scores quiz and determines pass/fail
8. Backend updates UserProgress with score and completion status
9. Backend returns detailed results to frontend
10. Frontend displays results with feedback

API Endpoints

Endpoint Method Description Auth Required
/api/quizzes GET List all quizzes Yes
/api/quizzes/{id} GET Get quiz with questions Yes
/api/lessons/{lessonId}/quiz GET Get quiz for a specific lesson Yes
/api/quizzes POST Create new quiz (Admin) Yes
/api/quizzes/{id} PUT Update quiz (Admin) Yes
/api/quizzes/{id} DELETE Delete quiz (Admin) Yes
/api/quizzes/{quizId}/questions GET List questions for a quiz Yes
/api/questions POST Add question to quiz (Admin) Yes
/api/questions/{id} PUT Update question (Admin) Yes
/api/questions/{id} DELETE Delete question (Admin) Yes
/api/quizzes/{quizId}/submit POST Submit quiz answers Yes
/api/quizzes/{quizId}/results GET Get quiz results history Yes

Database Schema (from application-plan.md)

-- Quizzes table
CREATE TABLE Quizzes (
    Id SERIAL PRIMARY KEY,
    LessonId INT REFERENCES Lessons(Id) ON DELETE CASCADE,
    PassingScore INT DEFAULT 80
);

-- Questions table
CREATE TABLE Questions (
    Id SERIAL PRIMARY KEY,
    QuizId INT REFERENCES Quizzes(Id) ON DELETE CASCADE,
    Type VARCHAR(20) NOT NULL CHECK (Type IN ('mcq', 'fill_in', 'listening', 'matching')),
    Content TEXT NOT NULL,
    CorrectAnswer TEXT NOT NULL,
    AudioUrl VARCHAR(255),
    Options TEXT[],  -- For MCQ: ['option1', 'option2']
    Points INT DEFAULT 1
);

Question Types

1. Multiple Choice (mcq)

{
    Type: "mcq",
    Content: "What is the article for 'Buch'?",
    CorrectAnswer: "das",
    Options: ["der", "die", "das"],
    Points: 1
}

2. Fill-in-the-Blank (fill_in)

{
    Type: "fill_in",
    Content: "Anna _____ um 7 Uhr auf.",
    CorrectAnswer: "steht",
    Options: null,
    Points: 1
}

3. Listening Comprehension (listening)

{
    Type: "listening",
    Content: "What did you hear?",
    CorrectAnswer: "This is a book.",
    AudioUrl: "/audio/quiz/1.wav",
    Options: ["This is a book.", "This is a cat."],
    Points: 2  // More points for harder questions
}

4. Matching (matching)

{
    Type: "matching",
    Content: "Match the word to its article",
    CorrectAnswer: "der",  // For "Buch" in this case
    Options: ["Buch", "Frau", "Kind"],  // Words to match
    Points: 1
}
// Note: Matching questions may need special handling
// Alternative: Store as JSON with pairs

🚀 Implementation Plan

Phase 1: Database & Models (2-3 hours)

  • Create Quiz entity
  • Create Question entity
  • Create QuizDto, QuestionDto, AnswerDto
  • Create QuizResult model
  • Create IQuizRepository interface
  • Create IQuestionRepository interface
  • Create repository implementations
  • Create migrations for Quizzes and Questions tables

Phase 2: Backend Services (2-3 hours)

  • Create QuizService with CRUD operations
  • Create QuestionService with CRUD operations
  • Create QuizSubmissionService for handling answers
  • Implement scoring logic
  • Implement pass/fail determination
  • Update UserProgress on quiz completion
  • Create mapping between entities and DTOs

Phase 3: API Controllers (2 hours)

  • Create QuizzesController
  • Create QuestionsController
  • Implement quiz submission endpoint
  • Implement results endpoint
  • Add authorization (Admin for write operations)
  • Add validation for quiz data

Phase 4: Question Type Implementation (2 hours)

  • Implement MCQ question handling
  • Implement fill-in-the-blank question handling
  • Implement listening comprehension with audio
  • Implement matching question handling
  • Add audio generation for listening questions

Phase 5: Frontend Integration (2 hours)

  • Create QuizPage component
  • Create QuizTab component
  • Create McqQuestion component
  • Create FillInBlank component
  • Create ListeningQuestion component
  • Create MatchingQuestion component
  • Create QuizResults component
  • Add quiz to LessonPage

Milestones

Milestone Date Status
Database & Models -
Backend Services -
API Controllers -
Question Type Implementation -
Frontend Integration -

Tasks

Backend

  • Create Domain/Entities/Quiz.cs
  • Create Domain/Entities/Question.cs
  • Create Application/DTOs/QuizDto.cs
  • Create Application/DTOs/QuestionDto.cs
  • Create Application/DTOs/AnswerDto.cs
  • Create Application/DTOs/QuizResult.cs
  • Create Domain/Interfaces/IQuizRepository.cs
  • Create Domain/Interfaces/IQuestionRepository.cs
  • Create Infrastructure/Data/Repositories/QuizRepository.cs
  • Create Infrastructure/Data/Repositories/QuestionRepository.cs
  • Create Application/Services/QuizService.cs
  • Create Application/Services/QuestionService.cs
  • Create Application/Services/QuizSubmissionService.cs
  • Create Presentation/Controllers/QuizzesController.cs
  • Create Presentation/Controllers/QuestionsController.cs
  • Integrate with UserProgress from Lesson Management
  • Register services in Program.cs
  • Write unit tests for services
  • Write integration tests for controllers

Database

  • Create migration for Quizzes table
  • Create migration for Questions table
  • Add foreign key from Quizzes to Lessons
  • Add indexes for QuizId, Type
  • Apply migrations

Audio Generation

  • Extend Coqui TTS service for quiz questions
  • Generate audio for listening comprehension questions
  • Store audio files with quiz question IDs

Question Types

  • Implement MCQ answer validation
  • Implement fill-in-the-blank answer validation
  • Implement listening comprehension answer validation
  • Implement matching answer validation
  • Add case-insensitive comparison where appropriate
  • Add whitespace trimming for answers

Frontend

  • Create pages/QuizPage.tsx
  • Create components/QuizTab.tsx
  • Create components/questions/McqQuestion.tsx
  • Create components/questions/FillInBlank.tsx
  • Create components/questions/ListeningQuestion.tsx
  • Create components/questions/MatchingQuestion.tsx
  • Create components/QuizResults.tsx
  • Create hooks/useQuiz.ts
  • Integrate AudioPlayer for listening questions
  • Add quiz timer (optional)
  • Add progress indicator

🔗 Dependencies

Feature Dependencies

Technical Dependencies

  • Entity Framework Core
  • AutoMapper (optional)

Blockers

  • Infrastructure Setup must be complete
  • Lesson Management must be complete
  • User Authentication must be complete for progress tracking

Definition of Done

General Criteria (All Features)

  • All acceptance criteria met and verified
  • All tasks in this document completed
  • Code follows Clean Architecture principles
  • Code reviewed and approved by at least 1 team member
  • All tests passing (unit, integration)
  • Documentation updated (README, AGENTS.md if applicable)
  • Feature works in development environment
  • Feature deployed to staging environment
  • Performance meets defined targets
  • Security review completed
  • No critical bugs or blockers

Quiz-Specific Criteria

  • Quizzes can be created, read, updated, and deleted
  • Questions can be added to, updated in, and removed from quizzes
  • All question types work correctly (MCQ, Fill-in, Listening, Matching)
  • Quiz submission works and returns score
  • Pass/fail determination is correct (80% threshold)
  • User progress is updated on quiz completion
  • Quiz results show correct/incorrect answers
  • Unlimited retakes are allowed
  • Audio for listening questions is generated and accessible

🧪 Testing Strategy

Testing Approach

Test Type Coverage Tools Responsibility
Unit Tests 80%+ code coverage MsTest, Moq Backend Dev
Integration Tests All service interactions MsTest, TestContainers Backend Dev
API Tests All endpoints MsTest, HttpClient Backend Dev
Frontend Unit Tests Component logic Vitest Frontend Dev
Frontend Integration Service integration Vitest Frontend Dev
E2E Tests Critical user journeys Playwright QA/Dev
Manual Testing Exploratory, edge cases BrowserStack QA

Quiz-Specific Tests

Backend Tests

  • Create quiz → success
  • Create quiz with invalid lesson → error
  • Get quiz by ID → returns correct quiz with questions
  • Get quiz by lesson → returns correct quiz
  • Add question to quiz → success
  • Add MCQ question → success
  • Add fill-in question → success
  • Add listening question → success
  • Add matching question → success
  • Update question → success
  • Delete question → success
  • Submit quiz with all correct answers → 100% score
  • Submit quiz with some correct answers → partial score
  • Submit quiz with all wrong answers → 0% score
  • Submit quiz with passing score → user progress updated
  • Submit quiz with failing score → user progress not updated
  • Delete quiz → cascades to questions

Question Type Tests

  • MCQ: Correct answer → scored correctly
  • MCQ: Incorrect answer → scored incorrectly
  • Fill-in: Exact match → scored correctly
  • Fill-in: Case-insensitive match → scored correctly
  • Fill-in: Whitespace variation → scored correctly
  • Fill-in: Close but wrong → scored incorrectly
  • Listening: Correct transcription → scored correctly
  • Listening: Incorrect transcription → scored incorrectly
  • Matching: All pairs correct → scored correctly
  • Matching: Some pairs correct → partial score

Business Logic Tests

  • Scoring with default points → correct calculation
  • Scoring with custom points → correct calculation
  • Pass/fail at 80% threshold → correct determination
  • Pass/fail at exactly 80% → passes
  • Pass/fail at 79% → fails
  • User progress updates on first pass → lesson marked complete
  • User progress updates on subsequent pass → no change (already complete)

📝 Notes & Decisions

Decisions Made

Date Decision Rationale
May 31, 2025 Static difficulty Simpler implementation, consistent experience for all users
May 31, 2025 80% passing score Industry standard, rigorous but achievable
May 31, 2025 Unlimited retakes Encourages practice, reduces anxiety
May 31, 2025 Multiple question types Varied testing, caters to different learning styles
May 31, 2025 Store AudioUrl on questions Enables listening comprehension questions

Technical Notes

  • Questions table uses PostgreSQL TEXT[] array type for Options
  • Each question has a Points value for weighted scoring
  • Quiz.PassingScore is the percentage required (default 80)
  • QuizResult should include: Passed, Score, TotalPoints, QuestionResults[]
  • QuestionResults should include: QuestionId, UserAnswer, CorrectAnswer, IsCorrect, PointsEarned

Question Type Validation Logic

MCQ

  • UserAnswer must exactly match one of the Options
  • Case-insensitive comparison recommended

Fill-in-the-Blank

  • UserAnswer compared to CorrectAnswer
  • Trim whitespace from both before comparison
  • Case-insensitive comparison recommended
  • Consider allowing minor variations (e.g., "steht" vs "stehen")

Listening Comprehension

  • UserAnswer must exactly match CorrectAnswer (or one of Options for MCQ-style listening)
  • AudioUrl must be present and valid

Matching

  • Need to handle multiple pairs
  • Consider storing as: { pairs: [{left: "Buch", right: "das"}, ...] }
  • Validate that all pairs are correct

Gotchas

  • ⚠️ Listening questions require audio generation - can be slow
  • ⚠️ Fill-in-the-blank needs careful validation (accents, case, etc.)
  • ⚠️ Matching questions need special data structure
  • ⚠️ Quiz deletion must cascade to Questions (ON DELETE CASCADE)
  • ⚠️ Question updates must maintain quiz integrity

📊 Progress History

Date Status Change Notes
May 31, 2025 Created Initial plan based on application-plan.md


Feature created from application-plan.md