Skip to content

Commit 5b787dc

Browse files
committed
ECER-5292: ICRA Eligibility submission endpoint and manager layer
1 parent bbb3baa commit 5b787dc

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

src/ECER.Clients.RegistryPortal/ECER.Clients.RegistryPortal.Server/ICRA/ICRAEligibilitiesEndpoints.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using ECER.Utilities.Security;
66
using MediatR;
77
using Microsoft.AspNetCore.Http.HttpResults;
8+
using Microsoft.AspNetCore.Mvc;
89

910
namespace ECER.Clients.RegistryPortal.Server.ICRA;
1011

@@ -58,6 +59,36 @@ public void Register(IEndpointRouteBuilder endpointRouteBuilder)
5859
.WithOpenApi("Handles icra queries", string.Empty, "icra_get")
5960
.RequireAuthorization()
6061
.WithParameterValidation();
62+
63+
endpointRouteBuilder.MapPost("/api/icra", async Task<Results<Ok<SubmitICRAEligibilityResponse>, BadRequest<ProblemDetails>, NotFound>> (ICRAEligibilitySubmissionRequest request, HttpContext ctx, IMediator messageBus, IMapper mapper, CancellationToken ct) =>
64+
{
65+
var userId = ctx.User.GetUserContext()?.UserId;
66+
bool IdIsNotGuid = !Guid.TryParse(request.Id, out _); if (IdIsNotGuid)
67+
{
68+
return TypedResults.BadRequest(new ProblemDetails() { Title = "ICRAEligibilityId is not valid" });
69+
}
70+
71+
var cmd = new SubmitICRAEligibilityCommand(request.Id!, userId!);
72+
var result = await messageBus.Send(cmd, ct);
73+
if (!result.IsSuccess && result.Error == Managers.Registry.Contract.ICRA.SubmissionError.DraftIcraEligibilityNotFound)
74+
{
75+
return TypedResults.NotFound();
76+
}
77+
if (!result.IsSuccess && result.Error == Managers.Registry.Contract.ICRA.SubmissionError.DraftIcraEligibilityValidationFailed)
78+
{
79+
var problemDetails = new ProblemDetails
80+
{
81+
Status = StatusCodes.Status400BadRequest,
82+
Title = "ICRA Eligibility submission failed",
83+
Extensions = { ["errors"] = result.ValidationErrors }
84+
};
85+
return TypedResults.BadRequest(problemDetails);
86+
}
87+
return TypedResults.Ok(new SubmitICRAEligibilityResponse(mapper.Map<ICRAEligibility>(result.Eligibility)));
88+
})
89+
.WithOpenApi("Submit an ICRA Eligibility", string.Empty, "icra_post")
90+
.RequireAuthorization()
91+
.WithParameterValidation();
6192
}
6293
}
6394

@@ -128,3 +159,6 @@ public enum ICRAStatus
128159
ReadyforReview,
129160
Submitted
130161
}
162+
163+
public record ICRAEligibilitySubmissionRequest(string Id);
164+
public record SubmitICRAEligibilityResponse(ICRAEligibility Eligibility);

src/ECER.Managers.Registry.Contract/ICRA/Contract.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ public record ICRAEligibilitiesQuery : IRequest<ICRAEligibilitiesQueryResults>
1313
}
1414

