All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Add FluentValidation.AspNetCore package - Create LevelValidators (CreateLevelValidator, UpdateLevelValidator) - Create LessonValidators (CreateLessonValidator, UpdateLessonValidator) - Register FluentValidation in Program.cs with auto-validation - Update LevelsController and LessonsController to use IActionResult - Make service methods virtual for Moq testing compatibility - Add 26 integration tests for LevelsController (13 tests) - Add 34 integration tests for LessonsController (17 tests) Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
101 lines
3.4 KiB
C#
101 lines
3.4 KiB
C#
using GermanApp.Application.DTOs;
|
|
using GermanApp.Domain.Entities;
|
|
using GermanApp.Domain.Interfaces;
|
|
|
|
namespace GermanApp.Application.Services;
|
|
|
|
/// <summary>
|
|
/// Application service for managing CEFR levels.
|
|
/// This is part of the Application layer.
|
|
/// </summary>
|
|
public class LevelService
|
|
{
|
|
private readonly ILevelRepository _levelRepository;
|
|
|
|
public LevelService(ILevelRepository levelRepository)
|
|
{
|
|
_levelRepository = levelRepository;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets all CEFR levels ordered by their sort order.
|
|
/// </summary>
|
|
public virtual async Task<IReadOnlyList<LevelDto>> GetAllLevelsAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
var levels = await _levelRepository.GetAllOrderedAsync(cancellationToken);
|
|
return levels.Select(l => l.ToDto()).ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a level by its ID.
|
|
/// </summary>
|
|
public virtual async Task<LevelDto?> GetLevelByIdAsync(int id, CancellationToken cancellationToken = default)
|
|
{
|
|
var level = await _levelRepository.GetByIdAsync(id, cancellationToken);
|
|
return level?.ToDto();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a level by its code (e.g., "A1", "B2").
|
|
/// </summary>
|
|
public virtual async Task<LevelDto?> GetLevelByCodeAsync(string code, CancellationToken cancellationToken = default)
|
|
{
|
|
var level = await _levelRepository.GetByCodeAsync(code, cancellationToken);
|
|
return level?.ToDto();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new CEFR level.
|
|
/// </summary>
|
|
public virtual async Task<LevelDto> CreateLevelAsync(CreateLevelDto dto, CancellationToken cancellationToken = default)
|
|
{
|
|
var level = dto.ToEntity();
|
|
var createdLevel = await _levelRepository.AddAsync(level, cancellationToken);
|
|
return createdLevel.ToDto();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates an existing CEFR level.
|
|
/// </summary>
|
|
public virtual async Task<LevelDto?> UpdateLevelAsync(int id, UpdateLevelDto dto, CancellationToken cancellationToken = default)
|
|
{
|
|
var level = await _levelRepository.GetByIdAsync(id, cancellationToken);
|
|
if (level == null)
|
|
return null;
|
|
|
|
level.UpdateFromDto(dto);
|
|
await _levelRepository.UpdateAsync(level, cancellationToken);
|
|
return level.ToDto();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes a CEFR level by its ID.
|
|
/// </summary>
|
|
public virtual async Task<bool> DeleteLevelAsync(int id, CancellationToken cancellationToken = default)
|
|
{
|
|
var level = await _levelRepository.GetByIdAsync(id, cancellationToken);
|
|
if (level == null)
|
|
return false;
|
|
|
|
await _levelRepository.DeleteAsync(level, cancellationToken);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the first level (lowest order number) - typically A1.
|
|
/// </summary>
|
|
public virtual async Task<LevelDto?> GetFirstLevelAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
var level = await _levelRepository.GetFirstLevelAsync(cancellationToken);
|
|
return level?.ToDto();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the next level after the specified one.
|
|
/// </summary>
|
|
public virtual async Task<LevelDto?> GetNextLevelAsync(int currentLevelId, CancellationToken cancellationToken = default)
|
|
{
|
|
var level = await _levelRepository.GetNextLevelAsync(currentLevelId, cancellationToken);
|
|
return level?.ToDto();
|
|
}
|
|
}
|