- Add QuizQuestion and QuizOption domain entities with QuestionType enum - Add IQuizQuestionRepository and IQuizOptionRepository interfaces - Add QuizQuestionRepository and QuizOptionRepository EF Core implementations - Add QuizQuestionService with CRUD, quiz submission, and statistics - Add QuizQuestionsController with comprehensive REST API endpoints - Add QuizQuestionDto and related DTOs for API communication - Add EF Core migration (20260612050652_AddQuizQuestionTables) for QuizQuestion and QuizOption - Add seed data with sample quiz questions for Greetings, Numbers, Grammar lessons - Update AppDbContext with DbSets and entity configurations - Update Program.cs with migration retry logic for Docker - Update docker-compose.yml with SeedDatabase configuration - Add unit tests for QuizQuestionService Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
191 lines
5.2 KiB
C#
191 lines
5.2 KiB
C#
using GermanApp.Domain.Entities;
|
|
|
|
namespace GermanApp.Application.DTOs;
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for QuizQuestion - used for API responses.
|
|
/// This is a read-only representation of a QuizQuestion entity.
|
|
/// </summary>
|
|
public record QuizQuestionDto(
|
|
int Id,
|
|
int LessonId,
|
|
string LessonTitle,
|
|
string QuestionText,
|
|
QuestionType Type,
|
|
string? CorrectAnswer,
|
|
int Difficulty,
|
|
int Order,
|
|
bool IsActive,
|
|
DateTime CreatedAt,
|
|
DateTime? UpdatedAt,
|
|
IReadOnlyList<QuizOptionDto> Options);
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for creating a new QuizQuestion.
|
|
/// </summary>
|
|
public record CreateQuizQuestionDto(
|
|
int LessonId,
|
|
string QuestionText,
|
|
QuestionType Type,
|
|
string? CorrectAnswer,
|
|
int Difficulty,
|
|
int Order,
|
|
IReadOnlyList<CreateQuizOptionDto>? Options);
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for updating an existing QuizQuestion.
|
|
/// </summary>
|
|
public record UpdateQuizQuestionDto(
|
|
int LessonId,
|
|
string QuestionText,
|
|
QuestionType Type,
|
|
string? CorrectAnswer,
|
|
int Difficulty,
|
|
int Order,
|
|
bool IsActive,
|
|
IReadOnlyList<UpdateQuizOptionDto>? Options);
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for QuizOption - used for API responses.
|
|
/// </summary>
|
|
public record QuizOptionDto(
|
|
int Id,
|
|
int QuizQuestionId,
|
|
string Text,
|
|
bool IsCorrect,
|
|
int Order);
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for creating a new QuizOption.
|
|
/// </summary>
|
|
public record CreateQuizOptionDto(
|
|
string Text,
|
|
bool IsCorrect,
|
|
int Order);
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for updating an existing QuizOption.
|
|
/// </summary>
|
|
public record UpdateQuizOptionDto(
|
|
int Id,
|
|
string Text,
|
|
bool IsCorrect,
|
|
int Order);
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for quiz question with user's answer.
|
|
/// </summary>
|
|
public record QuizQuestionWithAnswerDto(
|
|
int QuizQuestionId,
|
|
int LessonId,
|
|
string QuestionText,
|
|
QuestionType Type,
|
|
IReadOnlyList<QuizOptionDto> Options,
|
|
string? UserAnswer,
|
|
bool IsCorrect);
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for submitting quiz answers.
|
|
/// </summary>
|
|
public record SubmitQuizAnswersDto(
|
|
int LessonId,
|
|
IReadOnlyList<QuizAnswerDto> Answers);
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for a single quiz answer submission.
|
|
/// </summary>
|
|
public record QuizAnswerDto(
|
|
int QuizQuestionId,
|
|
string? AnswerText,
|
|
int[]? SelectedOptionIds);
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for quiz result.
|
|
/// </summary>
|
|
public record QuizResultDto(
|
|
int LessonId,
|
|
int TotalQuestions,
|
|
int CorrectAnswers,
|
|
double ScorePercentage,
|
|
bool Passed,
|
|
TimeSpan TimeTaken,
|
|
IReadOnlyList<QuizQuestionResultDto> QuestionResults);
|
|
|
|
/// <summary>
|
|
/// Data Transfer Object for individual question result.
|
|
/// </summary>
|
|
public record QuizQuestionResultDto(
|
|
int QuizQuestionId,
|
|
string QuestionText,
|
|
QuestionType Type,
|
|
bool IsCorrect,
|
|
string? CorrectAnswer,
|
|
string? UserAnswer);
|
|
|
|
/// <summary>
|
|
/// Extension methods for mapping between QuizQuestion entity and DTOs.
|
|
/// </summary>
|
|
public static class QuizQuestionDtoExtensions
|
|
{
|
|
public static QuizQuestionDto ToDto(this QuizQuestion quizQuestion) => new(
|
|
quizQuestion.Id,
|
|
quizQuestion.LessonId,
|
|
quizQuestion.Lesson?.Title ?? "Unknown",
|
|
quizQuestion.QuestionText,
|
|
quizQuestion.Type,
|
|
quizQuestion.CorrectAnswer,
|
|
quizQuestion.Difficulty,
|
|
quizQuestion.Order,
|
|
quizQuestion.IsActive,
|
|
quizQuestion.CreatedAt,
|
|
quizQuestion.UpdatedAt,
|
|
quizQuestion.Options?.OrderBy(o => o.Order).Select(o => o.ToDto()).ToList() ?? new List<QuizOptionDto>());
|
|
|
|
public static QuizQuestion ToEntity(this CreateQuizQuestionDto dto) =>
|
|
QuizQuestion.Create(
|
|
dto.LessonId,
|
|
dto.QuestionText,
|
|
dto.Type,
|
|
dto.CorrectAnswer ?? string.Empty,
|
|
dto.Difficulty,
|
|
dto.Order);
|
|
|
|
public static void UpdateFromDto(this QuizQuestion quizQuestion, UpdateQuizQuestionDto dto)
|
|
{
|
|
quizQuestion.UpdateLesson(dto.LessonId);
|
|
quizQuestion.UpdateQuestionText(dto.QuestionText);
|
|
quizQuestion.UpdateType(dto.Type);
|
|
quizQuestion.UpdateCorrectAnswer(dto.CorrectAnswer ?? string.Empty);
|
|
quizQuestion.UpdateDifficulty(dto.Difficulty);
|
|
quizQuestion.UpdateOrder(dto.Order);
|
|
|
|
if (dto.IsActive != quizQuestion.IsActive)
|
|
{
|
|
if (dto.IsActive)
|
|
quizQuestion.Activate();
|
|
else
|
|
quizQuestion.Deactivate();
|
|
}
|
|
}
|
|
|
|
public static QuizOptionDto ToDto(this QuizOption quizOption) => new(
|
|
quizOption.Id,
|
|
quizOption.QuizQuestionId,
|
|
quizOption.Text,
|
|
quizOption.IsCorrect,
|
|
quizOption.Order);
|
|
|
|
public static QuizOption ToEntity(this CreateQuizOptionDto dto, int quizQuestionId) =>
|
|
QuizOption.Create(
|
|
quizQuestionId,
|
|
dto.Text,
|
|
dto.IsCorrect,
|
|
dto.Order);
|
|
|
|
public static void UpdateFromDto(this QuizOption quizOption, UpdateQuizOptionDto dto)
|
|
{
|
|
quizOption.UpdateText(dto.Text);
|
|
quizOption.UpdateIsCorrect(dto.IsCorrect);
|
|
quizOption.UpdateOrder(dto.Order);
|
|
}
|
|
}
|