DeutschLernen/GermanApp/Application/DTOs/QuizQuestionDto.cs
Lasse Rune Hansen 242d5ea60b feat(backend): Complete Quiz System implementation
- Add Quiz entity with full domain logic (Create, Update, Activate, Deactivate)
- Add QuizQuestion entity updated to use QuizId instead of LessonId
- Add QuizRepository with all CRUD and query methods
- Add QuizQuestionRepository with QuizId-based and LessonId-based (legacy) methods
- Add QuizDto, CreateQuizDto, UpdateQuizDto, QuizWithQuestionsDto, QuizListItemDto
- Add QuizQuestionDto updated with QuizId, LessonId, QuizTitle, Points fields
- Add CreateQuizCommand, UpdateQuizCommand, DeleteQuizCommand, GetQuizWithQuestionsCommand
- Add QuizService with full quiz management (CRUD, activate, deactivate, counts, queries)
- Add QuizQuestionService updated with QuizId-based methods
- Add QuizzesController with comprehensive endpoints (GET, POST, PUT, DELETE)
- Add QuizzesController endpoints for quiz questions (by-quiz, random, active)
- Update QuizQuestionsController with new QuizId-based endpoints (backward compatible)
- Register QuizRepository and QuizService in DI container
- Update IRepository interfaces with QuizId-based methods
- Add SubmitQuizDto for quiz answer submission

Clean Architecture layers maintained:
- Domain: Quiz, QuizQuestion entities with business logic
- Application: DTOs, Commands, Services
- Infrastructure: Repositories, DbContext
- Presentation: Controllers

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-13 07:41:46 +02:00

207 lines
5.6 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 QuizId,
int LessonId,
string QuizTitle,
string LessonTitle,
string QuestionText,
QuestionType Type,
string? CorrectAnswer,
int Points,
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 QuizId,
string QuestionText,
QuestionType Type,
string? CorrectAnswer,
int Points,
int Difficulty,
int Order,
IReadOnlyList<CreateQuizOptionDto>? Options);
/// <summary>
/// Data Transfer Object for updating an existing QuizQuestion.
/// </summary>
public record UpdateQuizQuestionDto(
int QuizId,
string QuestionText,
QuestionType Type,
string? CorrectAnswer,
int Points,
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 QuizId,
int LessonId,
string QuestionText,
QuestionType Type,
int Points,
IReadOnlyList<QuizOptionDto> Options,
string? UserAnswer,
bool IsCorrect);
/// <summary>
/// Data Transfer Object for submitting quiz answers.
/// </summary>
public record SubmitQuizAnswersDto(
int QuizId,
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 QuizId,
int LessonId,
string QuizTitle,
int TotalQuestions,
int TotalPoints,
int ScorePoints,
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,
int Points,
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.QuizId,
quizQuestion.Quiz?.LessonId ?? 0,
quizQuestion.Quiz?.Title ?? "Unknown",
quizQuestion.Quiz?.Lesson?.Title ?? "Unknown",
quizQuestion.QuestionText,
quizQuestion.Type,
quizQuestion.CorrectAnswer,
quizQuestion.Points,
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.QuizId,
dto.QuestionText,
dto.Type,
dto.CorrectAnswer ?? string.Empty,
dto.Points,
dto.Difficulty,
dto.Order);
public static void UpdateFromDto(this QuizQuestion quizQuestion, UpdateQuizQuestionDto dto)
{
quizQuestion.UpdateQuiz(dto.QuizId);
quizQuestion.UpdateQuestionText(dto.QuestionText);
quizQuestion.UpdateType(dto.Type);
quizQuestion.UpdateCorrectAnswer(dto.CorrectAnswer ?? string.Empty);
quizQuestion.UpdatePoints(dto.Points);
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);
}
}