feat(application): add workflow and document request handlers
This commit is contained in:
@@ -0,0 +1,60 @@
|
|||||||
|
using DigitalData.TaskFlow.Application.Common.Interfaces;
|
||||||
|
using DigitalData.TaskFlow.Domain.Common;
|
||||||
|
using DigitalData.TaskFlow.Domain.Documents;
|
||||||
|
using DigitalData.TaskFlow.Domain.Enums;
|
||||||
|
using FluentValidation;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace DigitalData.TaskFlow.Application.Features.Documents.Queries.GetDocument;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a request to retrieve binary document content by document identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id">Document identifier.</param>
|
||||||
|
public sealed record GetDocumentQuery(string Id) : IRequest<ApiEnvelope<DocumentBinaryResult>>;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validates <see cref="GetDocumentQuery"/> requests.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class GetDocumentQueryValidator : AbstractValidator<GetDocumentQuery>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes validation rules for <see cref="GetDocumentQuery"/>.
|
||||||
|
/// </summary>
|
||||||
|
public GetDocumentQueryValidator()
|
||||||
|
{
|
||||||
|
RuleFor(x => x.Id)
|
||||||
|
.NotEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles <see cref="GetDocumentQuery"/> requests.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class GetDocumentQueryHandler(IDocumentRepository documentRepository)
|
||||||
|
: IRequestHandler<GetDocumentQuery, ApiEnvelope<DocumentBinaryResult>>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Executes the query and returns binary document data in the standard API envelope.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Query request.</param>
|
||||||
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
|
/// <returns>Document response envelope.</returns>
|
||||||
|
public async Task<ApiEnvelope<DocumentBinaryResult>> Handle(GetDocumentQuery request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var document = await documentRepository.GetAsync(request.Id, cancellationToken);
|
||||||
|
|
||||||
|
return new ApiEnvelope<DocumentBinaryResult>
|
||||||
|
{
|
||||||
|
Meta =
|
||||||
|
[
|
||||||
|
new MetaEntry
|
||||||
|
{
|
||||||
|
Code = (int)MetaCode.Ok,
|
||||||
|
Message = "OK"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
Data = document
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
using DigitalData.TaskFlow.Application.Common.Interfaces;
|
||||||
|
using DigitalData.TaskFlow.Domain.Closing;
|
||||||
|
using DigitalData.TaskFlow.Domain.Common;
|
||||||
|
using DigitalData.TaskFlow.Domain.Enums;
|
||||||
|
using FluentValidation;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace DigitalData.TaskFlow.Application.Features.Workflows.Commands.CloseWorkflow;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a request to close a workflow process using a selected closing method.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="WisagId">WISAG user identifier.</param>
|
||||||
|
/// <param name="Source">Source system name.</param>
|
||||||
|
/// <param name="ProcessId">Process identifier.</param>
|
||||||
|
/// <param name="ClosingMethodId">Selected closing method identifier.</param>
|
||||||
|
/// <param name="Comment">Optional user comment.</param>
|
||||||
|
/// <param name="RejectionReasonId">Optional rejection reason identifier.</param>
|
||||||
|
public sealed record CloseWorkflowCommand(
|
||||||
|
int WisagId,
|
||||||
|
string Source,
|
||||||
|
int ProcessId,
|
||||||
|
int ClosingMethodId,
|
||||||
|
string? Comment,
|
||||||
|
int? RejectionReasonId)
|
||||||
|
: IRequest<ApiEnvelope<CloseWorkflowResult>>;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validates <see cref="CloseWorkflowCommand"/> requests.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class CloseWorkflowCommandValidator : AbstractValidator<CloseWorkflowCommand>
|
||||||
|
{
|
||||||
|
private static readonly string[] AllowedSources = ["Ferdinand", "Contracts"];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes validation rules for <see cref="CloseWorkflowCommand"/>.
|
||||||
|
/// </summary>
|
||||||
|
public CloseWorkflowCommandValidator()
|
||||||
|
{
|
||||||
|
RuleFor(x => x.WisagId)
|
||||||
|
.GreaterThan(0);
|
||||||
|
|
||||||
|
RuleFor(x => x.ProcessId)
|
||||||
|
.GreaterThan(0);
|
||||||
|
|
||||||
|
RuleFor(x => x.ClosingMethodId)
|
||||||
|
.GreaterThan(0);
|
||||||
|
|
||||||
|
RuleFor(x => x.Source)
|
||||||
|
.NotEmpty()
|
||||||
|
.Must(source => AllowedSources.Contains(source))
|
||||||
|
.WithMessage("Source must be one of the supported source systems.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles <see cref="CloseWorkflowCommand"/> requests.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class CloseWorkflowCommandHandler(IWorkflowRepository workflowRepository)
|
||||||
|
: IRequestHandler<CloseWorkflowCommand, ApiEnvelope<CloseWorkflowResult>>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Executes the closing request and returns the operation result in the standard API envelope.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Command request.</param>
|
||||||
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
|
/// <returns>Closing result envelope.</returns>
|
||||||
|
public async Task<ApiEnvelope<CloseWorkflowResult>> Handle(CloseWorkflowCommand request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var decision = new CloseWorkflowDecision
|
||||||
|
{
|
||||||
|
ClosingMethodId = request.ClosingMethodId,
|
||||||
|
Comment = request.Comment,
|
||||||
|
RejectionReasonId = request.RejectionReasonId
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = await workflowRepository.CloseAsync(
|
||||||
|
request.WisagId,
|
||||||
|
request.Source,
|
||||||
|
request.ProcessId,
|
||||||
|
decision,
|
||||||
|
cancellationToken);
|
||||||
|
|
||||||
|
return new ApiEnvelope<CloseWorkflowResult>
|
||||||
|
{
|
||||||
|
Meta =
|
||||||
|
[
|
||||||
|
new MetaEntry
|
||||||
|
{
|
||||||
|
Code = (int)MetaCode.Ok,
|
||||||
|
Message = "OK"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
Data = result
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using DigitalData.TaskFlow.Application.Common.Interfaces;
|
||||||
|
using DigitalData.TaskFlow.Domain.Common;
|
||||||
|
using DigitalData.TaskFlow.Domain.Enums;
|
||||||
|
using DigitalData.TaskFlow.Domain.Workflows;
|
||||||
|
using FluentValidation;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace DigitalData.TaskFlow.Application.Features.Workflows.Queries.GetWorkflows;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a request to fetch grouped workflow data for a WISAG user.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="WisagId">WISAG user identifier.</param>
|
||||||
|
public sealed record GetWorkflowsQuery(int WisagId) : IRequest<ApiEnvelope<WorkflowSourcesResponse>>;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validates <see cref="GetWorkflowsQuery"/> requests.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class GetWorkflowsQueryValidator : AbstractValidator<GetWorkflowsQuery>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes validation rules for <see cref="GetWorkflowsQuery"/>.
|
||||||
|
/// </summary>
|
||||||
|
public GetWorkflowsQueryValidator()
|
||||||
|
{
|
||||||
|
RuleFor(x => x.WisagId)
|
||||||
|
.GreaterThan(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles <see cref="GetWorkflowsQuery"/> requests.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class GetWorkflowsQueryHandler(IWorkflowRepository workflowRepository)
|
||||||
|
: IRequestHandler<GetWorkflowsQuery, ApiEnvelope<WorkflowSourcesResponse>>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Executes the query and returns a workflow payload wrapped in the standard API envelope.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Query request.</param>
|
||||||
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
|
/// <returns>Workflow response envelope.</returns>
|
||||||
|
public async Task<ApiEnvelope<WorkflowSourcesResponse>> Handle(GetWorkflowsQuery request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var data = await workflowRepository.GetAsync(request.WisagId, cancellationToken);
|
||||||
|
|
||||||
|
return new ApiEnvelope<WorkflowSourcesResponse>
|
||||||
|
{
|
||||||
|
Meta =
|
||||||
|
[
|
||||||
|
new MetaEntry
|
||||||
|
{
|
||||||
|
Code = (int)MetaCode.Ok,
|
||||||
|
Message = "OK"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
Data = data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user