1515
public record ICRAEligibilitiesQueryResults(IEnumerable<ICRAEligibility> Items);
16+
17+
public record SubmitICRAEligibilityCommand(string icraEligibilityId, string userId) : IRequest<SubmitICRAEligibilityResult>;
18+
19+
public record SubmitICRAEligibilityResult()
20+
{
21+
public ICRAEligibility? Eligibility { get; set; }
22+
public SubmissionError? Error { get; set; }
23+
public IEnumerable<string>? ValidationErrors { get; set; }
24+
public bool IsSuccess { get { return ValidationErrors == null || !ValidationErrors.Any(); } }
25+
}
26+
27+
public enum SubmissionError
28+
{
29+
DraftIcraEligibilityNotFound,
30+
DraftIcraEligibilityValidationFailed
31+
}
1632
public record ICRAEligibility()
1733
{
1834
public string? Id { get; set; }

src/ECER.Managers.Registry/ICRAEligibilityHandlers.cs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using ECER.Resources.Documents.Applications;
66
using ECER.Resources.Documents.ICRA;
77
using MediatR;
8+
using ECER.Engines.Validation.ICRA;
89

910

1011
namespace ECER.Managers.Registry;
@@ -14,9 +15,11 @@ namespace ECER.Managers.Registry;
1415
/// </summary>
1516
public class ICRAEligibilityHandlers(
1617
IICRARepository iCRARepository,
17-
IMapper mapper)
18+
IMapper mapper,
19+
IICRAValidationEngine icraValidationEngine)
1820
: IRequestHandler<SaveICRAEligibilityCommand, Contract.ICRA.ICRAEligibility?>,
19-
IRequestHandler<ICRAEligibilitiesQuery, ICRAEligibilitiesQueryResults>
21+
IRequestHandler<ICRAEligibilitiesQuery, ICRAEligibilitiesQueryResults>,
22+
IRequestHandler<SubmitICRAEligibilityCommand, SubmitICRAEligibilityResult>
2023
{
2124

2225
public async Task<Contract.ICRA.ICRAEligibility?> Handle(SaveICRAEligibilityCommand request, CancellationToken cancellationToken)
@@ -27,7 +30,7 @@ public class ICRAEligibilityHandlers(
2730
var icraEligibilities = await iCRARepository.Query(new ICRAQuery
2831
{
2932
ByApplicantId = request.eligibility.ApplicantId,
30-
ByStatus = [Resources.Documents.ICRA.ICRAStatus.Draft]
33+
ByStatus = [Resources.Documents.ICRA.ICRAStatus.Draft] // IDE0028: already simplified
3134
}, cancellationToken);
3235

3336
var existingDraftICRA = icraEligibilities.FirstOrDefault();
@@ -47,6 +50,37 @@ public class ICRAEligibilityHandlers(
4750
return mapper.Map<Contract.ICRA.ICRAEligibility>(freshIcraEligibilities.SingleOrDefault())!;
4851
}
4952

53+
public async Task<SubmitICRAEligibilityResult> Handle(SubmitICRAEligibilityCommand request, CancellationToken cancellationToken)
54+
{
55+
ArgumentNullException.ThrowIfNull(request);
56+
57+
var eligibilities = await iCRARepository.Query(new ICRAQuery
58+
{
59+
ById = request.icraEligibilityId,
60+
ByApplicantId = request.userId,
61+
ByStatus = [Resources.Documents.ICRA.ICRAStatus.Draft]
62+
}, cancellationToken);
63+
64+
var draft = mapper.Map<IEnumerable<Contract.ICRA.ICRAEligibility>>(eligibilities)!.FirstOrDefault();
65+
if (draft == null)
66+
{
67+
return new SubmitICRAEligibilityResult { Eligibility = null, Error = Contract.ICRA.SubmissionError.DraftIcraEligibilityNotFound, ValidationErrors = new List<string> { "draft icra eligibility does not exist" } };
68+
}
69+
70+
var validation = await icraValidationEngine.Validate(draft!);
71+
if (!validation.IsValid)
72+
{
73+
return new SubmitICRAEligibilityResult { Eligibility = null, Error = Contract.ICRA.SubmissionError.DraftIcraEligibilityValidationFailed, ValidationErrors = validation.ValidationErrors };
74+
}
75+
76+
var repoModel = mapper.Map<Resources.Documents.ICRA.ICRAEligibility>(draft)!;
77+
repoModel.Status = Resources.Documents.ICRA.ICRAStatus.Submitted;
78+
var id = await iCRARepository.Save(repoModel, cancellationToken);
79+
80+
var fresh = await iCRARepository.Query(new ICRAQuery { ById = id }, cancellationToken);
81+
return new SubmitICRAEligibilityResult { Eligibility = mapper.Map<Contract.ICRA.ICRAEligibility>(fresh.SingleOrDefault()) };
82+
}
83+
5084

5185
public async Task<ICRAEligibilitiesQueryResults> Handle(ICRAEligibilitiesQuery request, CancellationToken cancellationToken)
5286
{

0 commit comments

Comments
 (0)