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
📋 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)
Phase 2: Backend Services (2-3 hours)
Phase 3: API Controllers (2 hours)
Phase 4: Question Type Implementation (2 hours)
Phase 5: Frontend Integration (2 hours)
Milestones
| Milestone |
Date |
Status |
| Database & Models |
- |
⏳ |
| Backend Services |
- |
⏳ |
| API Controllers |
- |
⏳ |
| Question Type Implementation |
- |
⏳ |
| Frontend Integration |
- |
⏳ |
✅ Tasks
Backend
Database
Audio Generation
Question Types
Frontend
🔗 Dependencies
Feature Dependencies
Technical Dependencies
- Entity Framework Core
- AutoMapper (optional)
Blockers
✅ Definition of Done
General Criteria (All Features)
Quiz-Specific Criteria
🧪 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
Question Type Tests
Business Logic Tests
📝 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 |
📎 Related Files & Links
Feature created from application-plan.md