using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Exceptions; using EnvelopeGenerator.Domain.Entities; using MediatR; using Microsoft.EntityFrameworkCore; namespace EnvelopeGenerator.Application.ThirdPartyModules.Queries; /// /// Query to read the license text of a third-party module. /// Either or must be provided, but not both. /// public record ReadThirdPartyModuleLicenseQuery : IRequest { /// /// The unique identifier of the third-party module (optional). /// public int? Id { get; init; } /// /// The name of the third-party module (optional). /// public string? Name { get; init; } /// /// Whether to filter only active modules. Defaults to true. /// public bool Active { get; init; } = true; } /// /// Handles and returns the license text of a third-party module. /// public class ReadThirdPartyModuleLicenseQueryHandler : IRequestHandler { private readonly IRepository _repository; /// /// Initializes a new instance of the class. /// /// The repository for accessing third-party modules. public ReadThirdPartyModuleLicenseQueryHandler(IRepository repository) { _repository = repository; } /// /// Handles the query by filtering on Id or Name and returning the license text. /// /// The query parameters. /// A cancellation token. /// The license text of the matching third-party module. /// /// Thrown when neither Id nor Name is provided, or when both are provided. /// /// /// Thrown when multiple modules match the given criteria, indicating a data integrity issue. /// /// /// Thrown when no module matches the given criteria. /// public async Task Handle(ReadThirdPartyModuleLicenseQuery request, CancellationToken cancel) { if (request.Id is null && request.Name is null) throw new BadRequestException("Either Id or Name must be provided."); if (request.Id is not null && request.Name is not null) throw new BadRequestException("Only one of Id or Name must be provided, not both."); var query = _repository.Query .Where(m => m.Active == request.Active); if (request.Id is int id) query = query.Where(m => m.Id == id); if (request.Name is string name) query = query.Where(m => m.Name == name); var modules = await query .Take(2) .ToListAsync(cancel); if (modules.Count > 1) throw new InvalidOperationException( $"Data integrity violation: multiple third-party modules found for the given criteria (Id={request.Id}, Name={request.Name}, Active={request.Active})."); return modules.SingleOrDefault() is ThirdPartyModule module ? module.License : throw new NotFoundException( $"Third-party module not found for the given criteria (Id={request.Id}, Name={request.Name}, Active={request.Active})."); } }