using GermanApp.Application.DTOs; using GermanApp.Application.UseCases.Commands; using GermanApp.Domain.Interfaces; using Microsoft.AspNetCore.Mvc; namespace GermanApp.Presentation.Endpoints; /// /// Minimal API endpoints for Lesson resources. /// This is part of the Presentation layer. /// public static class LessonsEndpoints { public static void MapLessonsEndpoints(this WebApplication app) { var group = app.MapGroup("/api/lessons"); // GET /api/lessons group.MapGet("/", async ([FromServices] ILessonRepository repository) => { var lessons = await repository.GetAllAsync(); return Results.Ok(lessons.Select(l => l.ToDto())); }) .WithName("GetAllLessons") .WithOpenApi(operation => new(operation) { Summary = "Get all lessons", Description = "Retrieves all available German lessons" }); // GET /api/lessons/{id} group.MapGet("/{id}", async ([FromRoute] int id, [FromServices] ILessonRepository repository) => { var lesson = await repository.GetByIdAsync(id); return lesson is null ? Results.NotFound() : Results.Ok(lesson.ToDto()); }) .WithName("GetLessonById") .WithOpenApi(operation => new(operation) { Summary = "Get lesson by ID", Description = "Retrieves a specific lesson by its identifier" }); // GET /api/lessons/beginner group.MapGet("/beginner", async ([FromServices] ILessonRepository repository) => { var lessons = await repository.GetBeginnerLessonsAsync(); return Results.Ok(lessons.Select(l => l.ToDto())); }) .WithName("GetBeginnerLessons") .WithOpenApi(operation => new(operation) { Summary = "Get beginner lessons", Description = "Retrieves all lessons at beginner level (A1-A2)" }); // GET /api/lessons/advanced group.MapGet("/advanced", async ([FromServices] ILessonRepository repository) => { var lessons = await repository.GetAdvancedLessonsAsync(); return Results.Ok(lessons.Select(l => l.ToDto())); }) .WithName("GetAdvancedLessons") .WithOpenApi(operation => new(operation) { Summary = "Get advanced lessons", Description = "Retrieves all lessons at advanced level (B2-C1)" }); // GET /api/lessons/level/{level} group.MapGet("/level/{level}", async ([FromRoute] int level, [FromServices] ILessonRepository repository) => { var lessons = await repository.GetByLevelAsync(level); return Results.Ok(lessons.Select(l => l.ToDto())); }) .WithName("GetLessonsByLevel") .WithOpenApi(operation => new(operation) { Summary = "Get lessons by level", Description = "Retrieves all lessons at a specific proficiency level" }); // POST /api/lessons group.MapPost("/", async ( [FromBody] CreateLessonDto dto, [FromServices] ICommandHandler handler, CancellationToken cancellationToken) => { var command = new CreateLessonCommand(dto); var result = await handler.Handle(command, cancellationToken); return Results.Created($"/api/lessons/{result.Id}", result); }) .WithName("CreateLesson") .WithOpenApi(operation => new(operation) { Summary = "Create a new lesson", Description = "Creates a new German lesson" }); // PUT /api/lessons/{id} group.MapPut("/{id}", async ( [FromRoute] int id, [FromBody] UpdateLessonDto dto, [FromServices] ILessonRepository repository) => { var existingLesson = await repository.GetByIdAsync(id); if (existingLesson is null) return Results.NotFound(); // Map DTO to entity existingLesson.Update(dto.Title, dto.Description, dto.Level); await repository.UpdateAsync(existingLesson); return Results.Ok(existingLesson.ToDto()); }) .WithName("UpdateLesson") .WithOpenApi(operation => new(operation) { Summary = "Update a lesson", Description = "Updates an existing lesson" }); // DELETE /api/lessons/{id} group.MapDelete("/{id}", async ([FromRoute] int id, [FromServices] ILessonRepository repository) => { var lesson = await repository.GetByIdAsync(id); if (lesson is null) return Results.NotFound(); await repository.DeleteAsync(lesson); return Results.NoContent(); }) .WithName("DeleteLesson") .WithOpenApi(operation => new(operation) { Summary = "Delete a lesson", Description = "Deletes a lesson by its identifier" }); } }