Compare commits

...

12 Commits

Author SHA1 Message Date
a3afeb175f Refactor controllers for MediatR and cleaner API design
- Switch EnvelopeController and ReceiverController to MediatR for all operations
- Encapsulate UserId in CreateEnvelopeCommand via Authorize() method
- Change CreateEnvelopeCommand binding to [FromBody]
- Add CancellationToken support to EnvelopeReceiverController
- Remove obsolete CRUD logic from ReceiverController; now only supports GET via MediatR
- Clean up unused dependencies and update controller summaries for clarity
2026-01-28 14:14:04 +01:00
114555c843 Add XML docs to ReadEnvelopeReceiverQueryHandler ctor
Added XML documentation comments to the constructor of the ReadEnvelopeReceiverQueryHandler class, including parameter descriptions for envelopeReceiver, rcvRepo, and mapper. The summary section is currently empty.
2026-01-28 14:10:03 +01:00
f294ef2fde Refactor EnvelopeTypeController to use MediatR
Replace IEnvelopeTypeService with IMediator in EnvelopeTypeController and update GetAllAsync to use ReadEnvelopeTypesQuery. Remove obsolete service-based code and attributes. Also, remove AsNoTracking() from repository query in ReadEnvelopeTypesQueryHandler.
2026-01-28 13:48:02 +01:00
02ad819da9 Refactor EnvelopeReceiverController to use MediatR only
Remove all usage of IEnvelopeReceiverService from EnvelopeReceiverController, including constructor injection and obsolete attributes. Update endpoints to exclusively use MediatR for handling queries. Clean up related obsolete code, comments, and unused usings. Update documentation to reflect these changes.
2026-01-28 13:43:34 +01:00
041d98ca78 Refactor EnvelopeController to use MediatR exclusively
Removed all usage of the obsolete IEnvelopeService from EnvelopeController, refactoring endpoints to use MediatR with ReadEnvelopeQuery. Simplified GetAsync and GetDocResultAsync logic, updated method signatures, and eliminated obsolete code paths and attributes. Cleaned up unused usings and updated constructor dependencies.
2026-01-28 13:41:43 +01:00
afea2fb5ea Refactor envelope queries into unified ReadEnvelopeQuery
Consolidate envelope querying logic by extending ReadEnvelopeQuery to support user filtering and status options, and introduce ReadEnvelopeQueryHandler to process all envelope queries. Remove ReadUserEnvelopesQuery and its handler, reducing duplication and improving maintainability.
2026-01-28 13:34:54 +01:00
beeb9e4e75 Refactor EmailTemplateController to use generic IRepository
Replaces IEmailTemplateRepository with IRepository<EmailTemplate> in EmailTemplateController. Removes unused ILogger dependency and updates the Get method to use the new repository interface. Cleans up obsolete attributes and using directives.
2026-01-28 13:13:37 +01:00
30d13b1ffb Add MediatR query handler for reading receiver details
Introduced a CQRS-style ReadReceiverQueryHandler using MediatR to enable flexible querying of receivers by Id, EmailAddress, or Signature. Integrated AutoMapper for DTO mapping and updated ReadReceiverQuery to support MediatR's request/response pipeline.
2026-01-28 13:09:51 +01:00
814df63306 Add MediatR query/handler for reading envelope types
Introduced ReadEnvelopeTypesQuery and its handler to fetch all
envelope types from the repository, map them to DTOs, and
return the result via MediatR. This enables clean, decoupled
retrieval of envelope types in the application.
2026-01-28 12:55:44 +01:00
830d1af44a Add ReadUserEnvelopesQuery and handler with filtering
Implemented ReadUserEnvelopesQuery and its handler to fetch user envelopes with support for filtering by user ID, status (range, include, ignore), envelope ID, and UUID. Utilizes repository and AutoMapper to return EnvelopeDto results.
2026-01-28 12:54:22 +01:00
94018d2a36 Add query handler to fetch receiver's latest used name
Introduced ReadReceiverNameQueryHandler to retrieve the most recently used name ("Anrede") for a receiver, supporting envelope generation. Updated ReadReceiverNameQuery to use MediatR and CQRS patterns, and implemented repository-based lookups for receiver identification and name retrieval. Added necessary using directives for repository and MediatR support.
2026-01-28 12:51:40 +01:00
cf5a724bf2 Add username filter to ReadEnvelopeReceiverQuery handler
Extended ReadEnvelopeReceiverQuery to support optional username-based filtering. Refactored the handler to apply this filter, updated repository access for consistency, and improved code clarity and null-safety. Cleaned up comments and formatting.
2026-01-28 12:42:21 +01:00
11 changed files with 374 additions and 290 deletions

View File

