- 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>
207 lines
5.6 KiB
C#
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);
|
|
}
|
|
}
|