Hardened API and catered for Partner role query filter bypass
This commit is contained in:
@@ -19,7 +19,7 @@ public sealed class GetApplicantInviteEndpoint : IEndpoint
|
||||
await service.GetApplicantInviteAsync(applicantUserId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var invite } => Results.Ok(invite),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
.WithDescription("Gets an applicant's invite")
|
||||
@@ -27,8 +27,8 @@ public sealed class GetApplicantInviteEndpoint : IEndpoint
|
||||
.WithName(typeof(GetApplicantInviteEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Invite>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Communications)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class GetApplicantInvitesEndpoint : IEndpoint
|
||||
await service.GetApplicantInvitesAsync(applicantUserId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var invite } => Results.Ok(invite),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
.WithDescription("Gets an applicant's invite list")
|
||||
@@ -27,8 +27,8 @@ public sealed class GetApplicantInvitesEndpoint : IEndpoint
|
||||
.WithName(typeof(GetApplicantInvitesEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Invite[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Communications)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public class CreateIndicatorEndpoint : IEndpoint
|
||||
await service.CreateIndicatorAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -28,8 +28,8 @@ public class CreateIndicatorEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateIndicatorEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Evidence);
|
||||
|
||||
@@ -19,7 +19,7 @@ public class CreateMilestoneEndpoint : IEndpoint
|
||||
await service.CreateMilestoneAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -30,6 +30,7 @@ public class CreateMilestoneEndpoint : IEndpoint
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Evidence);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class GetEvidenceEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var evidence } => Results.Ok(evidence),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific evidence record and assiciated file URLs")
|
||||
@@ -27,9 +27,9 @@ public sealed class GetEvidenceEndpoint : IEndpoint
|
||||
.WithName(typeof(GetEvidenceEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Domain.Models.Evidence>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Evidence)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,17 +19,17 @@ public sealed class GetEvidenceUrlEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var evidenceUrl } => Results.Ok(evidenceUrl),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a secure download URL of the evidence file, URL expires (default: 15min)")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(GetEvidenceUrlEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<string>(StatusCodes.Status200OK)
|
||||
.Produces<string>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<string>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetIndicatorEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var indicator } => Results.Ok(indicator),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific indicator.")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetIndicatorEndpoint : IEndpoint
|
||||
.WithName(typeof(GetIndicatorEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Indicator>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Evidence)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class UpdateEvidenceEndpoint : IEndpoint
|
||||
await service.UpdateEvidenceAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<UpdateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -29,9 +29,9 @@ public sealed class UpdateEvidenceEndpoint : IEndpoint
|
||||
.WithName(typeof(UpdateEvidenceEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Evidence);
|
||||
|
||||
@@ -19,7 +19,7 @@ public class CreateDisbursementEndpoint : IEndpoint
|
||||
await service.CreateDisbursementAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
@@ -28,9 +28,9 @@ public class CreateDisbursementEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateDisbursementEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Execution);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public class CreateRiskEndpoint : IEndpoint
|
||||
await service.CreateRiskAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -28,9 +28,9 @@ public class CreateRiskEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateRiskEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Execution);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetDisbursementEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var disbursement } => Results.Ok(disbursement),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific disbursement")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetDisbursementEndpoint : IEndpoint
|
||||
.WithName(typeof(GetDisbursementEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Disbursement>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Execution)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetRiskEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var risk } => Results.Ok(risk),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific risk")
|
||||
@@ -28,8 +28,8 @@ public sealed class GetRiskEndpoint : IEndpoint
|
||||
.WithName(typeof(GetRiskEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Risk>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Execution)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetRuleEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var rules } => Results.Ok(rules),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific programme rule")
|
||||
@@ -28,8 +28,8 @@ public sealed class GetRuleEndpoint : IEndpoint
|
||||
.WithName(typeof(GetRuleEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Rule>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Execution)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -18,7 +18,7 @@ public class GetInstrumentsEndpoint : IEndpoint
|
||||
CancellationToken cancellationToken = default) =>
|
||||
await service.GetInstrumentsAsync(programmeId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var instrumenrs } => Results.Ok(instrumenrs),
|
||||
{ IsSuccess: true, Value: var instruments } => Results.Ok(instruments),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
|
||||
@@ -20,7 +20,7 @@ public class GetOrganisationEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var organisation } => Results.Ok(organisation),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get organization profile by ID")
|
||||
@@ -28,9 +28,9 @@ public class GetOrganisationEndpoint : IEndpoint
|
||||
.WithName(typeof(GetOrganisationEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Organisation>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Governance)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class GetPortfolioEndpoint : IEndpoint
|
||||
await service.GetPortfolioAsync(portfolioIdHash: portfolioId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var portfolio } => Results.Ok(portfolio),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific portfolios")
|
||||
@@ -27,9 +27,9 @@ public sealed class GetPortfolioEndpoint : IEndpoint
|
||||
.WithName(typeof(GetPortfolioEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Portfolio[]>(StatusCodes.Status200OK)
|
||||
.Produces<Portfolio[]>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Governance)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class GetPortfolioProgrammesEndpoint : IEndpoint
|
||||
await service.GetPortfolioProgrammesAsync(portfolioId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var portfolios } => Results.Ok(portfolios),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -28,9 +28,9 @@ public sealed class GetPortfolioProgrammesEndpoint : IEndpoint
|
||||
.WithName(typeof(GetPortfolioProgrammesEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Programme[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Governance)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public class CreateAwardEndpoint : IEndpoint
|
||||
await service.CreateAwardAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
@@ -30,7 +30,7 @@ public class CreateAwardEndpoint : IEndpoint
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants);
|
||||
|
||||
@@ -20,8 +20,8 @@ public class CreateBudgetEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Create a new budget line (M05)")
|
||||
@@ -29,8 +29,8 @@ public class CreateBudgetEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateBudgetEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
|
||||
@@ -19,7 +19,7 @@ public class CreateContractEndpoint : IEndpoint
|
||||
await service.CreateContractAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -29,6 +29,7 @@ public class CreateContractEndpoint : IEndpoint
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.WithTags(EndpointTags.Grants);
|
||||
|
||||
@@ -20,7 +20,7 @@ public class GetAwardEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var award } => Results.Ok(award),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get award by ID")
|
||||
@@ -30,7 +30,7 @@ public class GetAwardEndpoint : IEndpoint
|
||||
.Produces<Award>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public class GetBudgetEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var budget } => Results.Ok(budget),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get budget by ID")
|
||||
@@ -28,7 +28,7 @@ public class GetBudgetEndpoint : IEndpoint
|
||||
.WithName(typeof(GetBudgetEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Budget>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
|
||||
@@ -20,7 +20,7 @@ public class GetContractEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var contract } => Results.Ok(contract),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get contract by ID")
|
||||
@@ -28,7 +28,7 @@ public class GetContractEndpoint : IEndpoint
|
||||
.WithName(typeof(GetContractEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Contract>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class GetContractUrlEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var contractUrl} => Results.Ok(contractUrl),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a secure download URL, has expiry period (default 15min)")
|
||||
@@ -29,7 +29,7 @@ public sealed class GetContractUrlEndpoint : IEndpoint
|
||||
.Produces<string>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class UpdateContractEndpoint : IEndpoint
|
||||
await service.UpdateContractAsync(request, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<UpdateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
@@ -30,7 +30,7 @@ public sealed class UpdateContractEndpoint : IEndpoint
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants)
|
||||
|
||||
@@ -40,7 +40,6 @@ public sealed class UploadContractEndpoint : IEndpoint
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public class CreateActivityEndpoint : IEndpoint
|
||||
await service.CreateActivityAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } result => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -28,6 +28,7 @@ public class CreateActivityEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateActivityEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class CreateProgrammeEndpoint : IEndpoint
|
||||
await service.CreateProgrammeAsync(request, userId: context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
@@ -29,9 +29,9 @@ public sealed class CreateProgrammeEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateProgrammeEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public class CreateProjectEndpoint : IEndpoint
|
||||
await service.CreateProjectAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } result => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
@@ -29,9 +29,9 @@ public class CreateProjectEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateProjectEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.WithTags(EndpointTags.Projects);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public class GetActivityEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var activity } => Results.Ok(activity),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific activity by it's id")
|
||||
@@ -27,9 +27,9 @@ public class GetActivityEndpoint : IEndpoint
|
||||
.WithName(typeof(GetActivityEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Domain.Models.Activity>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetBeneficiariesEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var beneficiaries } => Results.Ok(beneficiaries),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project beneficiaries")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetBeneficiariesEndpoint : IEndpoint
|
||||
.WithName(typeof(GetBeneficiariesEndpoint).ToEndpointName("Retrieval"))
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Beneficiary[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetBeneficiaryEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var beneficiary } => Results.Ok(beneficiary),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project beneficiaries")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetBeneficiaryEndpoint : IEndpoint
|
||||
.WithName(typeof(GetBeneficiariesEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Beneficiary>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetChangeRequestEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var changeRequest } => Results.Ok(changeRequest),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific project change request")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetChangeRequestEndpoint : IEndpoint
|
||||
.WithName(typeof(GetChangeRequestEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<ChangeRequest>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetChangeRequestsEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var changeRequests } => Results.Ok(changeRequests),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project change requests")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetChangeRequestsEndpoint : IEndpoint
|
||||
.WithName(typeof(GetChangeRequestsEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<ChangeRequest[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetComplianceItemEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var complianceItem } => Results.Ok(complianceItem),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific project compliance item")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetComplianceItemEndpoint : IEndpoint
|
||||
.WithName(typeof(GetComplianceItemEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<ComplianceItem>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetComplianceItemsEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var complianceItems } => Results.Ok(complianceItems),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project compliance items")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetComplianceItemsEndpoint : IEndpoint
|
||||
.WithName(typeof(GetComplianceItemsEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<ComplianceItem[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetIssueEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var issue } => Results.Ok(issue),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific project issue")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetIssueEndpoint : IEndpoint
|
||||
.WithName(typeof(GetIssueEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Issue>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetIssuesEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var issues } => Results.Ok(issues),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project issues")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetIssuesEndpoint : IEndpoint
|
||||
.WithName(typeof(GetIssuesEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Issue[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public class GetMilestoneEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var milestone } => Results.Ok(milestone),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific milestone")
|
||||
@@ -28,9 +28,9 @@ public class GetMilestoneEndpoint : IEndpoint
|
||||
.WithName(typeof(GetMilestoneEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Milestone>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetOutcomeEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var outcome } => Results.Ok(outcome),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific project outcome")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetOutcomeEndpoint : IEndpoint
|
||||
.WithName(typeof(GetOutcomeEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Outcome>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetOutcomesEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var outcomes } => Results.Ok(outcomes),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project beneficiary outcomes")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetOutcomesEndpoint : IEndpoint
|
||||
.WithName(typeof(GetOutcomesEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Outcome[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class GetProgrammeEndpoint : IEndpoint
|
||||
await service.GetProgrammeAsync(programmeId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var programme } => Results.Ok(programme),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -30,6 +30,7 @@ public sealed class GetProgrammeEndpoint : IEndpoint
|
||||
.Produces<Programme>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class GetProgrammeProjectsEndpoint : IEndpoint
|
||||
await service.GetProgrammeProjectsAsync(programmeId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var projects } => Results.Ok(projects),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
@@ -28,9 +28,9 @@ public sealed class GetProgrammeProjectsEndpoint : IEndpoint
|
||||
.WithName(typeof(GetProgrammeProjectsEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Project[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public class GetProjectEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var project } => Results.Ok(project),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get project by ID")
|
||||
@@ -28,9 +28,9 @@ public class GetProjectEndpoint : IEndpoint
|
||||
.WithName(typeof(GetProjectEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Project[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetSiteVisitEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var siteVisit } => Results.Ok(siteVisit),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project site visit")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetSiteVisitEndpoint : IEndpoint
|
||||
.WithName(typeof(GetSiteVisitEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<SiteVisit>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class GetSiteVisitsEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var siteVisits } => Results.Ok(siteVisits),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project site visits")
|
||||
@@ -28,9 +28,9 @@ public sealed class GetSiteVisitsEndpoint : IEndpoint
|
||||
.WithName(typeof(GetSiteVisitsEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<SiteVisit[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class UpdateProgrammeEndpoint : IEndpoint
|
||||
await service.UpdateProgrammeAsync(request, userId: context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<UpdateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -30,6 +30,7 @@ public sealed class UpdateProgrammeEndpoint : IEndpoint
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects);
|
||||
|
||||
@@ -19,7 +19,7 @@ public class UpdateProjectStatusEndpoint : IEndpoint
|
||||
await service.UpdateProjectStatusAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<UpdateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -29,6 +29,7 @@ public class UpdateProjectStatusEndpoint : IEndpoint
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects);
|
||||
|
||||
@@ -29,6 +29,7 @@ builder.Services.AddApiVersioning(options =>
|
||||
});
|
||||
|
||||
builder.Services.AddScoped<ActiveUserFilter>();
|
||||
builder.Services.AddScoped<UserRoleFilter>();
|
||||
builder.Services.AddTransient<ITenantContextService, TenantContextService>();
|
||||
|
||||
builder.Services.AddEndpoints(Assembly.GetExecutingAssembly());
|
||||
@@ -156,6 +157,15 @@ var versionGroups = new Dictionary<int, RouteGroupBuilder>
|
||||
|
||||
var filter = context.HttpContext.RequestServices.GetRequiredService<ActiveUserFilter>();
|
||||
|
||||
return await filter.InvokeAsync(context, next);
|
||||
})
|
||||
.AddEndpointFilter(async (context, next) =>
|
||||
{
|
||||
if (HttpMethods.IsOptions(context.HttpContext.Request.Method))
|
||||
return await next(context);
|
||||
|
||||
var filter = context.HttpContext.RequestServices.GetRequiredService<UserRoleFilter>();
|
||||
|
||||
return await filter.InvokeAsync(context, next);
|
||||
})
|
||||
}
|
||||
|
||||
@@ -15,17 +15,13 @@ public sealed class ActiveUserFilter(IIdentityService identityService) : IEndpoi
|
||||
|
||||
var (decoded, userId) = principal.GetUserId();
|
||||
var (emailDecoded, email) = principal.GetUserEmail();
|
||||
var (roleDecoded, role) = principal.GetUserRole();
|
||||
|
||||
|
||||
if (!decoded)
|
||||
return Results.Json(new { message = "Invalid user identifier in token." }, statusCode: StatusCodes.Status401Unauthorized);
|
||||
|
||||
if (!emailDecoded)
|
||||
return Results.Json(new { message = "Invalid/missing user email in token." }, statusCode: StatusCodes.Status401Unauthorized);
|
||||
|
||||
if (!roleDecoded)
|
||||
return Results.Json(new { message = "Invalid/missing user role in token." }, statusCode: StatusCodes.Status401Unauthorized);
|
||||
|
||||
var path = context.HttpContext.Request.Path.Value;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(path) && !path!.EndsWith("integration/sync", StringComparison.InvariantCultureIgnoreCase))
|
||||
@@ -38,8 +34,7 @@ public sealed class ActiveUserFilter(IIdentityService identityService) : IEndpoi
|
||||
|
||||
context.HttpContext.Items[UserIdItemKey] = userId;
|
||||
context.HttpContext.Items[EmailtemKey] = email;
|
||||
context.HttpContext.Items[UserRoleItemKey] = role;
|
||||
|
||||
|
||||
return await next(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using static PostFundManagement.Domain.Extensions.Constants;
|
||||
|
||||
namespace PostFundManagement.Application.Filters;
|
||||
|
||||
public sealed class UserRoleFilter(ITenantContextService tenantContext) : IEndpointFilter
|
||||
{
|
||||
public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
|
||||
{
|
||||
var principal = context.HttpContext.User;
|
||||
|
||||
var (roleDecoded, role) = principal.GetUserRole();
|
||||
|
||||
if (!roleDecoded)
|
||||
return Results.Json(new { message = "Invalid/missing user role in token." }, statusCode: StatusCodes.Status401Unauthorized);
|
||||
|
||||
context.HttpContext.Items[UserRoleItemKey] = role;
|
||||
|
||||
if (role.Equals("Partner", StringComparison.InvariantCultureIgnoreCase))
|
||||
tenantContext.ByPassTenantQueryFilter = true;
|
||||
|
||||
return await next(context);
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public sealed class CommunicationsService(IDbContextFactory<ApplicationDbContext
|
||||
|
||||
return Result.FailIf(await context.SaveChangesAsync(cancellationToken) <= 0 && notificationResult.IsFailed,
|
||||
CreateError.Create("Failed to create invite, contact support").CausedBy(notificationResult.Errors))
|
||||
.ToResult(invite.Map());
|
||||
.ToResult(invite?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Invite[]>> GetInvitesAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
|
||||
@@ -72,8 +72,8 @@ public sealed class CommunicationsService(IDbContextFactory<ApplicationDbContext
|
||||
.OrderByDescending(o => o.Id)
|
||||
.FirstOrDefaultAsync(i => i.Recipient == applicantUserId, cancellationToken);
|
||||
|
||||
return Result.FailIf(invite is null, NotFoundError.Create("No active invite found"))
|
||||
.ToResult(invite!.Map());
|
||||
return Result.FailIf(invite == null, NotFoundError.Create("No active invite found"))
|
||||
.ToResult(invite?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Invite[]>> GetApplicantInvitesAsync(Guid applicantUserId, CancellationToken cancellationToken = default) =>
|
||||
@@ -86,7 +86,7 @@ public sealed class CommunicationsService(IDbContextFactory<ApplicationDbContext
|
||||
.OrderByDescending(o => o.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(invites.Select(i => i.Map()).ToArray());
|
||||
return Result.Ok(invites?.Select(i => i.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateNotificationAsync(CreateNotificationRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -162,6 +162,6 @@ public sealed class CommunicationsService(IDbContextFactory<ApplicationDbContext
|
||||
.FirstOrDefaultAsync(n => n.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(notification is null, NotFoundError.Create("Notification not found"))
|
||||
.ToResult(notification!.Map());
|
||||
.ToResult(notification?.Map()!);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
|
||||
|
||||
context.Evidences.Add(evidence);
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create evidence."));
|
||||
}));
|
||||
|
||||
public async Task<Result> RecordIndicatorActualAmountAsync(string indicatorIdHash, decimal amount, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -65,7 +65,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
|
||||
.SetProperty(f => f.ActualAmount, amount)
|
||||
.SetProperty(f => f.CreatedBy, userId), cancellationToken);
|
||||
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.New);
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.Create("Failed to update indicator."));
|
||||
}));
|
||||
|
||||
public async Task<Result<Indicator[]>> GetIndicatorsAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
|
||||
@@ -79,7 +79,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(indicators.Select(i => i.Map()).ToArray());
|
||||
return Result.Ok(indicators?.Select(i => i.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Domain.Models.Evidence[]>> GetEvidenceFilesAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
|
||||
@@ -93,7 +93,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(evidence.Select(i => i.Map()).ToArray());
|
||||
return Result.Ok(evidence?.Select(i => i.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateMilestoneAsync(CreateMilestoneRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -142,7 +142,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
|
||||
CreatedAt = DateTime.UtcNow
|
||||
});
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create indicator."));
|
||||
}));
|
||||
|
||||
public async Task<Result<Indicator>> GetIndicatorAsync(string indicatorId, CancellationToken cancellationToken) =>
|
||||
@@ -158,8 +158,8 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
|
||||
|
||||
var indicator = await context.Indicators.AsNoTracking().FirstOrDefaultAsync(i => i.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(indicator is null, NotFoundError.New)
|
||||
.ToResult(indicator!.Map());
|
||||
return Result.FailIf(indicator is null, NotFoundError.Create("Indicator not found."))
|
||||
.ToResult(indicator?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Domain.Models.Evidence>> GetEvidenceAsync(string evidenceId, CancellationToken cancellationToken = default) =>
|
||||
@@ -175,8 +175,8 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
|
||||
|
||||
var evidence = await context.Evidences.AsNoTracking().FirstOrDefaultAsync(e => e.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(evidence is null, NotFoundError.New)
|
||||
.ToResult(evidence!.Map());
|
||||
return Result.FailIf(evidence is null, NotFoundError.Create("Evidence not found."))
|
||||
.ToResult(evidence?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Domain.Models.Evidence[]>> GetMilestoneEvidencesAsync(string milestoneIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -196,7 +196,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
|
||||
.ThenByDescending(o => o.UpdatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(evidences.Select(e => e.Map()).ToArray());
|
||||
return Result.Ok(evidences?.Select(e => e.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Domain.Models.Evidence[]>> GetProjectEvidencesAsync(string projectIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -216,7 +216,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
|
||||
.ThenBy(o => o.UpdatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(evidences.Select(e => e.Map()).ToArray());
|
||||
return Result.Ok(evidences?.Select(e => e.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdateEvidenceAsync(UpdateEvidenceRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -235,7 +235,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
|
||||
.SetProperty(f => f.UpdatedBy, userId)
|
||||
.SetProperty(f => f.UpdatedAt, DateTime.UtcNow), cancellationToken);
|
||||
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.New);
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.Create("Failed to update evidence."));
|
||||
}));
|
||||
|
||||
public async Task<Result<string>> GetEvidenceUrlAsync(string evidenceIdHash, CancellationToken cancellationToken = default) =>
|
||||
|
||||
@@ -59,7 +59,7 @@ public sealed class ExecutionService(IDbContextFactory<ApplicationDbContext> con
|
||||
CreatedAt = DateTime.UtcNow
|
||||
});
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create risk."));
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateDisbursementAsync(CreateDisbursementRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -80,7 +80,7 @@ public sealed class ExecutionService(IDbContextFactory<ApplicationDbContext> con
|
||||
CreatedAt = DateTime.UtcNow
|
||||
});
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create disbursement."));
|
||||
}));
|
||||
|
||||
public async Task<Result> ApproveDisbursementAsync(string disbursementIdHash, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -100,7 +100,7 @@ public sealed class ExecutionService(IDbContextFactory<ApplicationDbContext> con
|
||||
.SetProperty(f => f.UpdatedBy, userId)
|
||||
.SetProperty(f => f.UpdatedAt, DateTime.UtcNow), cancellationToken);
|
||||
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.New);
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.Create("Failed to approve disbursement."));
|
||||
}));
|
||||
|
||||
public async Task<Result<Disbursement>> GetDisbursementAsync(string disbursementIdHash, CancellationToken cancellationToken) =>
|
||||
@@ -117,8 +117,8 @@ public sealed class ExecutionService(IDbContextFactory<ApplicationDbContext> con
|
||||
var disbursement = await context.Disbursements.AsNoTracking()
|
||||
.FirstOrDefaultAsync(d => d.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(disbursement is null, NotFoundError.New)
|
||||
.ToResult(disbursement!.Map());
|
||||
return Result.FailIf(disbursement is null, NotFoundError.Create("Disbursement not found."))
|
||||
.ToResult(disbursement?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Risk>> GetRiskAsync(string riskIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -135,8 +135,8 @@ public sealed class ExecutionService(IDbContextFactory<ApplicationDbContext> con
|
||||
var risk = await context.Risks.AsNoTracking()
|
||||
.FirstOrDefaultAsync(r => r.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(risk is null, NotFoundError.New)
|
||||
.ToResult(risk!.Map());
|
||||
return Result.FailIf(risk is null, NotFoundError.Create("Risk not found."))
|
||||
.ToResult(risk?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdateRiskAsync(UpdateRiskRequest request, CancellationToken cancellationToken = default) =>
|
||||
@@ -152,7 +152,7 @@ public sealed class ExecutionService(IDbContextFactory<ApplicationDbContext> con
|
||||
.SetProperty(u => u.Likelihood, request.Likelihood)
|
||||
.SetProperty(u => u.Impact, request.Impact), cancellationToken);
|
||||
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.New);
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.Create("Failed to update risk."));
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdateDisbursementAsync(UpdateDisbursementRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -168,7 +168,7 @@ public sealed class ExecutionService(IDbContextFactory<ApplicationDbContext> con
|
||||
.SetProperty(d => d.UpdatedAt, DateTime.UtcNow)
|
||||
.SetProperty(d => d.UpdatedBy, userId), cancellationToken);
|
||||
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.New);
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.Create("Failed to update disbursement."));
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateRuleAsync(CreateRuleRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -231,8 +231,8 @@ public sealed class ExecutionService(IDbContextFactory<ApplicationDbContext> con
|
||||
|
||||
var rule = await context.Rules.AsNoTracking().FirstOrDefaultAsync(r => r.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(rule is null, NotFoundError.New)
|
||||
.ToResult(rule!.Map());
|
||||
return Result.FailIf(rule is null, NotFoundError.Create("Rule not found."))
|
||||
.ToResult(rule?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Rule[]>> GetRulesAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
|
||||
|
||||
@@ -29,7 +29,7 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
.OrderByDescending(o => o.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(programmes.Select(p => p.Map()).ToArray());
|
||||
return Result.Ok(programmes?.Select(p => p.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Portfolio[]>> GetOrganisationPorfoliosAsync(string organisationIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -49,7 +49,7 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
.OrderByDescending(o => o.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(portfolios.Select(p => p.Map()).ToArray());
|
||||
return Result.Ok(portfolios?.Select(p => p.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Organisation[]>> GetOrganisationsAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
|
||||
@@ -64,7 +64,7 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(organisations.Select(o => o.Organisation!.Map()).ToArray());
|
||||
return Result.Ok(organisations?.Select(o => o.Organisation!.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Organisation>> GetOrganisationAsync(string organisationIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -82,8 +82,8 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
.Include(i => i.OrganisationId)
|
||||
.FirstOrDefaultAsync(o => o.OrganisationId == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(tenantOrganisation is null, NotFoundError.New)
|
||||
.ToResult(tenantOrganisation!.Organisation!.Map());
|
||||
return Result.FailIf(tenantOrganisation is null, NotFoundError.Create("Organisation not found"))
|
||||
.ToResult(tenantOrganisation?.Organisation?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Instrument[]>> GetInstrumentsAsync(string programmeIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -102,7 +102,7 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
.OrderByDescending(o => o.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(instruments.Select(i => i.Map()).ToArray());
|
||||
return Result.Ok(instruments?.Select(i => i.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Dashboard>> GetDashboardAsync(CancellationToken cancellationToken = default) =>
|
||||
@@ -211,7 +211,7 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
TenantId = tenantContext.TenantId
|
||||
});
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create portfolio"));
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdatePortfolioAsync(UpdatePortfolioRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -248,7 +248,7 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
.OrderByDescending(o => o.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(programmes.Select(p => p.Map()).ToArray());
|
||||
return Result.Ok(programmes?.Select(p => p.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Portfolio>> GetPortfolioAsync(string portfolioIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -265,8 +265,8 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
var portfolio = await context.Portfolios.AsNoTracking()
|
||||
.FirstOrDefaultAsync(p => p.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(portfolio is null, NotFoundError.New)
|
||||
.ToResult(portfolio!.Map());
|
||||
return Result.FailIf(portfolio is null, NotFoundError.Create("Portfolio not found"))
|
||||
.ToResult(portfolio?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateTenantAsync(CreateTenantRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -316,8 +316,8 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
|
||||
var tenant = await context.Tenants.AsNoTracking().FirstOrDefaultAsync(t => t.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(tenant is null, NotFoundError.Create("Failed to retrieve tenants"))
|
||||
.ToResult(tenant!.Map());
|
||||
return Result.FailIf(tenant is null, NotFoundError.Create("Failed to retrieve tenant"))
|
||||
.ToResult(tenant?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdateTenantAsync(UpdateTenantRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -434,7 +434,7 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
.FirstOrDefaultAsync(f => f.TenantId == tenantContext.TenantId, cancellationToken);
|
||||
|
||||
return Result.FailIf(tenantOrganisation is null, NotFoundError.Create("Failed to find tenant organisation map"))
|
||||
.ToResult(tenantOrganisation!.Map());
|
||||
.ToResult(tenantOrganisation?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdateInstrumentAsync(UpdateInstrumentRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -483,7 +483,7 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(portfolios.Select(p => p.Map()).ToArray());
|
||||
return Result.Ok(portfolios?.Select(p => p.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<decimal>> GetProgrammeValueAsync(string programmeIdHash, CancellationToken cancellationToken = default) =>
|
||||
|
||||
@@ -23,7 +23,7 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(contracts.Select(c => c.Map()).ToArray());
|
||||
return Result.Ok(contracts?.Select(c => c.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Contract>> GetContractAsync(string contractIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -40,8 +40,8 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
var contract = await context.Contracts.AsNoTracking()
|
||||
.FirstOrDefaultAsync(c => c.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(contract is null, NotFoundError.New)
|
||||
.ToResult(contract!.Map());
|
||||
return Result.FailIf(contract is null, NotFoundError.Create("Contract not found"))
|
||||
.ToResult(contract?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Budget[]>> GetBudgetsAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
|
||||
@@ -55,7 +55,7 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(budgets.Select(b => b.Map()).ToArray());
|
||||
return Result.Ok(budgets?.Select(b => b.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Budget>> GetBudgetAsync(string budgetIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -72,8 +72,8 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
var budget = await context.Budgets.AsNoTracking()
|
||||
.FirstOrDefaultAsync(b => b.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(budget is null, NotFoundError.New)
|
||||
.ToResult(budget!.Map());
|
||||
return Result.FailIf(budget is null, NotFoundError.Create("Budget not found"))
|
||||
.ToResult(budget?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Award[]>> GetAwardsAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
|
||||
@@ -87,7 +87,7 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(awards.Select(a => a.Map()).ToArray());
|
||||
return Result.Ok(awards?.Select(a => a.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Award>> GetAwardAsync(string awardIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -103,8 +103,8 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
|
||||
var award = await context.Awards.AsNoTracking().FirstOrDefaultAsync(a => a.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(award is null, NotFoundError.New)
|
||||
.ToResult(award!.Map());
|
||||
return Result.FailIf(award is null, NotFoundError.Create("Award not found"))
|
||||
.ToResult(award?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result> ExecuteContractAsync(ExecuteContractRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -120,7 +120,7 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
.SetProperty(u => u.CreatedBy, userId)
|
||||
.SetProperty(u => u.Status, ContractStatus.Active), cancellationToken);
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, UpdateError.New);
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, UpdateError.Create("Failed to update contract"));
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateContractAsync(CreateContractRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -147,7 +147,7 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
|
||||
context.Contracts.Add(contract);
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create contract"));
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateBudgetAsync(CreateBudgetRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -173,7 +173,7 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
|
||||
context.Budgets.Add(budget);
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create budget"));
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateAwardAsync(CreateAwardRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -203,7 +203,7 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
|
||||
context.Awards.Add(award);
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create award"));
|
||||
}));
|
||||
|
||||
public async Task<Result<string>> GetContractUrlAsync(string contractIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -223,7 +223,7 @@ public sealed class GrantsService(IDbContextFactory<ApplicationDbContext> contex
|
||||
return Result.Fail<string>(NotFoundError.New);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(contract.SignedDocumentUrl))
|
||||
return Result.Fail<string>(ValidationError.Create("Ecidence is invalid, has no saved documentUrl"));
|
||||
return Result.Fail<string>(ValidationError.Create("Evidence is invalid, has no saved documentUrl"));
|
||||
|
||||
var secureDownloadUrlResult = await s3Service.GeneratePresignedUrlAsync(contract.SignedDocumentUrl,
|
||||
TimeSpan.FromMinutes(15), null, cancellationToken);
|
||||
|
||||
@@ -40,7 +40,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(projects.Select(p => p.Map()).ToArray());
|
||||
return Result.Ok(projects?.Select(p => p.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Project>> GetProjectAsync(string projectIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -57,8 +57,8 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
var project = await context.Projects.AsNoTracking()
|
||||
.FirstOrDefaultAsync(p => p.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(project is null, NotFoundError.New)
|
||||
.ToResult(project!.Map());
|
||||
return Result.FailIf(project is null, NotFoundError.Create("Project not found"))
|
||||
.ToResult(project?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Domain.Models.Activity[]>> GetActivitiesAsync(string projectIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -76,7 +76,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
.OrderByDescending(a => a.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(activities.Select(a => a.Map()).ToArray());
|
||||
return Result.Ok(activities?.Select(a => a.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateProjectAsync(CreateProjectRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -157,7 +157,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
.OrderBy(m => m.DueAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(milestones.Select(i => i.Map()).ToArray());
|
||||
return Result.Ok(milestones?.Select(i => i.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Indicator[]>> GetProjectIndicatorsAsync(string projectIdHash, CancellationToken cancellationToken) =>
|
||||
@@ -176,7 +176,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
.OrderByDescending(o => o.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(evidences.Select(e => e.Map()).ToArray());
|
||||
return Result.Ok(evidences?.Select(e => e.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Milestone>> GetMilestoneAsync(string milestoneIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -192,8 +192,8 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
var milestone = await context.Milestones.AsNoTracking()
|
||||
.FirstOrDefaultAsync(m => m.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(milestone is null, NotFoundError.New)
|
||||
.ToResult(milestone!.Map());
|
||||
return Result.FailIf(milestone is null, NotFoundError.Create("Milestone not found"))
|
||||
.ToResult(milestone?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Milestone[]>> GetMilestonesAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
|
||||
@@ -207,7 +207,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(milestones.Select(i => i.Map()).ToArray());
|
||||
return Result.Ok(milestones?.Select(i => i.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdateMilestoneAsync(UpdateMilestoneRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -216,7 +216,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
if (!await context.Users.AnyAsync(u => u.Id == userId, cancellationToken))
|
||||
return Result.Fail(NotFoundError.New);
|
||||
return Result.Fail(NotFoundError.Create("User not found"));
|
||||
|
||||
var changedTotal = await context.Milestones.Where(m => m.Id == request.MilestoneId)
|
||||
.ExecuteUpdateAsync(f => f
|
||||
@@ -263,8 +263,8 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
var activity = await context.Activities.AsNoTracking()
|
||||
.FirstOrDefaultAsync(a => a.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(activity is null, NotFoundError.New)
|
||||
.ToResult(activity!.Map());
|
||||
return Result.FailIf(activity is null, NotFoundError.Create("Activity not found"))
|
||||
.ToResult(activity?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Risk[]>> GetProjectRisksAsync(string projectIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -283,7 +283,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
.OrderByDescending(r => r.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(risks.Select(i => i.Map()).ToArray());
|
||||
return Result.Ok(risks?.Select(i => i.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateProgrammeAsync(CreateProgrammeRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -310,7 +310,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
TenantId = tenantContext.TenantId
|
||||
});
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create programme."));
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdateProgrammeAsync(UpdateProgrammeRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -319,7 +319,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
if (!await context.Users.AnyAsync(u => u.Id == userId, cancellationToken))
|
||||
return Result.Fail(NotFoundError.New);
|
||||
return Result.Fail(NotFoundError.Create("User not found"));
|
||||
|
||||
var changedTotal = await context.Programmes.Where(p => p.Id == request.ProgrammeId)
|
||||
.ExecuteUpdateAsync(f => f
|
||||
@@ -344,8 +344,8 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
|
||||
var programme = await context.Programmes.FirstOrDefaultAsync(p => p.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(programme is null, NotFoundError.New)
|
||||
.ToResult(programme!.Map());
|
||||
return Result.FailIf(programme is null, NotFoundError.Create("Programme not found"))
|
||||
.ToResult(programme?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result<Programme[]>> GetProgrammesAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
|
||||
@@ -359,7 +359,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(programmes.Select(i => i.Map()).ToArray());
|
||||
return Result.Ok(programmes?.Select(i => i.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result<Project[]>> GetProgrammeProjectsAsync(string programmeIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -373,14 +373,14 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
if (!await context.Programmes.AnyAsync(p => p.Id == decodeResult.Value, cancellationToken))
|
||||
return Result.Fail(NotFoundError.New);
|
||||
return Result.Fail(NotFoundError.Create("Programme not found"));
|
||||
|
||||
var projects = await context.Projects.AsNoTracking()
|
||||
.Where(p => p.ProgrammeId == decodeResult.Value)
|
||||
.OrderByDescending(o => o.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(projects.Select(i => i.Map()).ToArray());
|
||||
return Result.Ok(projects?.Select(i => i.Map()).ToArray() ?? []);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateChangeRequestAsync(CreateChangeRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -456,8 +456,8 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
|
||||
var changeRequest = await context.ChangeRequests.AsNoTracking().FirstOrDefaultAsync(c => c.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(changeRequest is null, NotFoundError.New)
|
||||
.ToResult(changeRequest!.Map());
|
||||
return Result.FailIf(changeRequest is null, NotFoundError.Create("Change request not found"))
|
||||
.ToResult(changeRequest?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateComplianceItemAsync(CreateComplianceItemRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -529,8 +529,8 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
|
||||
var compliancItem = await context.ComplianceItems.AsNoTracking().FirstOrDefaultAsync(c => c.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(compliancItem is null, NotFoundError.New)
|
||||
.ToResult(compliancItem!.Map());
|
||||
return Result.FailIf(compliancItem is null, NotFoundError.Create("Compliance item not found"))
|
||||
.ToResult(compliancItem?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateBeneficiaryAsync(CreateBeneficiaryRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -606,8 +606,8 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
var beneficiary = await context.Beneficiaries.AsNoTracking()
|
||||
.FirstOrDefaultAsync(b => b.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(beneficiary is null, NotFoundError.New)
|
||||
.ToResult(beneficiary!.Map());
|
||||
return Result.FailIf(beneficiary is null, NotFoundError.Create("Beneficiary not found"))
|
||||
.ToResult(beneficiary?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateIssueAsync(CreateIssueRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -681,8 +681,8 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
|
||||
var issue = await context.Issues.AsNoTracking().FirstOrDefaultAsync(i => i.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(issue is null, NotFoundError.New)
|
||||
.ToResult(issue!.Map());
|
||||
return Result.FailIf(issue is null, NotFoundError.Create("Issue not found"))
|
||||
.ToResult(issue?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateOutcomeAsync(CreateOutcomeRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -750,8 +750,8 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
var outcome = await context.Outcomes.AsNoTracking()
|
||||
.FirstOrDefaultAsync(o => o.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(outcome is null, NotFoundError.New)
|
||||
.ToResult(outcome!.Map());
|
||||
return Result.FailIf(outcome is null, NotFoundError.Create("Outcome not found"))
|
||||
.ToResult(outcome?.Map()!);
|
||||
}));
|
||||
|
||||
public async Task<Result> CreateSiteVisitAsync(CreateSiteVisitRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
@@ -820,7 +820,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
|
||||
var visit = await context.SiteVisits.AsNoTracking().FirstOrDefaultAsync(v => v.Id == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(visit is null, NotFoundError.New)
|
||||
.ToResult(visit!.Map());
|
||||
return Result.FailIf(visit is null, NotFoundError.Create("Site visit not found"))
|
||||
.ToResult(visit?.Map()!);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public sealed class UserService(IDbContextFactory<ApplicationDbContext> contextF
|
||||
changedTotal += await context.Users.Where(f => f.Id == userId)
|
||||
.ExecuteUpdateAsync(f => f.SetProperty(u => u.Status, status), cancellationToken);
|
||||
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.New);
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.Create("Failed to update user status."));
|
||||
}));
|
||||
|
||||
public async Task<Result<User>> GetUserAsync(Guid userId, CancellationToken cancellationToken) =>
|
||||
@@ -110,7 +110,7 @@ public sealed class UserService(IDbContextFactory<ApplicationDbContext> contextF
|
||||
.Include(i => i.User)
|
||||
.FirstOrDefaultAsync(f => f.UserId == userId, cancellationToken);
|
||||
|
||||
return Result.FailIf(tenantUser == null, NotFoundError.New)
|
||||
return Result.FailIf(tenantUser == null, NotFoundError.Create("User not found."))
|
||||
.ToResult(tenantUser!.User?.Map()!);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ public interface ITenantContextService
|
||||
{
|
||||
string? TenantName { get; }
|
||||
long TenantId { get; }
|
||||
bool ByPassTenantQueryFilter { get; set; }
|
||||
bool IsAdmin { get; }
|
||||
bool HasTenantFilter { get; }
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace PostFundManagement.Infrastructure.Database;
|
||||
public sealed class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options,
|
||||
ITenantContextService tenantService) : DbContext(options)
|
||||
{
|
||||
private bool BypassFilter => tenantService.IsAdmin;
|
||||
private bool BypassFilter => tenantService.IsAdmin || tenantService.ByPassTenantQueryFilter;
|
||||
private long CurrentTenantId => tenantService.TenantId;
|
||||
|
||||
public DbSet<TenantUser> TenantUsers => Set<TenantUser>();
|
||||
@@ -67,7 +67,7 @@ public sealed class ApplicationDbContext(DbContextOptions<ApplicationDbContext>
|
||||
|
||||
private void ApplyGlobalTenantFilter<TEntity>(ModelBuilder modelBuilder)
|
||||
where TEntity : class, ITenantEntity =>
|
||||
modelBuilder.Entity<TEntity>().HasQueryFilter(e => BypassFilter || e.TenantId == CurrentTenantId);
|
||||
modelBuilder.Entity<TEntity>().HasQueryFilter(e => BypassFilter == false && e.TenantId == CurrentTenantId);
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
@@ -84,14 +84,14 @@ public sealed class ApplicationDbContext(DbContextOptions<ApplicationDbContext>
|
||||
}
|
||||
}
|
||||
|
||||
modelBuilder.Entity<Organisation>().HasQueryFilter(o => BypassFilter ||
|
||||
modelBuilder.Entity<Organisation>().HasQueryFilter(o => BypassFilter == false &&
|
||||
Set<TenantOrganisation>().Any(to => to.TenantId == CurrentTenantId && to.OrganisationId == o.Id));
|
||||
|
||||
modelBuilder.Entity<TenantOrganisation>()
|
||||
.HasQueryFilter(to => BypassFilter || to.TenantId == CurrentTenantId);
|
||||
.HasQueryFilter(to => BypassFilter == false && to.TenantId == CurrentTenantId);
|
||||
|
||||
modelBuilder.Entity<TenantUser>()
|
||||
.HasQueryFilter(to => BypassFilter || to.TenantId == CurrentTenantId);
|
||||
.HasQueryFilter(to => BypassFilter == false && to.TenantId == CurrentTenantId);
|
||||
}
|
||||
|
||||
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
|
||||
@@ -10,5 +10,6 @@ public sealed partial class ApplicationDbContextFactory
|
||||
public long TenantId => 0L;
|
||||
public bool IsAdmin => true;
|
||||
public bool HasTenantFilter => false;
|
||||
public bool ByPassTenantQueryFilter { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ public sealed class TenantContextService : ITenantContextService
|
||||
|
||||
public long TenantId { get; }
|
||||
|
||||
public bool ByPassTenantQueryFilter { get; set; } = false;
|
||||
|
||||
public bool IsAdmin { get; }
|
||||
|
||||
public bool HasTenantFilter { get; }
|
||||
|
||||
Reference in New Issue
Block a user