DeutschLernen/GermanApp/Application/DTOs/QuizDto.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

151 lines
3.9 KiB
C#

using GermanApp.Domain.Entities;
namespace GermanApp.Application.DTOs;
/// <summary>
/// Data Transfer Object for Quiz - used for API responses.
/// This is a read-only representation of a Quiz entity.
/// </summary>
public record QuizDto(
int Id,
int LessonId,
string LessonTitle,
string Title,
string? Description,
int PassingScore,
int TimeLimitMinutes,
bool ShuffleQuestions,
bool IsActive,
int QuestionCount,
int TotalPoints,
DateTime CreatedAt,
DateTime? UpdatedAt);
/// <summary>
/// Data Transfer Object for creating a new Quiz.
/// </summary>
public record CreateQuizDto(
int LessonId,
string Title,
string? Description,
int PassingScore,
int TimeLimitMinutes,
bool ShuffleQuestions);
/// <summary>
/// Data Transfer Object for updating an existing Quiz.
/// </summary>
public record UpdateQuizDto(
int LessonId,
string Title,
string? Description,
int PassingScore,
int TimeLimitMinutes,
bool ShuffleQuestions,
bool IsActive);
/// <summary>
/// Data Transfer Object for quiz with its questions.
/// </summary>
public record QuizWithQuestionsDto(
int Id,
int LessonId,
string LessonTitle,
string Title,
string? Description,
int PassingScore,
int TimeLimitMinutes,
bool ShuffleQuestions,
bool IsActive,
DateTime CreatedAt,
DateTime? UpdatedAt,
IReadOnlyList<QuizQuestionDto> Questions);
/// <summary>
/// Data Transfer Object for quiz list item (summary).
/// </summary>
public record QuizListItemDto(
int Id,
int LessonId,
string LessonTitle,
string Title,
bool IsActive,
int QuestionCount,
DateTime CreatedAt);
/// <summary>
/// Data Transfer Object for submitting quiz answers.
/// </summary>
public record SubmitQuizDto(
int QuizId,
IReadOnlyList<QuizAnswerDto> Answers);
/// <summary>
/// Extension methods for mapping between Quiz entity and DTOs.
/// </summary>
public static class QuizDtoExtensions
{
public static QuizDto ToDto(this Quiz quiz) => new(
quiz.Id,
quiz.LessonId,
quiz.Lesson?.Title ?? "Unknown",
quiz.Title,
quiz.Description,
quiz.PassingScore,
quiz.TimeLimitMinutes,
quiz.ShuffleQuestions,
quiz.IsActive,
quiz.Questions?.Count ?? 0,
quiz.Questions?.Sum(q => q.Points) ?? 0,
quiz.CreatedAt,
quiz.UpdatedAt);
public static QuizListItemDto ToListItemDto(this Quiz quiz) => new(
quiz.Id,
quiz.LessonId,
quiz.Lesson?.Title ?? "Unknown",
quiz.Title,
quiz.IsActive,
quiz.Questions?.Count ?? 0,
quiz.CreatedAt);
public static QuizWithQuestionsDto ToQuizWithQuestionsDto(this Quiz quiz) => new(
quiz.Id,
quiz.LessonId,
quiz.Lesson?.Title ?? "Unknown",
quiz.Title,
quiz.Description,
quiz.PassingScore,
quiz.TimeLimitMinutes,
quiz.ShuffleQuestions,
quiz.IsActive,
quiz.CreatedAt,
quiz.UpdatedAt,
quiz.Questions?.OrderBy(q => q.Order).Select(q => q.ToDto()).ToList() ?? new List<QuizQuestionDto>());
public static Quiz ToEntity(this CreateQuizDto dto) =>
Quiz.Create(
dto.LessonId,
dto.Title,
dto.Description,
dto.PassingScore,
dto.TimeLimitMinutes);
public static void UpdateFromDto(this Quiz quiz, UpdateQuizDto dto)
{
quiz.UpdateLesson(dto.LessonId);
quiz.UpdateTitle(dto.Title);
quiz.UpdateDescription(dto.Description);
quiz.UpdatePassingScore(dto.PassingScore);
quiz.UpdateTimeLimit(dto.TimeLimitMinutes);
quiz.UpdateShuffleQuestions(dto.ShuffleQuestions);
if (dto.IsActive != quiz.IsActive)
{
if (dto.IsActive)
quiz.Activate();
else
quiz.Deactivate();
}
}
}