@@ -1,4 +1,4 @@
using AutoMapper;
using AutoMapper;
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Envelopes.Queries;
@@ -47,7 +47,13 @@ namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
/// Die Antwort enthält Details wie den Include, die Zuordnung zwischen Umschlag und Empfänger
/// sowie zusätzliche Metadaten.
/// </remarks>
public record ReadEnvelopeReceiverQuery : EnvelopeReceiverQueryBase<ReadEnvelopeQuery, ReadReceiverQuery>, IRequest<IEnumerable<EnvelopeReceiverDto>>;
public record ReadEnvelopeReceiverQuery : EnvelopeReceiverQueryBase<ReadEnvelopeQuery, ReadReceiverQuery>, IRequest<IEnumerable<EnvelopeReceiverDto>>
{
/// <summary>
/// Optionaler Benutzernamefilter, um Ergebnisse auf Umschläge eines bestimmten Besitzers einzuschränken.
/// </summary>
public string? Username { get; init; }
}
/// <summary>
///
@@ -82,73 +88,74 @@ public static class Extensions
q.Receiver.Signature = signature;
return mediator.Send(q, cancel).Then(envRcvs => envRcvs.FirstOrDefault());
}
}
/// <summary>
///
/// </summary>
public class ReadEnvelopeReceiverQueryHandler : IRequestHandler<ReadEnvelopeReceiverQuery, IEnumerable<EnvelopeReceiverDto>>
{
private readonly IRepository<EnvelopeReceiver> _repo;
private readonly IRepository<Receiver> _rcvRepo;
private readonly IMapper _mapper;
/// <summary>
///
/// Verarbeitet <see cref="ReadEnvelopeReceiverQuery"/> und liefert passende <see cref="EnvelopeReceiverDto"/>-Ergebnisse.
/// </summary>
/// <param name="envelopeReceiver"></param>
/// <param name="mapper"></param>
public ReadEnvelopeReceiverQueryHandler(IRepository<EnvelopeReceiver> envelopeReceiver, IRepository<Receiver> rcvRepo, IMapper mapper)
public class ReadEnvelopeReceiverQueryHandler : IRequestHandler<ReadEnvelopeReceiverQuery, IEnumerable<EnvelopeReceiverDto>>
{
_repo = envelopeReceiver;
_mapper = mapper;
_rcvRepo = rcvRepo;
}
private readonly IRepository<EnvelopeReceiver> _repo;
private readonly IRepository<Receiver> _rcvRepo;
private readonly IMapper _mapper;
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
/// <exception cref="BadRequestException"></exception>
public async Task<IEnumerable<EnvelopeReceiverDto>> Handle(ReadEnvelopeReceiverQuery request, CancellationToken cancel)
{
var q = _repo.ReadOnly().Where(request, notnull: false);
if (request.Envelope.Status is not null)
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiver"></param>
/// <param name="rcvRepo"></param>
/// <param name="mapper"></param>
public ReadEnvelopeReceiverQueryHandler(IRepository<EnvelopeReceiver> envelopeReceiver, IRepository<Receiver> rcvRepo, IMapper mapper)
{
var status = request.Envelope.Status;
if (status.Min is not null)
q = q.Where(er => er.Envelope!.Status >= status.Min);
if (status.Max is not null)
q = q.Where(er => er.Envelope!.Status <= status.Max);
if (status.Include?.Length > 0)
q = q.Where(er => status.Include.Contains(er.Envelope!.Status));
if (status.Ignore is not null)
q = q.Where(er => !status.Ignore.Contains(er.Envelope!.Status));
_repo = envelopeReceiver;
_mapper = mapper;
_rcvRepo = rcvRepo;
}
var envRcvs = await q
.Include(er => er.Envelope).ThenInclude(e => e!.Documents!).ThenInclude(d => d.Elements)
.Include(er => er.Envelope).ThenInclude(e => e!.Histories)
.Include(er => er.Envelope).ThenInclude(e => e!.User)
.Include(er => er.Receiver)
.ToListAsync(cancel);
if (request.Receiver.HasAnyCriteria && envRcvs.Any())
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
/// <exception cref="BadRequestException"></exception>
public async Task<IEnumerable<EnvelopeReceiverDto>> Handle(ReadEnvelopeReceiverQuery request, CancellationToken cancel)
{
var receiver = await _rcvRepo.ReadOnly().Where(request.Receiver).FirstAsync(cancel);
var q = _repo.Query.Where(request, notnull: false);
foreach (var envRcv in envRcvs)
envRcv.Envelope?.Documents?.First().Elements.RemoveAll(s => s.ReceiverId != receiver.Id);
if (request.Username is string username)
q = q.Where(er => er.Envelope!.User.Username == username);
if (request.Envelope.Status is not null)
{
var status = request.Envelope.Status;
if (status.Min is not null)
q = q.Where(er => er.Envelope!.Status >= status.Min);
if (status.Max is not null)
q = q.Where(er => er.Envelope!.Status <= status.Max);
if (status.Include?.Length > 0)
q = q.Where(er => status.Include.Contains(er.Envelope!.Status));
if (status.Ignore is not null)
q = q.Where(er => !status.Ignore.Contains(er.Envelope!.Status));
}
var envRcvs = await q
.Include(er => er.Envelope).ThenInclude(e => e!.Documents!).ThenInclude(d => d.Elements)
.Include(er => er.Envelope).ThenInclude(e => e!.Histories)
.Include(er => er.Envelope).ThenInclude(e => e!.User)
.Include(er => er.Receiver)
.ToListAsync(cancel);
if (request.Receiver.HasAnyCriteria && envRcvs.Count != 0)
{
var receiver = await _rcvRepo.Query.Where(request.Receiver).FirstAsync(cancel);
foreach (var envRcv in envRcvs)
envRcv.Envelope?.Documents?.FirstOrDefault()?.Elements?.RemoveAll(s => s.ReceiverId != receiver.Id);
}
return _mapper.Map<List<EnvelopeReceiverDto>>(envRcvs);
}
return _mapper.Map<List<EnvelopeReceiverDto>>(envRcvs);
}
}
}

