- Updated Lesson entity to use LevelId (int) instead of Level (int) - Added navigation property Level (Level entity) - Added Order, Topic, and IsActive properties to Lesson - Updated Lesson.Create() factory method signature to accept levelId, title, order, topic, description - Split Update method into individual property update methods - Updated LessonDto to use LevelId, LevelName, LevelCode instead of Level int - Added CreateLessonDto and UpdateLessonDto with all required fields - Added UpdateFromDto extension method for Lesson - Updated CreateLessonCommand to validate LevelId instead of Level - Updated SeedDataExtension to seed Level entities first, then use new Lesson.Create() signature - Made SeedDatabaseAsync async and updated Program.cs to await it - Updated LessonsEndpoints to use GetByLevelAsync for beginner/advanced queries - Fixed missing using directive for Domain.Entities Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
65 lines
2 KiB
C#
65 lines
2 KiB
C#
using GermanApp.Application.DTOs;
|
|
using GermanApp.Domain.Entities;
|
|
using GermanApp.Domain.Exceptions;
|
|
using GermanApp.Domain.Interfaces;
|
|
|
|
namespace GermanApp.Application.UseCases.Commands;
|
|
|
|
/// <summary>
|
|
/// Command for creating a new lesson.
|
|
/// This follows the CQRS pattern - commands represent write operations.
|
|
/// </summary>
|
|
public record CreateLessonCommand(CreateLessonDto LessonData) : ICommand<LessonDto>;
|
|
|
|
/// <summary>
|
|
/// Handler for the CreateLessonCommand.
|
|
/// </summary>
|
|
public class CreateLessonCommandHandler : ICommandHandler<CreateLessonCommand, LessonDto>
|
|
{
|
|
private readonly ILessonRepository _lessonRepository;
|
|
|
|
public CreateLessonCommandHandler(ILessonRepository lessonRepository)
|
|
{
|
|
_lessonRepository = lessonRepository;
|
|
}
|
|
|
|
public async Task<LessonDto> Handle(CreateLessonCommand command, CancellationToken cancellationToken)
|
|
{
|
|
// Convert DTO to domain entity
|
|
var lesson = command.LessonData.ToEntity();
|
|
|
|
// Validate business rules (could be extracted to a validator)
|
|
if (lesson.LevelId < 1 || lesson.LevelId > 5)
|
|
{
|
|
throw new ValidationException("Level must be between 1 and 5");
|
|
}
|
|
|
|
// Add to repository
|
|
var createdLesson = await _lessonRepository.AddAsync(lesson, cancellationToken);
|
|
|
|
// Return DTO representation
|
|
return createdLesson.ToDto();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generic command interface.
|
|
/// </summary>
|
|
/// <typeparam name="TResult">The result type</typeparam>
|
|
public interface ICommand<out TResult>
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generic command handler interface.
|
|
/// </summary>
|
|
/// <typeparam name="TCommand">The command type</typeparam>
|
|
/// <typeparam name="TResult">The result type</typeparam>
|
|
public interface ICommandHandler<in TCommand, TResult>
|
|
where TCommand : ICommand<TResult>
|
|
{
|
|
Task<TResult> Handle(TCommand command, CancellationToken cancellationToken);
|
|
}
|
|
|
|
// Note: For MediatR integration, you would implement IRequestHandler<TCommand, TResult>
|
|
// instead of the custom interfaces above.
|