View File

@@ -0,0 +1,45 @@
using EnvelopeGenerator.Application.Common.Dto;
using MediatR;
using AutoMapper;
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Application.EnvelopeTypes.Queries;
/// <summary>
///
/// </summary>
public record ReadEnvelopeTypesQuery : IRequest<IEnumerable<EnvelopeTypeDto>>;
/// <summary>
///
/// </summary>
public class ReadEnvelopeTypesQueryHandler : IRequestHandler<ReadEnvelopeTypesQuery, IEnumerable<EnvelopeTypeDto>>
{
private readonly IRepository<EnvelopeType> _repository;
private readonly IMapper _mapper;
/// <summary>
///
/// </summary>
/// <param name="repository"></param>
/// <param name="mapper"></param>
public ReadEnvelopeTypesQueryHandler(IRepository<EnvelopeType> repository, IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<EnvelopeTypeDto>> Handle(ReadEnvelopeTypesQuery request, CancellationToken cancellationToken)
{
var types = await _repository.Query.ToListAsync(cancellationToken);
return _mapper.Map<IEnumerable<EnvelopeTypeDto>>(types);
}
}

View File

@@ -33,7 +33,18 @@ public record CreateEnvelopeCommand : IRequest<EnvelopeDto?>
/// <summary>
/// ID des Absenders
/// </summary>
public int UserId { get; set; }
internal int UserId { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public bool Authorize(int userId)
{
UserId = userId;
return true;
}
/// <summary>
/// Determines which component is used for envelope processing.

View File

@@ -1,18 +1,33 @@
using MediatR;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Application.Common.Query;
using EnvelopeGenerator.Application.Common.Dto;
using AutoMapper;
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Application.Envelopes.Queries;
/// <summary>
/// Repräsentiert eine Abfrage für Umschläge.
/// </summary>
public record ReadEnvelopeQuery : EnvelopeQueryBase, IRequest
public record ReadEnvelopeQuery : EnvelopeQueryBase, IRequest<IEnumerable<EnvelopeDto>>
{
/// <summary>
/// Abfrage des Include des Umschlags
/// </summary>
public EnvelopeStatusQuery? Status { get; init; }
/// <summary>
/// Optionaler Benutzerfilter; wenn gesetzt, werden nur Umschläge des Benutzers geladen.
/// </summary>
public int? UserId { get; init; }
/// <summary>
/// Setzt den Benutzerkontext für die Abfrage.
/// </summary>
public ReadEnvelopeQuery Authorize(int userId) => this with { UserId = userId };
}
/// <summary>
@@ -65,4 +80,62 @@ public record EnvelopeStatusQuery
/// Eine Liste von Statuswerten, die ignoriert werden werden.
/// </summary>
public EnvelopeStatus[]? Ignore { get; init; }
}
/// <summary>
/// Verarbeitet <see cref="ReadEnvelopeQuery"/> und liefert passende <see cref="EnvelopeDto"/>-Ergebnisse.
/// </summary>
public class ReadEnvelopeQueryHandler : IRequestHandler<ReadEnvelopeQuery, IEnumerable<EnvelopeDto>>
{
private readonly IRepository<Envelope> _repository;
private readonly IMapper _mapper;
/// <summary>
///
/// </summary>
/// <param name="repository"></param>
/// <param name="mapper"></param>
public ReadEnvelopeQueryHandler(IRepository<Envelope> repository, IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public async Task<IEnumerable<EnvelopeDto>> Handle(ReadEnvelopeQuery request, CancellationToken cancel)
{
var query = _repository.Query;
if (request.UserId is int userId)
query = query.Where(e => e.UserId == userId);
if (request.Id is int id)
query = query.Where(e => e.Id == id);
if (request.Uuid is string uuid)
query = query.Where(e => e.Uuid == uuid);
if (request.Status is { } status)
{
if (status.Min is not null)
query = query.Where(e => e.Status >= status.Min);
if (status.Max is not null)
query = query.Where(e => e.Status <= status.Max);
if (status.Include?.Length > 0)
query = query.Where(e => status.Include.Contains(e.Status));
if (status.Ignore?.Length > 0)
query = query.Where(e => !status.Ignore.Contains(e.Status));
}
var envelopes = await query
.Include(e => e.Documents)
.ToListAsync(cancel);
return _mapper.Map<IEnumerable<EnvelopeDto>>(envelopes);
}
}

View File

@@ -1,4 +1,8 @@
using EnvelopeGenerator.Application.Receivers.Queries;
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.Common.Query;
using MediatR;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Application.Envelopes.Queries;
@@ -6,6 +10,54 @@ namespace EnvelopeGenerator.Application.Envelopes.Queries;
/// Eine Abfrage, um die zuletzt verwendete Anrede eines Empfängers zu ermitteln,
/// damit diese für zukünftige Umschläge wiederverwendet werden kann.
/// </summary>
public record ReadReceiverNameQuery() : ReadReceiverQuery
public record ReadReceiverNameQuery() : ReceiverQueryBase, IRequest<string?>;
/// <summary>
///
/// </summary>
public class ReadReceiverNameQueryHandler : IRequestHandler<ReadReceiverNameQuery, string?>
{
}
private readonly IRepository<EnvelopeReceiver> _envelopeReceiverRepository;
private readonly IRepository<Receiver> _receiverRepository;
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiverRepository"></param>
/// <param name="receiverRepository"></param>
public ReadReceiverNameQueryHandler(IRepository<EnvelopeReceiver> envelopeReceiverRepository, IRepository<Receiver> receiverRepository)
{
_envelopeReceiverRepository = envelopeReceiverRepository;
_receiverRepository = receiverRepository;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<string?> Handle(ReadReceiverNameQuery request, CancellationToken cancellationToken)
{
var receiverQuery = _receiverRepository.Query.AsNoTracking();
if (request.Id is int id)
receiverQuery = receiverQuery.Where(r => r.Id == id);
if (request.EmailAddress is string email)
receiverQuery = receiverQuery.Where(r => r.EmailAddress == email);
if (request.Signature is string signature)
receiverQuery = receiverQuery.Where(r => r.Signature == signature);
var receiver = await receiverQuery.FirstOrDefaultAsync(cancellationToken);
if (receiver is null)
return null;
var erName = await _envelopeReceiverRepository.Query
.Where(er => er.ReceiverId == receiver.Id)
.OrderByDescending(er => er.AddedWhen)
.Select(er => er.Name)
.FirstOrDefaultAsync(cancellationToken);
return erName;
}
}

View File

@@ -1,4 +1,10 @@
using EnvelopeGenerator.Application.Common.Query;
using AutoMapper;
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.Common.Dto.Receiver;
using EnvelopeGenerator.Application.Common.Query;
using MediatR;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Application.Receivers.Queries;
@@ -6,4 +12,53 @@ namespace EnvelopeGenerator.Application.Receivers.Queries;
/// Stellt eine Abfrage dar, um die Details eines Empfängers zu lesen.
/// um spezifische Informationen über einen Empfänger abzurufen.
/// </summary>
public record ReadReceiverQuery : ReceiverQueryBase;
public record ReadReceiverQuery : ReceiverQueryBase, IRequest<IEnumerable<ReceiverDto>>;
/// <summary>
///
/// </summary>
public class ReadReceiverQueryHandler : IRequestHandler<ReadReceiverQuery, IEnumerable<ReceiverDto>>
{
private readonly IRepository<Receiver> _repository;
private readonly IMapper _mapper;
/// <summary>
///
/// </summary>
/// <param name="repository"></param>
/// <param name="mapper"></param>
public ReadReceiverQueryHandler(IRepository<Receiver> repository, IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<ReceiverDto>> Handle(ReadReceiverQuery request, CancellationToken cancellationToken)
{
var query = _repository.Query;
if (request.Id is int id)
{
query = query.Where(r => r.Id == id);
}
if (request.EmailAddress is string email)
{
query = query.Where(r => r.EmailAddress == email);
}
if (request.Signature is string signature)
{
query = query.Where(r => r.Signature == signature);
}
var receiver = await query.ToListAsync(cancellationToken);
return _mapper.Map<IEnumerable<ReceiverDto>>(receiver);
}
}

View File

@@ -7,10 +7,10 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MediatR;
using System.Threading.Tasks;
using DigitalData.UserManager.Application.Services;
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Common.Dto;
using EnvelopeGenerator.Application.Common.Interfaces.Repositories;
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
@@ -23,12 +23,9 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers;
[Authorize]
public class EmailTemplateController : ControllerBase
{
private readonly ILogger<EmailTemplateController> _logger;
private readonly IMapper _mapper;
[Obsolete("Use IRepository")]
private readonly IEmailTemplateRepository _repository;
private readonly IRepository<EmailTemplate> _repository;
private readonly IMediator _mediator;
@@ -39,12 +36,11 @@ public class EmailTemplateController : ControllerBase
/// <param name="repository">
/// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird.
/// </param>
[Obsolete("Use IRepository")]
public EmailTemplateController(IMapper mapper, IEmailTemplateRepository repository, ILogger<EmailTemplateController> logger, IMediator mediator)
[Obsolete("Use MediatR")]
public EmailTemplateController(IMapper mapper, IRepository<EmailTemplate> repository, IMediator mediator)
{
_mapper = mapper;
_repository = repository;
_logger = logger;
_mediator = mediator;
}
@@ -67,7 +63,7 @@ public class EmailTemplateController : ControllerBase
{
if (emailTemplate is null || (emailTemplate.Id is null && emailTemplate.Type is null))
{
var temps = await _repository.ReadAllAsync();
var temps = await _repository.Query.ToListAsync();
return Ok(_mapper.Map<IEnumerable<EmailTemplateDto>>(temps));
}
else

View File

@@ -1,11 +1,9 @@
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.Envelopes.Commands;
using EnvelopeGenerator.Application.Envelopes.Commands;
using EnvelopeGenerator.Application.Envelopes.Queries;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using EnvelopeGenerator.Application.Common.Interfaces.Services;
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
@@ -29,21 +27,16 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers;
public class EnvelopeController : ControllerBase
{
private readonly ILogger<EnvelopeController> _logger;
[Obsolete("Use MediatR")]
private readonly IEnvelopeService _envelopeService;
private readonly IMediator _mediator;
/// <summary>
/// Erstellt eine neue Instanz des EnvelopeControllers.
/// </summary>
/// <param name="logger">Der Logger, der für das Protokollieren von Informationen verwendet wird.</param>
/// <param name="envelopeService">Der Dienst, der für die Verarbeitung von Umschlägen zuständig ist.</param>
/// <param name="mediator"></param>
[Obsolete("Use MediatR")]
public EnvelopeController(ILogger<EnvelopeController> logger, IEnvelopeService envelopeService, IMediator mediator)
public EnvelopeController(ILogger<EnvelopeController> logger, IMediator mediator)
{
_logger = logger;
_envelopeService = envelopeService;
_mediator = mediator;
}
@@ -59,98 +52,56 @@ public class EnvelopeController : ControllerBase
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
[Authorize]
[HttpGet]
[Obsolete("Use MediatR")]
public async Task<IActionResult> GetAsync([FromQuery] ReadEnvelopeQuery envelope)
{
if (User.GetId() is int intId)
return await _envelopeService.ReadByUserAsync(intId, min_status: envelope.Status?.Min, max_status: envelope.Status?.Max).ThenAsync(
Success: envelopes =>
{
if (envelope.Id is int id)
envelopes = envelopes.Where(e => e.Id == id);
if (envelope.Status is EnvelopeStatusQuery status)
envelopes = envelopes.Where(e => e.Status == status);
if (envelope.Uuid is string uuid)
envelopes = envelopes.Where(e => e.Uuid == uuid);
return envelopes.Any() ? Ok(envelopes) : NotFound();
},
Fail: IActionResult (msg, ntc) =>
{
_logger.LogNotice(ntc);
return StatusCode(StatusCodes.Status500InternalServerError);
});
else
{
_logger.LogError("Trotz erfolgreicher Autorisierung wurde die Benutzer-ID nicht als Ganzzahl erkannt. Dies könnte auf eine fehlerhafte Erstellung der Anspruchsliste zurückzuführen sein.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
var result = await _mediator.Send(envelope.Authorize(User.GetId()));
return result.Any() ? Ok(result) : NotFound();
}
/// <summary>
/// Ruft das Ergebnis eines Dokuments basierend auf der ID ab.
/// </summary>
/// <param name="id">Die eindeutige ID des Umschlags.</param>
/// <param name="query"></param>
/// <param name="view">Gibt an, ob das Dokument inline angezeigt werden soll (true) oder als Download bereitgestellt wird (false).</param>
/// <returns>Eine IActionResult-Instanz, die das Dokument oder einen Fehlerstatus enthält.</returns>
/// <response code="200">Das Dokument wurde erfolgreich abgerufen.</response>
/// <response code="404">Das Dokument wurde nicht gefunden oder ist nicht verfügbar.</response>
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
[HttpGet("doc-result")]
[Obsolete("Use MediatR")]
public async Task<IActionResult> GetDocResultAsync([FromQuery] int id, [FromQuery] bool view = false)
public async Task<IActionResult> GetDocResultAsync([FromQuery] ReadEnvelopeQuery query, [FromQuery] bool view = false)
{
if (User.GetId() is int intId)
return await _envelopeService.ReadByUserAsync(intId).ThenAsync(
Success: envelopes =>
{
var envelope = envelopes.Where(e => e.Id == id).FirstOrDefault();
var envelopes = await _mediator.Send(query.Authorize(User.GetId()));
var envelope = envelopes.FirstOrDefault();
if (envelope is null)
return NotFound("Envelope not available.");
else if (envelope?.DocResult is null)
return NotFound("The document has not been fully signed or the result has not yet been released.");
else
{
if (view)
{
Response.Headers.Append("Content-Disposition", "inline; filename=\"" + envelope.Uuid + ".pdf\"");
return File(envelope.DocResult, "application/pdf");
}
else
return File(envelope.DocResult, "application/pdf", $"{envelope.Uuid}.pdf");
}
},
Fail: IActionResult (msg, ntc) =>
{
_logger.LogNotice(ntc);
return StatusCode(StatusCodes.Status500InternalServerError);
});
else
if (envelope is null)
return NotFound("Envelope not available.");
if (envelope.DocResult is null)
return NotFound("The document has not been fully signed or the result has not yet been released.");
if (view)
{
_logger.LogError("Trotz erfolgreicher Autorisierung wurde die Benutzer-ID nicht als Ganzzahl erkannt. Dies könnte auf eine fehlerhafte Erstellung der Anspruchsliste zurückzuführen sein.");
return StatusCode(StatusCodes.Status500InternalServerError);
Response.Headers.Append("Content-Disposition", "inline; filename=\"" + envelope.Uuid + ".pdf\"");
return File(envelope.DocResult, "application/pdf");
}
return File(envelope.DocResult, "application/pdf", $"{envelope.Uuid}.pdf");
}
/// <summary>
///
/// </summary>
/// <param name="envelope"></param>
/// <param name="command"></param>
/// <returns></returns>
[NonAction]
[Authorize]
[HttpPost]
public async Task<IActionResult> CreateAsync([FromQuery] CreateEnvelopeCommand envelope)
public async Task<IActionResult> CreateAsync([FromBody] CreateEnvelopeCommand command)
{
envelope.UserId = User.GetId();
var res = await _mediator.Send(envelope);
var res = await _mediator.Send(command.Authorize(User.GetId()));
if (res is null)
{
_logger.LogError("Failed to create envelope. Envelope details: {EnvelopeDetails}", JsonConvert.SerializeObject(envelope));
_logger.LogError("Failed to create envelope. Envelope details: {EnvelopeDetails}", JsonConvert.SerializeObject(command));
return StatusCode(StatusCodes.Status500InternalServerError);
}
else

View File

@@ -1,5 +1,4 @@
using AutoMapper;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
using EnvelopeGenerator.Application.Envelopes.Queries;
@@ -11,12 +10,8 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Options;
using System.Data;
using System.Reflection.Metadata;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Application.Common.SQL;
using EnvelopeGenerator.Application.Common.Dto.Receiver;
using EnvelopeGenerator.Application.Common.Interfaces.Services;
using EnvelopeGenerator.Application.Common.Interfaces.SQLExecutor;
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
@@ -33,38 +28,19 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers;
public class EnvelopeReceiverController : ControllerBase
{
private readonly ILogger<EnvelopeReceiverController> _logger;
[Obsolete("Use MediatR")]
private readonly IEnvelopeReceiverService _erService;
private readonly IMediator _mediator;
private readonly IMapper _mapper;
private readonly IEnvelopeExecutor _envelopeExecutor;
private readonly IEnvelopeReceiverExecutor _erExecutor;
private readonly IDocumentExecutor _documentExecutor;
private readonly string _cnnStr;
/// <summary>
/// Konstruktor für den EnvelopeReceiverController.
/// </summary>
/// <param name="logger">Logger-Instanz zur Protokollierung von Informationen und Fehlern.</param>
/// <param name="envelopeReceiverService">Service zur Verwaltung von Umschlagempfängern.</param>
/// <param name="mediator">Mediator-Instanz zur Verarbeitung von Befehlen und Abfragen.</param>
/// <param name="mapper"></param>
/// <param name="envelopeExecutor"></param>
/// <param name="erExecutor"></param>
/// <param name="documentExecutor"></param>
/// <param name="csOpt"></param>
[Obsolete("Use MediatR")]
public EnvelopeReceiverController(ILogger<EnvelopeReceiverController> logger, IEnvelopeReceiverService envelopeReceiverService, IMediator mediator, IMapper mapper, IEnvelopeExecutor envelopeExecutor, IEnvelopeReceiverExecutor erExecutor, IDocumentExecutor documentExecutor, IOptions<ConnectionString> csOpt)
public EnvelopeReceiverController(ILogger<EnvelopeReceiverController> logger, IMediator mediator, IMapper mapper, IEnvelopeExecutor envelopeExecutor, IEnvelopeReceiverExecutor erExecutor, IDocumentExecutor documentExecutor, IOptions<ConnectionString> csOpt)
{
_logger = logger;
_erService = envelopeReceiverService;
_mediator = mediator;
_mapper = mapper;
_envelopeExecutor = envelopeExecutor;
@@ -87,7 +63,6 @@ public class EnvelopeReceiverController : ControllerBase
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
[Authorize]
[HttpGet]
[Obsolete("Use MediatR")]
public async Task<IActionResult> GetEnvelopeReceiver([FromQuery] ReadEnvelopeReceiverQuery envelopeReceiver)
{
var username = User.GetUsernameOrDefault();
@@ -99,20 +74,11 @@ public class EnvelopeReceiverController : ControllerBase
return StatusCode(StatusCodes.Status500InternalServerError);
}
return await _erService.ReadByUsernameAsync(
username: username,
min_status: envelopeReceiver.Envelope.Status?.Min,
max_status: envelopeReceiver.Envelope.Status?.Max,
envelopeQuery: envelopeReceiver.Envelope,
receiverQuery: envelopeReceiver.Receiver,
ignore_statuses: envelopeReceiver.Envelope.Status?.Ignore ?? Array.Empty<EnvelopeStatus>())
.ThenAsync(
Success: Ok,
Fail: IActionResult (msg, ntc) =>
{
_logger.LogNotice(ntc);
return StatusCode(StatusCodes.Status500InternalServerError, msg);
});
envelopeReceiver = envelopeReceiver with { Username = username };
var result = await _mediator.Send(envelopeReceiver);
return Ok(result);
}
/// <summary>
@@ -129,25 +95,17 @@ public class EnvelopeReceiverController : ControllerBase
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
[Authorize]
[HttpGet("salute")]
[Obsolete("Use MediatR")]
public async Task<IActionResult> GetReceiverName([FromQuery] ReadReceiverNameQuery receiver)
{
return await _erService.ReadLastUsedReceiverNameByMailAsync(receiver.EmailAddress, receiver.Id, receiver.Signature).ThenAsync(
Success: res => res is null ? NotFound() : Ok(res),
Fail: IActionResult (msg, ntc) =>
{
if (ntc.HasFlag(Flag.NotFound))
return NotFound();
_logger.LogNotice(ntc);
return StatusCode(StatusCodes.Status500InternalServerError);
});
var name = await _mediator.Send(receiver);
return name is null ? NotFound() : Ok(name);
}
/// <summary>
/// Datenübertragungsobjekt mit Informationen zu Umschlägen, Empfängern und Unterschriften.
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns>HTTP-Antwort</returns>
/// <remarks>
/// Sample request:
@@ -183,13 +141,10 @@ public class EnvelopeReceiverController : ControllerBase
/// <response code="500">Es handelt sich um einen unerwarteten Fehler. Die Protokolle sollten überprüft werden.</response>
[Authorize]
[HttpPost]
public async Task<IActionResult> CreateAsync([FromBody] CreateEnvelopeReceiverCommand request)
public async Task<IActionResult> CreateAsync([FromBody] CreateEnvelopeReceiverCommand request, CancellationToken cancel)
{
CancellationToken cancel = default;
int userId = User.GetId();
#region Create Envelope
var envelope = await _envelopeExecutor.CreateEnvelopeAsync(userId, request.Title, request.Message, request.TFAEnabled, cancel);
var envelope = await _envelopeExecutor.CreateEnvelopeAsync(User.GetId(), request.Title, request.Message, request.TFAEnabled, cancel);
#endregion
#region Add receivers

View File

@@ -1,5 +1,5 @@
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.Common.Interfaces.Services;
using MediatR;
using EnvelopeGenerator.Application.EnvelopeTypes.Queries;
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
@@ -13,36 +13,27 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers;
public class EnvelopeTypeController : ControllerBase
{
private readonly ILogger<EnvelopeTypeController> _logger;
[Obsolete("Use MediatR")]
private readonly IEnvelopeTypeService _service;
private readonly IMediator _mediator;
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
/// <param name="service"></param>
[Obsolete("Use MediatR")]
public EnvelopeTypeController(ILogger<EnvelopeTypeController> logger, IEnvelopeTypeService service)
/// <param name="mediator"></param>
public EnvelopeTypeController(ILogger<EnvelopeTypeController> logger, IMediator mediator)
{
_logger = logger;
_service = service;
_mediator = mediator;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
[Obsolete("Use MediatR")]
[HttpGet]
public async Task<IActionResult> GetAllAsync()
{
return await _service.ReadAllAsync().ThenAsync(
Success: Ok,
Fail: IActionResult (msg, ntc) =>
{
_logger.LogNotice(ntc);
return ntc.HasFlag(Flag.NotFound) ? NotFound() : StatusCode(StatusCodes.Status500InternalServerError);
});
var result = await _mediator.Send(new ReadEnvelopeTypesQuery());
return Ok(result);
}
}

View File

@@ -1,12 +1,7 @@
using DigitalData.Core.Abstraction.Application.DTO;
using DigitalData.Core.API;
using MediatR;
using EnvelopeGenerator.Application.Receivers.Queries;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using EnvelopeGenerator.Application.Receivers.Commands;
using EnvelopeGenerator.Application.Common.Dto.Receiver;
using EnvelopeGenerator.Application.Common.Interfaces.Services;
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
@@ -14,22 +9,22 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers;
/// Controller für die Verwaltung von Empfängern.
/// </summary>
/// <remarks>
/// Dieser Controller bietet Endpunkte für CRUD-Operationen (Erstellen, Lesen, Aktualisieren, Löschen)
/// sowie zusätzliche Funktionen wie das Abrufen von Empfängern basierend auf E-Mail-Adresse oder Signatur.
/// Dieser Controller bietet Endpunkte für das Abrufen von Empfängern basierend auf E-Mail-Adresse oder Signatur.
/// </remarks>
[Route("api/[controller]")]
[ApiController]
[Authorize]
[Obsolete("Use MediatR")]
public class ReceiverController : CRUDControllerBaseWithErrorHandling<IReceiverService, CreateReceiverCommand, ReceiverDto, UpdateReceiverCommand, Receiver, int>
public class ReceiverController : ControllerBase
{
private readonly IMediator _mediator;
/// <summary>
/// Initialisiert eine neue Instanz des <see cref="ReceiverController"/>-Controllers.
/// </summary>
/// <param name="logger">Der Logger für die Protokollierung.</param>
/// <param name="service">Der Dienst für Empfängeroperationen.</param>
public ReceiverController(ILogger<ReceiverController> logger, IReceiverService service) : base(logger, service)
/// <param name="mediator">Mediator für Anfragen.</param>
public ReceiverController(IMediator mediator)
{
_mediator = mediator;
}
/// <summary>
@@ -40,60 +35,13 @@ public class ReceiverController : CRUDControllerBaseWithErrorHandling<IReceiverS
[HttpGet]
public async Task<IActionResult> Get([FromQuery] ReadReceiverQuery receiver)
{
if (receiver.Id is null && receiver.EmailAddress is null && receiver.Signature is null)
return await base.GetAll();
if (!receiver.HasAnyCriteria)
{
var all = await _mediator.Send(new ReadReceiverQuery());
return Ok(all);
}
if (receiver.Id is int id)
return await _service.ReadByIdAsync(id).ThenAsync(
Success: Ok,
Fail: IActionResult (msg, ntc) =>
{
return NotFound();
});
return await _service.ReadByAsync(emailAddress: receiver.EmailAddress, signature: receiver.Signature).ThenAsync(
Success: Ok,
Fail: IActionResult (msg, ntc) =>
{
return NotFound();
});
var result = await _mediator.Send(receiver);
return result is null ? NotFound() : Ok(result);
}
#region REMOVED ENDPOINTS
/// <summary>
/// Diese Methode ist deaktiviert und wird nicht verwendet.
/// </summary>
[NonAction]
public override Task<IActionResult> GetAll() => base.GetAll();
/// <summary>
/// Diese Methode ist deaktiviert und wird nicht verwendet.
/// </summary>
[NonAction]
public override Task<IActionResult> Delete([FromRoute] int id) => base.Delete(id);
/// <summary>
/// Diese Methode ist deaktiviert und wird nicht verwendet.
/// </summary>
[NonAction]
public override Task<IActionResult> Update(UpdateReceiverCommand updateDto) => base.Update(updateDto);
/// <summary>
/// Diese Methode ist deaktiviert und wird nicht verwendet.
/// </summary>
[NonAction]
public override Task<IActionResult> Create(CreateReceiverCommand createDto)
{
return base.Create(createDto);
}
/// <summary>
/// Diese Methode ist deaktiviert und wird nicht verwendet.
/// </summary>
[NonAction]
public override Task<IActionResult> GetById([FromRoute] int id)
{
return base.GetById(id);
}
#endregion
}